用纹理绘制多个对象 [英] Draw multiple objects with textures

查看:91
本文介绍了用纹理绘制多个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用纹理绘制立方体.

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);
   }

(坐标转换在OperateWithMainMatrix()中) 然后调用Draw()函数:

(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?

推荐答案

要解决此问题,您需要利用所谓的深度缓冲区.这是确保表面不会在较近的表面的顶部绘制的原因(例如,立方体的侧面显示在立方体的前面).

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. 在使用glEnable(GL_DEPTH_TEST)
  2. 进行初始化时启用深度测试
  3. 通过在glClear调用中添加位来清除每个帧上的深度缓冲区: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
  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.

这篇关于用纹理绘制多个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆