# OpenGL Sphere get bended when moving on X-Y surface, In perspective projection

This topic is 2436 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi everyone,

I'm a beginner playing with OPENGL ES on Android now. Now I'm hung on a problem , please read and see what's wrong:[font=Wingdings][/font]

What I want to do, should be quite simple :

1. Setup the view using perspective projection ( call glFrustum API)

2. Draw a sphere at {0,0,-3}

3. Use glTranslatef(X-2, Y-2, -3) to move the sphere at the X-Y surface.

It works fine at #1 and #2, as the image I attach

But when I call glTranslatef(X-2 , Y-2 , -3) , the sphere get bened got the same result on both Android mobile and emulator.

The sphere’s vertices are imported from 3D MAX generated file. I suspect the root cause is from the Open GL ES projection matrix’s setup.

Here’s how I setup the projection matrix:

[size=2] [size=2]public[size=2] [size=2]void[size=2] onSurfaceChanged(GL10 gl, [size=2]int[size=2] width, [size=2]int[size=2] height) {[size=2]

[size=2] gl.glViewport(0, 0, width, height);[size=2]

[size=2] gl.glMatrixMode(GL10.[size=2]GL_PROJECTION[size=2]);[size=2]

[size=2] [size=2]ratio[size=2] = ([size=2]float[size=2]) width / height;[size=2]

[size=2] gl.glFrustumf(-[size=2]ratio[size=2], [size=2]ratio[size=2], -[size=2]1[size=2], [size=2]1[size=2], [size=2]2[size=2], [size=2]15[size=2]); [size=2]

[size=2] gl.glMatrixMode(GL10.[size=2]GL_MODELVIEW[size=2]);[size=2]

[size=2] }

And it look bad only to Sphere ,, when moving a cube it just works fine.

Really grateful to any suggestion !!

##### Share on other sites
Looks like you have a matrix ordering problem here. It doesn't necessarily have to be a problem with projection.

Could you post your drawing code (using the appropriate tags)?

I suspect you have some scaling as well which might be influenced by the translate due to wrong ordering.

##### Share on other sites
Hi Lord_Evil,

Thanks for your suggest. Here's the code snippet:

 public class MyGLRender implements Renderer { this.sphere = GlObject3D.consturctFromObjectFile(res, "data/Sphere.obj"); @Override public void onDrawFrame(GL10 gl) { initScene(gl); sphere.draw(gl); //Draw sphere } /** * Initialize scene each time at onDrawFrame(GL10 gl) * @param gl */ protected void initScene(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0, 0, 0); gl.glEnable(GL10.GL_LIGHTING); gl.glEnable(GL10.GL_LIGHT0); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); } public void onSurfaceCreated(GL10 gl, EGLConfig config) { gl.glShadeModel(GL10.GL_SMOOTH); gl.glClearColor(0, 0, 0, 0); gl.glClearDepthf(1.0f); gl.glEnable(GL10.GL_DEPTH_TEST); gl.glDepthFunc(GL10.GL_LEQUAL); gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); gl.glHint(GL10.GL_POINT_SMOOTH_HINT, GL10.GL_NICEST); } public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); ratio = (float) width / height; gl.glFrustumf(-ratio*basicUnit, ratio*basicUnit, -basicUnit, basicUnit, near, far); gl.glMatrixMode(GL10.GL_MODELVIEW); } } 

And this is code snippet of "sphere.draw" method:

public void draw(GL10 gl) { gl.glTranslatef( -2,-2,0); //Move to left-top of the screen gl.glVertexPointer(3, GL10.GL_FLOAT, 0, verticesBuffer); gl.glEnableClientState(GL10.GL_NORMAL_ARRAY); gl.glNormalPointer(GL10.GL_FLOAT, 0, this.normalsBuffer); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, this.verticesBuffer.capacity()/3); }

What "Sphere.draw(gl)" do is simply apply the vertex parsed from "data/Sphere.obj" file, using "glVertexPointer" and "glDrawArrays" API. And I don't think this "problem" related to "glNormalPointer" , because I tried take off "glNormalPointer" and I still get a bended sphere when calling "Translate(X, Y)"

##### Share on other sites
This is the "Sphere.obj" file. I generated it from 3d max 2011.

I have to rename it to "Sphere.txt" since the Forum disallow "obj" uploaded

##### Share on other sites
The problem could be caused by the viewing angle being too large, this will cause distortions near the edges of the screen. You may want to use gluPerspective instead of glFrustum, it's much more intuitive to use in most cases.

EDIT:
On another note, the call to glTranslateF(0, 0, 0) in initScene does nothing. The translate, rotate and scale functions 'add' to the current matrix, so a translation/rotation of zero or a scale of 1 have no effect.

##### Share on other sites
You will always get some bending with a perspective where the sphere is close to the camera. You can make it better by decreasing the field of view and moving the camera further away, or use orthographic projection to get rid of it (camera infinitely far away).

If you use a digital camera to take a photograph of a tennis ball for example, you will get the same effect if it's in the corner of the picture.

##### Share on other sites

You will always get some bending with a perspective where the sphere is close to the camera. You can make it better by decreasing the field of view and moving the camera further away, or use orthographic projection to get rid of it (camera infinitely far away).

If you use a digital camera to take a photograph of a tennis ball for example, you will get the same effect if it's in the corner of the picture.

Hi Eric, is it possible in OpenGL ES, that I define a perspective projection , but when in draw() , I define some object to be drawn/view in orthographic projection ? I can't believe sphere get bended always when being placed at the corner of screen, and I'm so curious how the game solve such problems - I am a WOW fun and I saw objects being drawn fantastically perfect. But of couse that is base on the assumption that WOW use OpenGL to build its engine ..

##### Share on other sites
What is the value of 'basicUnit'? It simply looks like you're using a very wide FOV (wide-angle lens).

##### Share on other sites

What is the value of 'basicUnit'? It simply looks like you're using a very wide FOV (wide-angle lens).

Oh I missed that code

float basicUnit = 10f;

That is to define the length unit along X and Y axis.

##### Share on other sites
Rene, yes, when I turn to call gluPerspective instead of glFrustum, the sphere looks more smooth and less bending than the case of "glFrustum". i wonder what's the key to totally solve the problem?

Can I define a projection matrix by myself rather than through the given API to gain a better "view angle" for my project?

1. 1
2. 2
3. 3
4. 4
frob
20
5. 5
JoeJ
20

• 11
• 11
• 12
• 13
• 9
• ### Forum Statistics

• Total Topics
632214
• Total Posts
3004853

×