0

透視投影について学んだばかりで、openGl に適用するのは少し混乱しています。

単純な Square を考えてみましょう。
透視投影を使用する前に、{0.0f,0.0f,0.0f,1.0f,1.0f,1.0f,1.0f,0.0 の入力に対して、[-1,1] 空間で頂点の座標を定義するだけで済みました。 f} の場合、正方形はウィンドウの第 1 象限を占めます。
私のコードから次の部分を検討してください。

マトリックスの設定:

    glm::mat4 mvp(1.0);
    mvp*=glm::perspective(45.0f,1.0f,0.01f,100.0f);

ユニフォーム:

    loc = glGetUniformLocation(program.getHandle(),"mvp");
    glUniformMatrix4fv(loc,1,GL_FALSE,glm::value_ptr(mvp));

頂点シェーダー:

    #version 330
    in vec2 pos;
    uniform mat4 mvp;
    void main()
    {
        gl_Position = mvp*vec4(pos,0.0f,1.0f);
    }

しかし、結果は空白の画面です。
ここで適用する必要がある追加の変換は何ですか?
また、頂点データはどの座標にあるべきですか?

完全なコードは次のとおりです。

#include "program.h"
#include <GL/glew.h>
#include <SFML/Window.hpp>
#include <stdexcept>
#include <iostream>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/core/type.hpp>

void GlewInit()
{
        GLenum err = glewInit();
        if (GLEW_OK != err)
        {
                std::cerr<<"Error: "<<glewGetErrorString(err)<<std::endl;
                throw(std::runtime_error("GLEW_INIT Failure."));
        }
}
int main()
{
    sf::Window win(sf::VideoMode(400,400),"Manasij");
    GlewInit();
    float vertexdata[]={0.0f,0.0f,0.0f,1.0f,1.0f,1.0f,1.0f,0.0f};
    GLubyte indexdata[]={0,1,2,3};
    float colordata[]={0.3f,0.0f,0.5f,1.0f};
    mm::Program program
    (
        {
            mm::Shader(GL_VERTEX_SHADER,"vshader.vert"),
            mm::Shader(GL_FRAGMENT_SHADER,"fshader.frag")
        }
    );

    glm::mat4 mvp(1.0);

    mvp*=glm::perspective(45.0f,1.0f,0.01f,100.0f);


    GLuint vao,vbo,ibo;
    glGenVertexArrays(1,&vao);
    glBindVertexArray(vao);

    glGenBuffers(1,&vbo);
    glBindBuffer(GL_ARRAY_BUFFER,vbo);
    glBufferData(GL_ARRAY_BUFFER,8*sizeof(GLfloat),vertexdata,GL_STATIC_DRAW);

    glGenBuffers(1,&ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,4*sizeof(GLubyte),indexdata,GL_STATIC_DRAW);

    glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,0,0);
    glEnableVertexAttribArray(0);
    glBindAttribLocation(program.getHandle(),0,"pos");


    glUseProgram(program.getHandle());
    auto loc = glGetUniformLocation(program.getHandle(),"col");
    glUniform4fv(loc,1,colordata);
    loc = glGetUniformLocation(program.getHandle(),"mvp");
    glUniformMatrix4fv(loc,1,GL_FALSE,glm::value_ptr(mvp));
    glUseProgram(0);


    glClearColor(1.0f,1.0f,1.0f,1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    while(win.isOpen())
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glUseProgram(program.getHandle());
//      glDrawArrays(GL_QUADS,0,4);
        glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,nullptr);
        glUseProgram(0);

        win.display();
        sf::Event eve;
        while(win.pollEvent(eve))
            if(eve.type==sf::Event::Closed)
                win.close();
    }
    return 0;
}
4

2 に答える 2

4

しかし、結果は空白の画面になります。ここで適用する必要がある追加の変換は何ですか?

呼び出しの最後の2つのパラメーターが表示されglm::perspectiveます。これらは、クリップの近距離と遠距離を定義します。あなたの正方形はZ=0にあり、それ以上変換しないと、表示ボリュームから外れます。解決策:seqareを-Z方向に数単位移動します。

近距離値と遠距離値に対する次の制約に注意してください。

  • abs(far)> abs(near)> 0

  • sgn(near)= sgn(far)

sgn(near)= sgn(far)=-の場合、深度範囲の符号を交換するか、深度テスト関数をGL_LESSに変更する必要があります。

デプスバッファの解像度は直線的に分散されていないため、1/zのように分散されます。

  • abs(near)はできるだけ大きくする必要があります
  • abs(far)はできるだけ小さくする必要があります。
于 2012-07-30T07:38:07.937 に答える
0

おそらく、この Web サイトが役に立ちます。OpenGL での射影行列の設定について説明しています。

http://www.songho.ca/opengl/gl_projectionmatrix.html

于 2012-08-07T12:51:10.810 に答える