2

解决方案

问题出在我的 z 区间中,我正在考虑 z 的负值,例如 (-0.1f < z < 100f),而不是我对近/远平面 ex 使用了正区间:(0.0f < z < 100.0f),我安排了OpenGL中已弃用无效的其他东西,我在我的glm :: lookAt上安排了我的坏位置。

注意:不要将旧的渲染方式与新的渲染方式混合使用(这是一个很好的做法,但可能会出现问题),顺便说一句:您必须了解您在空间中的位置。

谢谢大家:)


我是一名初学者图形程序员,我试图使用基本的顶点/片段着色器绘制一个非常简单的三角形。但是我的投影矩阵有一个错误,我找不到它。另外,我试图做一个 reshape void 并且我希望 reshape 回调与 shader 绘制的三角形一起工作。当我在我的渲染空白中编写这些产品时,会发生这种情况:

MVP = 投影矩阵 * 模型视图矩阵;

结果 ->我不喜欢

如果我只将 ModelView 矩阵分配给 MVP,我会得到:

结果->我也不喜欢,因为原点应该在左上角并且在窗口的中心

这些是我的重塑空隙

void OpenGL_Initialization(int w, int h){
    ProjectionMatrix = glm :: ortho(0.0f,(GLfloat)w,(GLfloat)h,0.0f,0.1f, 100.0f);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glLoadMatrixf(glm :: value_ptr(ProjectionMatrix));
    glMatrixMode(GL_MODELVIEW);
}

void Reshape(int w, int h){
    width  = w;
    height = h;
    glViewport(0,0,w,h);
    OpenGL_Initialization(w,h);
}

这是我的渲染回调:

void Render(){
    glClearColor(0.75,0.75,0.75,1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glGetFloatv(GL_MODELVIEW_MATRIX,glm :: value_ptr(ModelViewMatrix));

    MVP = ProjectionMatrix * ModelViewMatrix;

    glUniformMatrix4fv(glGetUniformLocation(ProgramHandler,"MVP"),1,GL_FALSE,glm :: value_ptr(MVP));

    glBindVertexArray(vaoHandle);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glBindVertexArray(0);

    glutSwapBuffers();

}

这些也是我的顶点和片段着色器

#version 400

layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexColor;

uniform mat4 MVP;

out vec3 Color;

void main(){    
    Color = VertexColor;
    gl_Position = MVP*vec4(VertexPosition,1.0);
}

#version 400
in  vec3 Color;
out vec4 FragColor;
void main(){
    FragColor = vec4(Color,1.0);
}

VBO 和 VAO 初始化:

void InitVBO(GLuint programHandler){
    glBindAttribLocation(programHandler,0,"VertexPosition");
    glBindAttribLocation(programHandler,1,"VertexColor");

    GLfloat positionData[] = {-0.5f,0.5f,0.0f,0.0f,-.5f,0.0f,0,0,0};
    GLfloat colorData[]    = {1.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,0.0f,1.0f};

    GLuint vboHandles[2];

    glGenBuffers(2,vboHandles);

    glBindBuffer(GL_ARRAY_BUFFER,vboHandles[0]);
    glBufferData(GL_ARRAY_BUFFER,9*sizeof(GLfloat),positionData,GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER,vboHandles[1]);
    glBufferData(GL_ARRAY_BUFFER,9*sizeof(GLfloat),colorData,GL_STATIC_DRAW);

    glGenVertexArrays(1, &vaoHandle);
    glBindVertexArray(vaoHandle);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    glBindBuffer(GL_ARRAY_BUFFER, vboHandles[0]);
    glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0,(GLubyte *)NULL );

    glBindBuffer(GL_ARRAY_BUFFER, vboHandles[1]);
    glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 0,(GLubyte *)NULL );
}

4

2 回答 2

2

看来您正在混合使用固定功能管道(即 GL1.x)调用和可编程着色器管道调用。虽然它可能不会导致您所描述的问题,但通常认为使用其中一个或另一个而不是同时使用两者是一种很好的做法。

上传要由着色器程序使用的矩阵的正确方法是调用glUniformMatrix4fv(正如您所做的那样)。但是,函数中glMatrixModeglLoadIdentityglLoadMatrix调用OpenGL_Initialization(int w, int h)实际上与您正在使用的着色器程序的状态无关;相反,他们正在改变现已弃用的矩阵堆栈的状态。

同样,该glGetFloatv(GL_MODELVIEW_MATRIX,glm :: value_ptr(ModelViewMatrix))调用正在获取内置矩阵堆栈使用的模型视图矩阵数据,其中可能包含垃圾数据。

基本上,我建议你做的是放弃所有已弃用的功能,并OpenGL_Initialization像这样简单地重新实现该功能:

void OpenGL_Initialization(int w, int h){
     ProjectionMatrix = glm::ortho(0.0, (GLfloat)w, (GLfloat)h, 0.0, -1.0, 1.0);
}

在你的渲染回调中你会做

glClearColor(0.75, 0.75, 0.75, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glm::mat4 ModelViewMatrix; // default constructor => identity
MVP = ProjectionMatrix * ModelViewMatrix;

glUseProgram(ProgramHandler); // possibly redundant
GLuint MVP_loc = glGetUniformLocation(ProgramHandler, "MVP");
glUniformMatrix4fv(MVP_loc, 1, GL_FALSE, glm::value_ptr(MVP));

/* draw, swap buffers */
于 2013-08-21T17:40:12.673 回答
0

您的代码中有两个问题,

  1. 您的三角形位于 z=0 平面,但您将近/远设置为 0.1 和 100,因此您的三角形不在视锥体中,您需要将 z 值设置在 (-0.1 < z < -100) 的范围内
  2. 如果 w, h 是窗口的大小,那么光栅化后的三角形将只占据屏幕上的一个像素,换句话说,您几乎看不到屏幕上的任何内容。你可以认为你在以像素为单位的窗口空间中,所以你需要有一个合理大小的三角形。所以,这个问题的修复,或者你改变你的顶点位置更大,例如(w / 2,h / 2,-1,w,h / 2,-1,w,h,-1)或者你可以改变orth 为 glm :: ortho(-1, 1, -1, 1, 0.1f, 100.0f);
于 2013-08-22T14:34:35.277 回答