帮我找到我的错误。我从书中举了一个例子,但可能是作者(或我)制造了一些麻烦,我找不到解决方案。第一类是我的对象的几何形状
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
public class Planet {
FloatBuffer m_VertexData;
FloatBuffer m_NormalData;
FloatBuffer m_ColorData;
float m_Scale;
float m_Squash;
float m_Radius;
int m_Stacks, m_Slices;
public final static int SS_SUNLIGHT = GL10.GL_LIGHT0;
public Planet(int stacks, int slices, float radius, float squash) {
this.m_Stacks = stacks; //1
this.m_Slices = slices;
this.m_Radius = radius;
this.m_Squash=squash;
init(m_Stacks,m_Slices,radius,squash,"dummy");
}
private void init(int stacks,int slices, float radius, float squash, String textureFile) {
float[] vertexData;
float[] colorData; //2
float[] normalData;
float colorIncrement=0f;
float blue=0f;
float red=1.0f;
int numVertices=0;
int vIndex=0;
int cIndex=0;
int nIndex =0;
m_Scale=radius;
m_Squash=squash;
colorIncrement=1.0f/(float)stacks;//3
m_Stacks = stacks;
m_Slices = slices;
//vertices
vertexData = new float[ 3*((m_Slices*2+2) * m_Stacks)]; //4
//color data
colorData = new float[ (4*(m_Slices*2+2) * m_Stacks)]; //5
// Normalize data
normalData = new float [ (3*(m_Slices*2+2)* m_Stacks)]; //1
int phiIdx, thetaIdx;
//latitude
for(phiIdx=0; phiIdx < m_Stacks; phiIdx++) //6
{
//starts at -90 degrees (-1.57 radians) goes up to +90 degrees (or +1.57 radians)
//the first circle
float phi0 = (float)Math.PI * ((float)(phiIdx+0) * (1.0f/(float)(m_Stacks)) - 0.5f); //7
//the next, or second one.
float phi1 = (float)Math.PI * ((float)(phiIdx+1) * (1.0f/(float)(m_Stacks)) - 0.5f); //8
float cosPhi0 = (float)Math.cos(phi0); //9
float sinPhi0 = (float)Math.sin(phi0);
float cosPhi1 = (float)Math.cos(phi1);
float sinPhi1 = (float)Math.sin(phi1);
float cosTheta, sinTheta;
//longitude
for(thetaIdx=0;thetaIdx < m_Slices; thetaIdx++)
{
//increment along the longitude circle each "slice"
float theta= (float) (-2.0f*(float)Math.PI * ((float)thetaIdx) *(1.0/(float)(m_Slices-1)));
cosTheta = (float)Math.cos(theta);
sinTheta = (float)Math.sin(theta);
//we're generating a vertical pair of points, such
//as the first point of stack 0 and the first point of stack 1
//above it. This is how TRIANGLE_STRIPS work,
//taking a set of 4 vertices and essentially drawing two triangles
//at a time. The first is v0-v1-v2 and the next is v2-v1-v3. Etc.
//get x-y-z for the first vertex of stack
vertexData[vIndex+0] = m_Scale*cosPhi0*cosTheta; //11
vertexData[vIndex+1] = m_Scale*(sinPhi0*m_Squash);
vertexData[vIndex+2] = m_Scale*(cosPhi0*sinTheta);
vertexData[vIndex+3] = m_Scale*cosPhi1*cosTheta;
vertexData[vIndex+4] = m_Scale*(sinPhi1*m_Squash);
vertexData[vIndex+5] = m_Scale*(cosPhi1*sinTheta);
colorData[cIndex+0] = (float)red; //12
colorData[cIndex+1] = (float)0f;
colorData[cIndex+2] = (float)blue;
colorData[cIndex+4] = (float)red;
colorData[cIndex+5] = (float)0f;
colorData[cIndex+6] = (float)blue;
colorData[cIndex+3] = (float)1.0;
colorData[cIndex+7] = (float)1.0;
// Normalize data pointers for lighting.
normalData[nIndex + 0] = cosPhi0*cosTheta;
normalData[nIndex + 1] = sinPhi0;
normalData[nIndex + 2] = cosPhi0*sinTheta;
normalData[nIndex + 3] = cosPhi1*cosTheta;
normalData[nIndex + 4] = sinPhi1;
normalData[nIndex + 5] = cosPhi1*sinTheta;
cIndex+=2*4; //13
vIndex+=2*3; //14
nIndex+=2*3;
}
// blue+=colorIncrement; //15
red-=colorIncrement;
// create a degenerate triangle to connect stacks and maintain winding order //16
vertexData[vIndex+0] = vertexData[vIndex+3] = vertexData[vIndex-3];
vertexData[vIndex+1] = vertexData[vIndex+4] = vertexData[vIndex-2];
vertexData[vIndex+2] = vertexData[vIndex+5] = vertexData[vIndex-1];
}
m_VertexData = makeFloatBuffer(vertexData); //17
m_ColorData = makeFloatBuffer(colorData);
m_NormalData = makeFloatBuffer(normalData);
}
protected static FloatBuffer makeFloatBuffer(float[] arr)
{
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer(); fb.put(arr);
fb.position(0);
return fb;
}
public void draw(GL10 gl) {
gl.glFrontFace(GL10.GL_CW); //1
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, m_VertexData); //2
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, m_ColorData); gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
//3
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, (m_Slices+1)*2*(m_Stacks-1)+2);
}
private void initLighting(GL10 gl) {
float[] diffuse = {0.0f, 1.0f, 0.0f, 1.0f}; //1
float[] pos = {0.0f, 10.0f, -3.0f, 1.0f}; //2
gl.glLightfv(SS_SUNLIGHT, GL10.GL_POSITION, makeFloatBuffer(pos)); //3
gl.glLightfv(SS_SUNLIGHT, GL10.GL_DIFFUSE, makeFloatBuffer(diffuse)); //4
gl.glShadeModel(GL10.GL_FLAT); //5
gl.glEnable(GL10.GL_LIGHTING); //6
gl.glEnable(SS_SUNLIGHT); //7
}
}
第二个是渲染:包装组合示例.太阳能系统;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView;
public class SolarSystemRenderer implements GLSurfaceView.Renderer{
private Planet mPlanet;
public SolarSystemRenderer(boolean b) {
mPlanet=new Planet(30,30,1.0f, 1.0f);
}
private float mTransY;
private float mAngle;
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glClearColor(0.0f,0.0f,0.0f,1.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0.0f,(float)Math.sin(mTransY), -10.0f);
gl.glRotatef(mAngle, 1, 0, 0);
gl.glRotatef(mAngle, 0, 1, 0);
mPlanet.draw(gl);
mTransY+=.0f;
mAngle+=.4;
}
public void onSurfaceChanged(GL10 gl, int width, int height) //11
{
gl.glViewport(0, 0, width, height); //12
float aspectRatio;
float zNear =3.2f;
float zFar =1000;
float fieldOfView = 30.0f/57.3f; //1
float size;
gl.glEnable(GL10.GL_NORMALIZE);
aspectRatio=(float)width/(float)height; //2
gl.glMatrixMode(GL10.GL_PROJECTION); //3
size = zNear * (float)(Math.tan((double)(fieldOfView/2.0f))); //4
gl.glFrustumf(-size, size, -size /aspectRatio, //5
size /aspectRatio, zNear, zFar);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) //15
{
gl.glDisable(GL10.GL_DITHER); //16
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); //17
gl.glEnable(GL10.GL_CULL_FACE);
gl.glCullFace(GL10.GL_BACK);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthMask(false);
initGeometry(gl);
initLighting(gl);
}
}
所以在表面创建方法中,我在初始化 initGeometry(gl) 时有错误; 初始化照明(gl); 此外,如果我将我的 initLighting 方法从第一个类剪切到渲染类,我会在初始化 makeFloatBuffer 时出错。
我对这本书的这一部分也有问题。
尝试在渲染器中的 onSurfaceCreated 方法中注释掉几行:
initGeometry(gl); - 因为代码中没有为此定义方法。
gl.glEnable(GL10.GL_DEPTH_TEST); - 不确定这一行有什么问题,但注释掉这一行使整个事情如书中所述。