Draw multiple objects with textures

2019-07-25 00:21发布

问题:

I want to draw cubes using textures.

void OperateWithMainMatrix(ESContext* esContext, GLfloat offsetX, GLfloat offsetY, GLfloat offsetZ) {

UserData *userData = (UserData*) esContext->userData;
ESMatrix modelview;
ESMatrix perspective;
    //Manipulation with matrix 
    ...
    glVertexAttribPointer(userData->positionLoc, 3, GL_FLOAT, GL_FALSE, 0, cubeFaces);
    //in cubeFaces coordinates verticles cube
    glVertexAttribPointer(userData->normalLoc, 3, GL_FLOAT, GL_FALSE, 0, cubeFaces);
    //for normals (use in fragment shaider for textures)

    glEnableVertexAttribArray(userData->positionLoc);
    glEnableVertexAttribArray(userData->normalLoc);

    // Load the MVP matrix
    glUniformMatrix4fv(userData->mvpLoc, 1, GL_FALSE, 
                       (GLfloat*)&userData->mvpMatrix.m[0][0]);

    //Bind base map
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_CUBE_MAP, userData->baseMapTexId);

    //Set the base map sampler to texture unit to 0
    glUniform1i(userData->baseMapLoc, 0);

   // Draw the cube
    glDrawArrays(GL_TRIANGLES, 0, 36);
   }

(coordinates transformation is in OperateWithMainMatrix() ) Then Draw() function is called:

void Draw(ESContext *esContext)
{
   UserData *userData = esContext->userData;
   // Set the viewport
   glViewport(0, 0, esContext->width, esContext->height);

   // Clear the color buffer
   glClear(GL_COLOR_BUFFER_BIT);

   // Use the program object
   glUseProgram(userData->programObject);

  OperateWithMainMatrix(esContext, 0.0f, 0.0f, 0.0f);

  eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
}

This work fine, but if I try to draw multiple cubes (next code for example):

void Draw(ESContext *esContext)
{ ...

    // Use the program object
    glUseProgram(userData->programObject);

    OperateWithMainMatrix(esContext, 2.0f, 0.0f, 0.0f);
    OperateWithMainMatrix(esContext, 1.0f, 0.0f, 0.0f);
    OperateWithMainMatrix(esContext, 0.0f, 0.0f, 0.0f);
    OperateWithMainMatrix(esContext, -1.0f, 0.0f, 0.0f);
    OperateWithMainMatrix(esContext, -2.0f, 0.0f, 0.0f);
    eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
}

A side faces overlapes frontal face. This process is illustrated on image:

Alternate picture (with colours and clean image):

The side face of the right cube overlaps frontal face of the center cube. How can i remove this effect and display miltiple cubes without it?

回答1:

To fix this you need to utilize what's known as the depth buffer. This is what's responsible for making sure that surfaces don't get drawn overtop of surfaces that are nearer (like the side of a cube showing over the front of a cube).

Luckily it's not much work involved to do so:

  1. Enable depth testing at initialization with glEnable(GL_DEPTH_TEST)
  2. Clear depth buffer on each frame by adding it's bit to the glClear call: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

After this you should no longer see your surfaces popping on top of nearer surfaces.