Convert objects independently in OpenGL ES 2.0

All the tutorials I've seen always use a single object, such as a triangle or a cube. But I don’t understand how I can independently manipulate individual objects. I saw several tutorials that reference the fixed function pipeline and use pushmatrix and popmatrix, but with a programmable pipeline these functions are gone. Below is the init function and the drawing function, which draw one triangle on the screen and rotate it around the Z axis. Can someone show me code or even pseudo-code to add a second triangle and rotate it independently of another triangle? Talk around another axis or in the opposite direction?

Here they are:

int Init(ESContext* esContext) { UserData* userData = (UserData *)esContext->userData; const char *vShaderStr = "attribute vec4 vPosition; \n" "uniform mat4 MVPMatrix;" "void main() \n" "{ \n" " gl_Position = MVPMatrix * vPosition;\n" "} \n"; const char *fShaderStr = "precision mediump float; \n" "void main() \n" "{ \n" " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n" "} \n"; GLuint vertexShader; GLuint fragmentShader; GLuint programObject; GLint linked; GLfloat ratio = 320.0f/240.0f; vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr); fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr); programObject = glCreateProgram(); if (programObject == 0) return 0; glAttachShader(programObject, vertexShader); glAttachShader(programObject, fragmentShader); glBindAttribLocation(programObject, 0, "vPosition"); glLinkProgram(programObject); glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &linked); if (!linked) { GLint infoLen = 0; glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { char* infoLog = (char *)malloc(sizeof(char) * infoLen); glGetProgramInfoLog(programObject, infoLen, NULL, infoLog); free(infoLog); } glDeleteProgram(programObject); return FALSE; } userData->programObject = programObject; glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glViewport(0, 0, esContext->width, esContext->height); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(userData->programObject); userData->angle = 0.0f; userData->start = time(NULL); userData->ProjMatrix = PVRTMat4::Perspective(ratio*2.0f, 2.0f, 3.0f, 7.0f, PVRTMat4::eClipspace::OGL, false, false); userData->ViewMatrix = PVRTMat4::LookAtLH(PVRTVec3(0.0f, 0.0f, -3.0f), PVRTVec3(0.0f, 0.0f, 0.0f), PVRTVec3(0.0f, 1.0f, 0.0f)); return TRUE; } void Draw(ESContext *esContext) { GLfloat vVertices[] = {0.0f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f}; GLint MVPHandle; double timelapse; PVRTMat4 MVPMatrix = PVRTMat4::Identity(); UserData* userData = (UserData *)esContext->userData; timelapse = difftime(time(NULL), userData->start) * 1000; if(timelapse > 16.0f) //Maintain approx 60FPS { if (userData->angle > 360.0f) { userData->angle = 0.0f; } else { userData->angle += 0.1f; } } userData->ModelMatrix = PVRTMat4::RotationZ(userData->angle); MVPMatrix = userData->ViewMatrix * userData->ModelMatrix; MVPMatrix = userData->ProjMatrix * MVPMatrix; MVPHandle = glGetUniformLocation(userData->programObject, "MVPMatrix"); glUniformMatrix4fv(MVPHandle, 1, FALSE, MVPMatrix.ptr()); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices); glEnableVertexAttribArray(0); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 3); eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface); } 
+8
opengl-es
source share
1 answer

After drawing the first triangle, generate a new MVP matrix with the new desired rotation / position, load it, and then draw the triangle again. You can change the uniform as many times as you like during the scene.

This is similar to what push and pop do, they just change the active matrix before drawing this object.

Pseudo-code example:

 MMatrix = identity; MVPMatrix = VPMatrix * MMatrix; glUniformMatrix4fv(MVPHandle, 1, FALSE, MVPMatrix.ptr()); glDrawArrays(GL_TRIANGLES, 0, 3); //draw triangle at 0,0,0 MMatrix.translate(1,0,0); MVPMatrix = VPMatrix * MMatrix; glUniformMatrix4fv(MVPHandle, 1, FALSE, MVPMatrix.ptr()); glDrawArrays(GL_TRIANGLES, 0, 3); //draw triangle at 1,0,0 MMatrix.translate(1,0,0); MVPMatrix = VPMatrix * MMatrix; glUniformMatrix4fv(MVPHandle, 1, FALSE, MVPMatrix.ptr()); glDrawArrays(GL_TRIANGLES, 0, 3); //draw triangle at 2,0,0 ..repeat for as many objects as you want.. 

This will leave you with three triangles, (0,0,0), (1,0,0) and (2,0,0).

+6
source share

All Articles