简体   繁体   中英

LWJGL (OpenGL) VBO model matrix not rendering correctly

I have two VBOs I am trying to render, both of them should have two different positions on the screen. When I try to modify the position of one of the VBOs, it gets transferred to the other.

Example- I change the y position of object 2, both object 1 and object 2 now exist at that y position.

My code for transforming the VBOs:

    Matrix4f.scale(scale, modelMatrix, modelMatrix);
    Matrix4f.translate(position, modelMatrix, modelMatrix);
    Matrix4f.rotate(Toolkit.degToRad(rotation.x), new Vector3f(1f,0f,0f), modelMatrix, modelMatrix);
    Matrix4f.rotate(Toolkit.degToRad(rotation.y), new Vector3f(0f,1f,0f), modelMatrix, modelMatrix);
    Matrix4f.rotate(Toolkit.degToRad(rotation.z), new Vector3f(0f,0f,1f), modelMatrix, modelMatrix);

Please note that position, rotation, and scale are all Vector3fs, and modelMatrix is well, the model matrix.

Also, Toolkit.degToRad is similar to a Math.toRadians() type method.

My code for passing info to the shaders:

    //Apply Transformations
    camera.reset();
    camera.transform();

    glUseProgram(ss.pId);

    //Projection Matrix
    camera.projectionMatrix.store(camera.matrixBuffer);
    camera.matrixBuffer.flip();
    projection.Matrix4(camera.matrixBuffer);
    //View Matrix
    camera.viewMatrix.store(camera.matrixBuffer);
    camera.matrixBuffer.flip();
    view.Matrix4(camera.matrixBuffer);

    glUseProgram(0);

    //Apply Transformations
    obj.reset();
    obj.transform();

    glUseProgram(ss.pId);

    //Object 1
    obj.modelMatrix.store(camera.matrixBuffer);
    camera.matrixBuffer.flip();
    model.Matrix4(camera.matrixBuffer);

    glUseProgram(0);

    //Apply Transformations
    obj2.reset();
    obj2.transform();


    glUseProgram(ss.pId);

    obj2.modelMatrix.store(camera.matrixBuffer);
    camera.matrixBuffer.flip();
    model.Matrix4(camera.matrixBuffer);

    glUseProgram(0);

obj and obj2 are VBOs, model is a shader uniform, camera is the camera, and ss is the shader program and ss.pId is the program id.

My code for drawing the VBOs: Note that this is found in obj and obj2 and is used like this

obj.draw();
obj2.draw();

And here is the drawing method

    GL20.glUseProgram(ss.pId);

    GL13.glActiveTexture(GL13.GL_TEXTURE0);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, t.id);

    GL30.glBindVertexArray(g.vaoId);
    GL20.glEnableVertexAttribArray(0);
    GL20.glEnableVertexAttribArray(1);
    GL20.glEnableVertexAttribArray(2);

    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, g.vboiId);

    GL11.glDrawElements(GL11.GL_TRIANGLES, g.indices, GL11.GL_UNSIGNED_BYTE, 0);

    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
    GL20.glDisableVertexAttribArray(0);
    GL20.glDisableVertexAttribArray(1);
    GL20.glDisableVertexAttribArray(2);
    GL20.glUseProgram(0);


    GL20.glUseProgram(ss.pId);

    GL13.glActiveTexture(GL13.GL_TEXTURE0);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, t.id);

    GL30.glBindVertexArray(g.vaoId);
    GL20.glEnableVertexAttribArray(0);
    GL20.glEnableVertexAttribArray(1);
    GL20.glEnableVertexAttribArray(2);

    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, g.vboiId);

    GL11.glDrawElements(GL11.GL_TRIANGLES, g.indices, GL11.GL_UNSIGNED_BYTE, 0);

    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
    GL20.glDisableVertexAttribArray(0);
    GL20.glDisableVertexAttribArray(1);
    GL20.glDisableVertexAttribArray(2);
    GL20.glUseProgram(0);

g is the geometry class,

g contains indices buffer id, and vertices buffer id. t contains texture and id.

Thanks for your help.

Your whole program structure looks fairly unusual, and I believe this is part of what is tripping you up. For example, while I'm all for encapsulation, wrapping a single uniform in an object, like you appear to be doing with your model variable, is pushing it too far IMHO. A uniform value is really an attribute of a shader program, not an independent object.

Anyway, without going too deep into design aspects, I believe your main problem is in this code sequence (with parts omitted):

// calculate camera.matrixBuffer for object 1
model.Matrix4(camera.matrixBuffer);
...
// calculate camera.matrixBuffer for object 2
model.Matrix4(camera.matrixBuffer);

The second of these calls will overwrite the value written in the first one, without the first one ever being used. When you later render object 1 and object 2, they will both use the second value for the uniform.

As long as you use the same shader program for both objects (which is a good thing, unless they really need different shaders), you will have to set the uniform value before you draw each of the objects.

So the calls to set the uniforms should go into the draw function, where the structure will look roughly like this:

// calculate camera.matrixBuffer for object 1
model.Matrix4(camera.matrixBuffer);
obj1.draw();
...
// calculate camera.matrixBuffer for object 2
model.Matrix4(camera.matrixBuffer);
obj2.draw();

Matrix transforms are applied to everything, not just a single VBO.

My suggestion would be to transform, draw, then do a reverse transformation for the next draw.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM