Zippy
Zippy

Reputation: 3887

Changing camera position in OpenGL ES 2.0

I'm developing an app for Android devices using OpenGL ES 2.0 and am having trouble understanding how to move my camera - (ultimately, I'm attempting to produce a 'screen shaking' effect - so I need all currently rendered objects to move in unison).

So, at the moment, I have a SpriteBatch class which I use to batch up a load of entities and render them all in a single OpenGL call.

Within this class, I have my vertex and fragment shaders.

So, I simply create an instance of this class for my objects..... something like:

SpriteBatch tileSet1 = new SpriteBatch(100); //100 tiles

I'll then render it like this:

tileSet1.render();

Within my GLSurfaceView class (in onSurfaceChanged), I am setting up my view like this:

//offsetX, offsetY, width and height are all valid and previously declared)

GLES20.glViewport(offsetX, offsetY, width, height); 

Matrix.orthoM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

Then, within my onDrawFrame() method, I simply call all of my logic and rendering like this:

logic();
render();

(Obviously, my game loop has been greatly simplified for the purpose of this question).

I really am not sure where I'm supposed to put Matrix.setLookAtM.

I've tried placing it into my 'GLSufaceView' class - again, in onSurfaceChanged, but it doesn't seem to have any effect. How does setLookAtM work in relation to the shaders? I ask because my shaders are in my 'SpriteBatch' class and belong to instances of that class (I could be misunderstanding this completely though).

If any more code is required, please ask and I will post.

Would appreciate a pointer in the right direction.

Upvotes: 0

Views: 2459

Answers (1)

Reto Koradi
Reto Koradi

Reputation: 54642

Calls like Matrix.orthoM() and Matrix.setLookAtM() do not change your OpenGL state at all. They are just utility methods to calculate matrices. They set values in the matrix passed to them as the first argument, and nothing else.

Applying those matrices to your OpenGL rendering is a separate task. The main steps you need for this in a typical use case are:

  1. Declare a uniform variable of type mat4 in your vertex shader.

    uniform mat4 ProjMat;
    
  2. Use the matrix while transforming vertices in the vertex shader code:

    gl_Position = ProjMat * ...;
    
  3. In your Java code, get the location of the uniform variable after compiling and linking the shader:

    int projMatLoc = GLES20.glGetUniformLocation(progId, "ProjMat");
    
  4. Calculate the desired matrix, and use it to set the value of the uniform variable:

    Matrix.orthoM(projMat, ...);
    ...
    GLES20.glUseProgram(progId);
    GLES20.glUniformMatrix4fv(projMatLoc, 1, false, projMat, 0);
    

Note that uniform values have shader program scope. So if you have multiple shader programs that use the matrix, and want to change it for all of them, you'll have to make the glUniformMatrix4fv() call for each of them, after making it active with glUseProgram().

Upvotes: 3

Related Questions