the following text is a bit lenghty as I wanted to make sure that people with similar problems that e.g. google this page can easily follow the exact problem and its solutions easily. But now on to my issue:
I recently started programming OpenGL ES on an Android smartphone and ran into problems understanding how gluPerspective and gluLookAt are used. I think I understand what they do, however I cannot see the triangle I draw. I run the following code in the onDrawFrame-method of my activity. Said activity implements GLSurfaceView.Renderer with the onDrawFrame marked with @Override. My code is:
gl.glViewport(0, 0, screen_width, screen_height);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //set background to black
gl.glClearDepthf(1.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_PROJECTION); // Change PROJECTION matrix
gl.glLoadIdentity();
float aspect_ratio = (float) screen_width / screen_height;
GLU.gluPerspective(gl, 67, aspect_ratio, 1, 100);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glMatrixMode(GL10.GL_MODELVIEW); // Change MODELVIEW matrix
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, 20, 0, 0, 0, 0, 1, 0);
// make triangle with vertices (-2,0,0), (2,0,0), and (0,.5,0)
float[] vertices = { -2f, 0, 0, 2f, 0, 0, 0, .5f, 0 };
ByteBuffer buffer = ByteBuffer.allocateDirect(vertices.length * 4);
buffer.order(ByteOrder.nativeOrder());
FloatBuffer vertex_buffer = buffer.asFloatBuffer();
for (int i = 0; i < 9; i++) {
vertex_buffer.put(vertices[i]);
}
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex_buffer);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_DEPTH_TEST);
The next points are short notes on what I putatively know about camera settings in the above code. PLEASE correct me if I got something wrong in the following explanations, as that might already solve all of my issues!
- glMatrixMode(GL10.GL_PROJECTION) switches to changing the camera matrix (for which I load an identity matrix directly afterwards)
- GLU.gluPerspective(gl, 67, aspect_ratio, 1, 100) sets a perspective projection with a view frustrum of 67 degree view angle in the y-dimension. Using “aspect_ration=(float)width/height” OpenGL computes the view angle in the x-dimension. Further the “1” is the near clipping plane, while “100” is the value of the far clipping plane in this case.
- As far as I know it does not matter, where in the code gluLookAt is called, as long as it is done before the actual drawing (I’m unsure about this though). In this example I change to the MODELVIEW matrix first, load an identity matrix, and then gluLookAt is called.
3. - “GLU.gluLookAt(gl, 0, 0, 20, 0, 0, 0, 0, 1, 0)” actually consists of three 3-element vectors. The initial one ((0,0,20) in this example) sets the position of the camera in world coordinates (i.e. 20 units on the positive Z-axis, which means it is “sticking out” of the front of the phone’s screen). The second vector determines the point in the world coordinate system the camera looks at (in this example the origin of the coordinate system, i.e. the camera looks along the negative z-axis). The third vector is the up-vector that defines the direction of the y-Axis of the cameras coordinate system (and therefore also the x-axis via cross product with the vector from camera position to the point it looks at).
The triangle drawing code was copied from a tutorial (but I found similar code also in other tutorials, so I assume this is not the problem).
As far as I get it, the camera is now positioned on (0,0,20) and looks towards the origin of the coordinate system. Its drawing frustrum starts at z-value 19 and goes as far as -80 (the camera is at z-axis point 20 and looks along the negative z-axis; its viewing frustrum has near and far plane at 1 and 100 (both looking along the negative z-axis in this case), respectively). Therefore, the triangle should be visible, as its vertices are positioned around the origin on the z-axis=0 plane (i.e. the xy-plane), which is clearly within the viewing frustrum. Further the drawn vertices are arranged in counter-clockwise order; the default in OpenGL.
So after this long introduction into the problem my simple question is: What did I mess up so that this code does not do what I expect it to?
I found the answer after looking at further tutorials (and then also noticed it in the ones I used before)! Thank all of you for your answers, they were very helpful in diagnosing OpenGL problems in general and will for sure help me in the future!
The solution to my problem is… that the problem is not glulookat or gluperspective, but in my case the internal position of the FloatBuffer. I did not set the position of variable vertex_buffer to 0 after the for(0 < i < 9) loop. Setting the buffer’s position to 0 can be accomplished with at least two commands:
To my knowledge they do the same thing. I quickly tested where in the code the position reset belongs and in my example code I could call it after gl.glEnableClientState(GL10.GL_VERTEX_ARRAY), however I had to call it before gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex_buffer), otherwise the initial problem returned.
I hope this helps other people with similar issues or maybe is just a short of glulookat and gluperspective 😉
Thanks again for your suggestions!