如何在多个视口中使用透视和正射(OpenGL 4.x)

时间:2016-06-17 10:33:45

标签: opengl

我需要使用不同的投影(ortha,perspective,fustrum)在不同的视口中渲染一些场景。

//1
    glViewport( 0, 0, 500, 500);
    ortho = glm::ortho(left, right, top, bottom, -1.f, 1.f); //-1.f, 1.f, -1.f, 1.f, -1.f, 1.f
    GLint orthoLoc = glGetUniformLocation(programID, "ortho");
    glUniformMatrix4fv(orthoLoc, 1, GL_FALSE, &ortho[0][0]);
    Projection::lookAtScene(programID, glm::vec3(0, 1, 0), glm::vec3(0, 0, 0), glm::vec3(1, 0, 0)); 
    drawCube();

//2
    glViewport(500, 0, 500, 500);
    glm::mat4 fru = glm::frustum(left, right, top, bottom, 1.f, 20.f);
    GLint fruLoc = glGetUniformLocation(programID, "fru");
    glUniformMatrix4fv(fruLoc, 1, GL_FALSE, &fru[0][0]);
    Projection::lookAtScene(programID, glm::vec3(0, 0, 0), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0));    
    drawCube();
顶点着色器中的

uniform mat4 ortho;
uniform mat4 proj;
uniform mat4 view;
uniform mat4 fru;
...
mat4 Model = rotate*scale*trans;
Model = Model*ortho*view*fru;
    gl_Position = Model*vec4(pos.xyz, 1);

作为一个结果,我只看到透视投影。我知道这不是最好的方法。我怎么能正确地做到这一点,以便在每个视口中都有自己的投影。

2 个答案:

答案 0 :(得分:0)

您必须为视口提供偏移量,否则它们将被相互吸引。你也应该研究一下“剪刀测试”。

答案 1 :(得分:0)

呃,让我们看看..

在着色器上它应该看起来像:

gl_Position = completeProjection * vec4(position, 1.0f);

但是,我发现你想在一个着色器中使用透视和正投影? (如果我错在这里,请纠正我)。如果你想这样,你可以这样做:

gl_Position = perspectiveProjection * orthoProjection * view * model * vec4(position, 1.0f);

在你的代码中它就像:

uniform mat4 ortho;
uniform mat4 proj;
uniform mat4 view;
uniform mat4 fru;

void main() {
    mat4 Model = rotate * scale * trans; // Same
    Model = ortho * fru * view * Model; // the order of ortho and fru here doesn't matter (See explanation below) /!\The order for the other is importent though/!\
    gl_Position = Model * vec4(pos.xyz, 1); // By this point, Model is a complete projection
}

切换相机时,请记住将未使用的矩阵放入标识矩阵。身份矩阵不会做任何事情,因此orthofru的顺序并不重要,因为其中一个将是一个身份。 虽然我建议你只使用一个名为projection的制服,然后每次想要从不同的视角渲染时,都会将正交/透视矩阵上传到它。这样,您就不需要将未使用的矩阵设置为标识。像:

// ---Code---

// Preparing ortho matrix & other matrices
glUniformMatrix4fv(glGetUniformLocation(programID, "proj"), 1, GL_FALSE, &ortho[0][0]);
drawCube();
// Preparing perspective matrix & other matrices
glUniformMatrix4fv(glGetUniformLocation(programID, "proj"), 1, GL_FALSE, &fru[0][0]);
drawCube();

// ---Vertex Shader---

uniform mat4 proj;
uniform mat4 view;

void main() {
    mat4 Model = rotate * scale * trans; // Same
    Model = proj * view * Model; // the order of ortho and fru here doesn't matter (See explanation below)
    gl_Position = Model * vec4(pos.xyz, 1); // By this point, Model is a complete projection
}

P.s:我看到你已经有proj矩阵制服..

那就是说,由于缺乏信息我不能再说了。但这就是我在那里看错了。