开发者

I'm having trouble setting up my camera in openGL

开发者 https://www.devze.com 2023-03-16 18:55 出处:网络
Right now I have a frustum, I really actually need to have an ortho instead but i couldn\'t get it to work so I tried a frustum. The gluLookAt doesn\'t change the view when i change it\'s parameters,

Right now I have a frustum, I really actually need to have an ortho instead but i couldn't get it to work so I tried a frustum. The gluLookAt doesn't change the view when i change it's parameters, the only thing that actually has an influence on the view right now is the glViewport. Which i just noticed I was screwing around with it and should actually be glViewport(0, 0, width, height);

package Android.StreetBall;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
//import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.util.Log;

public class GameRenderer implements Renderer{
    //Actual game size 19*12
    private float _Width = 0;
    private float _Height = 0;
    private final float _XBlocks = 19.0f;
    private final float _XBPF = 1.0f / _XBlocks;//Blocks per X frame
    private final float _YBlocks = 12.0f;
    private final float _YBPF = 1.0f / _YBlocks;//blocks per Y frame

    private BaseDrawableObject[] _DrawQueue;
    private Object _DrawLock;
    private boolean _DrawQueueChanged;

    public GameRenderer(){
            //_DrawQueueChanged = false;
            _DrawQueueChanged = true;
            _DrawLock = new Object();
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        //float ratio = _Width / _Height;
        //gl.glViewport(0, 0, (int) _Width, (int) _Height);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
        gl.glShadeModel(GL10.GL_SMOOTH);
        gl.glClearDepthf(1.0f);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthFunc(GL10.GL_LEQUAL);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        _Width = width;
        _Height = height;
        Log.v("Dimensions", width + ", " + height);
        gl.glViewport(0, 0, width, height);
        //float ratio = width/height;
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        }

    public void onDrawFrame(GL10 gl) {

        gl.glOrthof(0.0f, _Width, _Height, 0.0f, -1.0f, 1.0f);    
        GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);


        synchronized(_DrawLock){
            if(!_DrawQueueChanged){
                while(!_DrawQueueChanged){
                    try{
                        Log.d("game","rendering is waiting");
                        _DrawLock.wait();
                    } catch(InterruptedException e){
                        //no biggy
                    }
                }
            }
            _DrawQueueChanged = false;
        }    
        synchronized(this){
            if(_DrawQueue != null && _DrawQueue.length > 0){
                Log.d("game","rendering");
                gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

                for(BaseDrawableObject i: _DrawQueue){
                    if(i != null){
                        gl.glLoadIdentity();
                        gl.glScalef(_XBPF, _YBPF, 1);
                        gl.glTranslatef(i._Position.x,i._Position.y, 0.0f);
                        i.draw(gl);
                    }
                }
            } else if(_DrawQueue == null){
                gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
            }
        }
    }//end 开发者_开发技巧method

    /**
     * blocks while onDrawFrame is in progress, used by other threads to determine when drawing
     */


    public synchronized void setDrawQueue(BaseDrawableObject[] queue){
        _DrawQueue = queue;
        synchronized(_DrawLock){
            _DrawQueueChanged = true;
            _DrawLock.notify();
        }
    }

    public synchronized void waitDrawingComplete() {        
    }
}//end class


A couple of things:

  • You call transformation methods in onDrawFrame, so they accumulate. You should include a push/popMatrix or a glLoadIdentity.
  • You call a glLoadIdentity before drawing each object, undoing the projection transformations.
  • You leave the current matrix mode to projection, but you should switch to modelview for the transformations.
  • It is advisable to apply the orthof to the projection matrix, and the glulookat to the modelview (See here for an explanation).

I think it should look something like this:

onSurfaceChanged(...) { 
   glViewPort(...)
   glMatrixMode(GL10.GL_PROJECTION);
   glOrthof(...);
   glMatrixMode(GL10.GL_MODELVIEW);
}

onDrawFrame(...) {
   glLoadIdentity();
   GLU.gluLookAt(...);
   for each object {
      glPushMatrix();
      glRotatef(...);
      glTranslatef(...);
      drawObject(...);
      glPopMatrix();
   }
}

Hope this helps, cheers, Aert.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号