我将可移动的 3d 对象和不可移动的 3d 分开。我可以为不可移动物体生成 2 个纹理:背景颜色纹理和背景深度纹理。我没有问题。两者的值都可以。我用灰色渐变纹理检查深度值。
我想用这些纹理在opengl中写入/填充颜色缓冲区和深度缓冲区,但深度不起作用(屏幕上的颜色缓冲区很好)。
我的目标是在相机不移动时永远不要重新计算不可移动的 3d 对象。
(rem:深度缓冲区位大小始终为 16 位)
这是我生成深度纹理的代码:
U16 m_backgroundDepthBuffer[4096 * 4096]; // it's a member of my class
glReadPixels(0,0, width(), height(), GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, (void*)m_backgroundDepthBuffer);
// Allocate GPU-memory for the depth-texture.
glDeleteTextures(1, &m_backgroundDepthTextureId);
glGenTextures(1, &m_backgroundDepthTextureId);
glBindTexture(GL_TEXTURE_2D, m_backgroundDepthTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16,
width(), height(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, m_backgroundDepthBuffer);
这是我填充颜色缓冲区的代码:
void Application::Render()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
// render background
Render::RenderImage(m_backgroundTextureId, 0,0, width(), height());
// for debug
// Render::RenderImage(m_backgroundDepthGrayTextureId, 0,0, width(), height());
// This is how I fill the depth buffer : it's work but slow
glDrawPixels(width(), height(), GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, (GLvoid*) m_backgroundDepthBuffer); //
// doesn't work
// Render::RenderDepth(m_backgroundDepthTextureId, 0,0, width(), height());
}
这是我的 Render::RenderImage() :它有效
void Render::RenderImage(U32 tex, int x, int y, int w, int h, float anchorX, float anchorY)
{
glClear(GL_DEPTH_BUFFER_BIT);
GLboolean depth = glIsEnabled(GL_DEPTH_TEST);
if (depth)
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, s_width, s_height, 0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor3ub(255, 255, 255);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
x -= (int)(anchorX * w);
y -= (int)(anchorY * h);
gVertices[0] = VECTOR3F(x, y, 0);
gVertices[1] = VECTOR3F(x + w - 1, y, 0);
gVertices[2] = VECTOR3F(x + w - 1, y + h - 1, 0);
gVertices[3] = VECTOR3F(x, y + h - 1, 0);
gTexCoords[0] = VECTOR2F(0, 1);
gTexCoords[1] = VECTOR2F(1, 1);
gTexCoords[2] = VECTOR2F(1, 0);
gTexCoords[3] = VECTOR2F(0, 0);
gIndexes[0] = 2;
gIndexes[1] = 1;
gIndexes[2] = 0;
gIndexes[3] = 0;
gIndexes[4] = 3;
gIndexes[5] = 2;
glVertexPointer(3, GL_FLOAT, 0, gVertices);
glTexCoordPointer(2, GL_FLOAT, 0, gTexCoords);
glDrawElements(GL_TRIANGLES, 3 * 2, GL_UNSIGNED_SHORT, gIndexes);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
if (depth)
glEnable(GL_DEPTH_TEST);
}
这是我的 Render::RenderDepth() :它不起作用/我有一个深度 = 0.0f 的纹理,而不是使用每个纹素的深度。我只想更改深度缓冲区而不对颜色缓冲区执行任何操作 Render::RenderDepth() 类似于 Render::RenderImage() :我渲染 2 个三角形
void Render::RenderDepth(U32 tex, int x, int y, int w, int h, float anchorX, float anchorY)
{
glClear(GL_DEPTH_BUFFER_BIT);
/*glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_DEPTH_TEXTURE_MODE, GL_ALPHA);
*/
GLboolean depth = glIsEnabled(GL_DEPTH_TEST);
//if (depth)
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, s_width, s_height, 0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor3ub(255, 255, 255);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
x -= (int)(anchorX * w);
y -= (int)(anchorY * h);
gVertices[0] = VECTOR3F(x, y, 0.0);
gVertices[1] = VECTOR3F(x + w - 1, y, 0.0);
gVertices[2] = VECTOR3F(x + w - 1, y + h - 1, 0.0);
gVertices[3] = VECTOR3F(x, y + h - 1, 0.0);
gTexCoords[0] = VECTOR2F(0, 1);
gTexCoords[1] = VECTOR2F(1, 1);
gTexCoords[2] = VECTOR2F(1, 0);
gTexCoords[3] = VECTOR2F(0, 0);
gIndexes[0] = 2;
gIndexes[1] = 1;
gIndexes[2] = 0;
gIndexes[3] = 0;
gIndexes[4] = 3;
gIndexes[5] = 2;
glVertexPointer(3, GL_FLOAT, 0, gVertices);
glTexCoordPointer(2, GL_FLOAT, 0, gTexCoords);
glDrawElements(GL_TRIANGLES, 3 * 2, GL_UNSIGNED_SHORT, gIndexes);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}