首页 文章

Shader GLSL OpenGL上的投影矩阵问题

提问于
浏览
2

SOLUTION

问题出在我的z区间我正在考虑z上的负值(-0.1f <z <100f),相反,我使用了近/远平面ex的正间隔:(0.0f <z <100.0f),我安排了在OpenGL中被弃用的其他东西,我把我的不良位置安排在我的glm :: lookAt上 .

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

谢谢大家们:)


我的投影矩阵有一个错误,我找不到它 . 另外, Im trying to do a reshape void and I want that reshape callback works well with the triangle drawn by the shader . 当我在渲染中写出这些产品时,会发生以下情况:

MVP = ProjectionMatrix * ModelViewMatrix;

结果 - > I dont Like

如果我只分配给MVP ModelView Matrix我得到了这个:

结果 - > I dont Like too because the origin should be in the upper left corner and is in the center of the window

These are my Reshape Voids

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

And this is my render callback :

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

}

Also these are my vertex and fragment shader

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

The VBOs and VAO initialization:

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

2 回答

  • 2

    您似乎正在使用fixed-function pipeline(即GL1.x)调用和可编程着色器管道调用的混合 . 虽然通常认为使用其中一个或另一个通常被视为良好做法,但不能同时使用两者 .

    上传着色器程序使用的矩阵的正确方法是调用 glUniformMatrix4fv (正如您所做的那样) . 但是, OpenGL_Initialization(int w, int h) 函数中的 glMatrixModeglLoadIdentityglLoadMatrix 调用实际上对着色器程序的状态没有影响,而're using; instead they'重新改变了now-deprecated矩阵堆栈的状态 .

    类似地, 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 */
    
  • 0

    您的代码中存在两个问题,

    • 您的三角形位于z = 0平面,但您将near / far设置为0.1和100,因此您的三角形不在视锥体之外,您需要在(-0.1 <z <-100)的范围内设置z值)

    • 如果w,h是窗口的大小,则光栅化后的三角形只会占据屏幕上的一个像素,换句话说,屏幕上几乎看不到任何内容 . 你可以认为你在窗口空间中有像素单位,所以你需要有一个合理的大小三角形 . 所以,对于这个问题的修复,要么你改变你的顶点位置,例如, (w / 2,h / 2,-1,w,h / 2,-1,w,h,-1)或者你可以将正数改为glm :: ortho(-1,1,-1,1 ,0.1f,100.0f);

相关问题