OpenGL深度不起作用,三角形消失
Posted
技术标签:
【中文标题】OpenGL深度不起作用,三角形消失【英文标题】:OpenGL Depth Not working, Triangles Disappear 【发布时间】:2012-06-14 01:03:04 【问题描述】:由于某种原因,我无法检测到我无法为任何三角形设置 z 索引。三角形将以相同的深度显示,从 1 到 -1(含),但之后它会消失。我没有应用任何 MVP 矩阵(试图首先弄清楚这一点),并且我希望能够看到我的三角形随着 z 值的减小而变小。这是我目前所拥有的:
//My main function
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_ALPHA|GLUT_DOUBLE|GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutCreateWindow("Window");
if (init_resources())
glutDisplayFunc(onDisplay);
glutIdleFunc(idle);
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMainLoop();
//And in my display function
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
还有我的顶点着色器:
gl_Position = vec4(coord2d, 0.0, 1.0);
glGetIntegerv(GL_DEPTH_BITS, &depth)
也返回 24。
编辑:完整代码
Sprite *sprite1;
Sprite *sprite2;
GLuint program;
GLuint cameraAttribute;
int init_resources()
//Link shaders, create program and attach shaders
GLint link_ok = GL_FALSE;
GLuint vs, fs;
if ((vs = create_shader("vertShader.sh", GL_VERTEX_SHADER)) == 0) return 0;
if ((fs = create_shader("fragShader.sh", GL_FRAGMENT_SHADER)) == 0) return 0;
program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
if (!link_ok)
fprintf(stderr, "glLinkProgram:");
print_log(program);
return 0;
//Create Attributes
cameraAttribute = glGetUniformLocation(program, "camera");
if(cameraAttribute == -1)
cout << "Error!";
//Init sprites
sprite1 = new Sprite();
sprite2 = new Sprite();
return 1;
void onDisplay()
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
glUseProgram(program);
sprite1->render();
sprite2->render();
glutSwapBuffers();
void idle()
//Create Projection Matrix to change clip space.
mat4 projectionMatrix = perspective(60.0f, (float)glutGet(GLUT_WINDOW_WIDTH) / (float)glutGet(GLUT_WINDOW_HEIGHT), 0.1f, 100.f);
glUniformMatrix4fv(cameraAttribute, 1, GL_FALSE, &projectionMatrix[0][0]);
void free_resources()
glDeleteProgram(program);
int main(int argc, char* argv[])
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_ALPHA|GLUT_DOUBLE|GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutCreateWindow("My Second Triangle");
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
if (init_resources())
glutDisplayFunc(onDisplay);
glutIdleFunc(idle);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//uses glGetError to check for how many errors there are.
cout << CheckGLErrors() << "\n";
glutMainLoop();
free_resources();
return 0;
还有我的精灵文件:
#include "Sprite.h"
Sprite::Sprite()
init();
void Sprite::init()
GLfloat triangle_vertices[] =
0.0, 0.8f,
-0.8f, -0.8f,
0.8f, -0.8f,
;
//Set attributes
locationAttribute = glGetAttribLocation(program, "coord2d");
if (locationAttribute == -1)
fprintf(stderr, "Could not bind attribute location");
translationUniform = glGetUniformLocation(program, "translationUniform");
if(translationUniform == -1)
fprintf(stderr, "Could not bind attribute transformation");
//Create buffer
glGenBuffers(1, &mainBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mainBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_vertices), triangle_vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
locationAttribute, // attribute
2, // number of elements per vertex, here (x,y)
GL_FLOAT, // the type of each element
GL_FALSE, // take our values as-is
0, // no extra data between each position
0 // offset of first element
);
glBindBuffer(GL_ARRAY_BUFFER, 0);
void Sprite::render()
glBindBuffer(GL_ARRAY_BUFFER, mainBuffer);
glDrawArrays(GL_TRIANGLES, 0, 3);
和顶点着色器:(注意,版本由解析器添加)
attribute vec2 coord2d;
uniform mat4 translationUniform;
uniform mat4 camera;
void main(void)
gl_Position = camera * vec4(coord2d, -1.1, 1.0);
【问题讨论】:
【参考方案1】:glEnable(GL_BLEND | GL_DEPTH_TEST);
你不能像这样组合这些,你必须发出两个 glEnable 命令。这可能会产生错误,或者启用完全不同的东西。
您将此与使用位掩码的 glClear 混淆了。
开始在您的代码中使用glGetError
,它会为您发现这个问题。
【讨论】:
谢谢,但我只是出于绝望才尝试这个。它也不适用于两个单独的语句。 嗯,这很奇怪,这不是错误。 GL_BLEND 和 GL_DEPTH_TEST 的按位或为 0xBF3,这不是我能看到的任何 opengl 合法值。无论如何,我认为我发现了其他无关的东西,我将其发布在单独的帖子中。 @bipolarpants【参考方案2】:好的,我重新阅读了这个问题,我想我现在明白了。
三角形在 -1 到 1 之外消失,因为没有任何投影矩阵,您绘制的是标准化的设备坐标,该坐标具有 -1 到 1 的近端和远端裁剪平面。这意味着任何具有 z 值的顶点都在外面-1 到 1 的值将被剔除。
其次,你说你没有看到它随着距离变小。这是透视投影的一个特性,你没有(因为你没有投影矩阵)。使用默认投影矩阵(正交),您不会得到任何透视缩短,因此无论距离如何,您的三角形都将显示相同的大小。如果你想对场景应用透视,那么你需要一个透视矩阵:尝试应用gluPerspective(1, 45, 0.1, 100);
,这应该会给你更多的东西,就像你所期望的那样(三角形将出现,z 从 -0.1 到 -100,变得越来越小接近 z=-100)。您可能需要调整这些以匹配场景的规模。
【讨论】:
好的,原来我以为可能是这样。但是当我尝试时,我在顶点着色器中使用了转换(由 GLMs 透视()创建)并且没有效果。在我交换缓冲区之前,我也刚刚在我的 onDisplay() 函数中尝试了gluPerspective(1, 45, 0.1, 100);
,它也没有任何效果。即,改变 FoV 没有做任何事情,剪切平面也没有受到影响。
@bipolarpants 请发布您的完整代码,我无法从那些小 sn-ps 中看出发生了什么。
我相信这就是一切,如果有任何不清楚/错误的地方,你可以告诉我,我是 OpenGL 的新手(而且只有平庸的 C++)
出错没关系,有时每个人都是新的,但代码看起来很乱。到处都有大量未使用的代码,我无法理解您要做什么。着色器中不使用translationUniform。您生成 PV 矩阵,然后忽略它。也许从清理它开始,这样你就可以真正使用你生成的变量,也许你会在这个过程中自己解决它。 @bipolarpants
@bipolarpants:另外,您将“3”设置为 glVertexAttribPointer 的大小,应该为“2”,并且您在 sprite::move 中设置矩阵元素 3-3,它应该是 4-3(翻译在最后一列)。 gluPerspective 仅影响内置矩阵堆栈,如果您使用自己的 glm 矩阵,则无效。以上是关于OpenGL深度不起作用,三角形消失的主要内容,如果未能解决你的问题,请参考以下文章