变换反馈打开gl返回的变换坐标

时间:2014-11-07 14:14:43

标签: c++ opengl

我使用变换反馈方法在加载后捕获变换后的坐标顶点。我在一个有4个面的简单CUBE上进行测试(不考虑底面和顶面)。

这是我的代码,以及我得到的结果。你会注意到我回来的坐标超出了[-1 1]的范围。在许多教程中,他们说他们必须在这个区间内。你能帮助我吗 ?

// Link statically with GLEW
#define GLEW_STATIC

// Headers
#include <GL/glew.h>
#include <SFML/Window.hpp>
#include<glm/glm/gtc/matrix_transform.hpp>
#include<glm/glm/gtc/type_ptr.hpp>

 #define GLSL(src) "#version 150 core\n" #src

// Shader sources
const GLchar* vertexSource =
    "#version 150 core\n"
    "in vec3 position;"
    "in vec3 color;"

    "out vec3 Color;"
        "out vec4 outposition;"
    "uniform mat4 model;"
    "uniform mat4 view;"
    "uniform mat4 proj;"

    "void main() {"

    "   Color = color;"

    "   gl_Position = proj * view    * vec4(position, 1.0);"

        "outposition=gl_Position;"
    "}";


const GLchar* fragmentSource =
    "#version 150 core\n"
    "in vec3 Color;"

    "out vec4 outColor;"


    "void main() {"
    "   outColor = vec4(Color, 1.0) ;"
    "}";

int main()
{
    sf::ContextSettings settings;
    settings.depthBits = 24;
    settings.stencilBits = 8;

    sf::Window window(sf::VideoMode(800, 600, 32), "OpenGL", sf::Style::Titlebar | sf::Style::Close, settings);
glViewport( 0 , 0 , 800,600 );
 glEnable(GL_DEPTH_TEST);
 glDepthFunc(GL_LEQUAL);
 glColorMask;
 //glEnable(GL_CULL_FACE);
 //glFrontFace(GL_CW);// pour lui dire que les polygones faces à la caméra ont des noeuds dans le sens horaire
 //glCullFace(GL_BACK);

    // Initialize GLEW
    glewExperimental = GL_TRUE;
    glewInit();

    // Create and compile the vertex shader
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexSource, NULL);
    glCompileShader(vertexShader);

    // Create and compile the fragment shader
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
    glCompileShader(fragmentShader);

   // Link the vertex and fragment shader into a shader program
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glBindFragDataLocation(shaderProgram, 0, "outColor");

   const GLchar* feedbackVaryings[] = { "outposition" };
        glTransformFeedbackVaryings(shaderProgram, 1, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);

    glLinkProgram(shaderProgram);
    glUseProgram(shaderProgram);

    // Create Vertex Array Object
    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    // Create a Vertex Buffer Object and copy the vertex data to it
    GLuint vbo;
    glGenBuffers(1, &vbo);


//cube avec des faces carrees
  GLfloat vertices2[] = {
    //Frontie red

        -1.5f, -1.0f, 1.5f, 1.0f, 0.0f, 0.0f, //bottom left

       1.5f, -1.0f, 1.5f, 1.0f, 0.0f, 0.0f, //bottom right

       1.5f, 1.0f, 1.5f, 1.0f, 0.0f, 0.0f, //top right

      -1.5f, 1.0f, 1.5, 1.0f, 0.0f, 0.0f, //top left

        //Rightvert
       //
        1.5f, -1.0f, -1.5f, 0.0f, 1.0f, 0.0f,
        1.5f, 1.0f, -1.5f, 0.0f, 1.0f, 0.0f,
        1.5f, 1.0f, 1.5f, 0.0f, 1.0f, 0.0f,
        1.5f, -1.0f, 1.5f, 0.0f, 1.0f, 0.0f,

        //Back bleu

        -1.5f, -1.0f, -1.5f, 0.0f, 0.0f, 1.0f,
        -1.5f, 1.0f, -1.5f, 0.0f, 0.0f, 1.0f,

         1.5f, 1.0f, -1.5f, 0.0f, 0.0f, 1.0f,

         1.5f, -1.0f, -1.5f, 0.0f, 0.0f, 1.0f,

        //Left jaune

         -1.5f, -1.0f, -1.5f, 1.0f, 1.0f, 0.0f,
         -1.5f, -1.0f, 1.5f, 1.0f, 1.0f, 0.0f,
         -1.5f, 1.0f, 1.5f, 1.0f, 1.0f, 0.0f,
         -1.5f, 1.0f, -1.5f, 1.0f, 1.0f, 0.0f,
      };    


    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);

    // Specify the layout of the vertex data
    GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
    glEnableVertexAttribArray(posAttrib);
    glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);

    GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
    glEnableVertexAttribArray(colAttrib);
    glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));

    GLint uniModel = glGetUniformLocation(shaderProgram, "model");

    // Set up projection
    glm::mat4 view = glm::lookAt(
        glm::vec3(0.0f, 0.0f, 9.0f),
        glm::vec3(0.0f, 0.0f, 0.0f),
        glm::vec3(0.0f, 1.0f, 0.0f)
    );
    GLint uniView = glGetUniformLocation(shaderProgram, "view");
    glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view));

    glm::mat4 proj = glm::perspective(45.0f, 800.0f / 600.0f, 1.0f, 10.0f);
    GLint uniProj = glGetUniformLocation(shaderProgram, "proj");
    glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj));
       //Create transform feedback buffer
        GLuint tbo;
        glGenBuffers(1, &tbo);
        glBindBuffer(GL_ARRAY_BUFFER, tbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), NULL, GL_STATIC_READ);

        // Perform feedback transform
        glEnable(GL_RASTERIZER_DISCARD);
        glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tbo);
        glBeginTransformFeedback(GL_POINTS);
        glDrawArrays(GL_POINTS, 0, 48);
        glEndTransformFeedback();
        glDisable(GL_RASTERIZER_DISCARD);

         glFlush();

        // Fetch and print results
        GLfloat feedback[64];
        glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(feedback), feedback);
int k=0;
        for(int i=0;i<64;i++)
        {            
            cout<<feedback[i]<<" ";
            k++;
            if(k==4){cout<<endl; k=0;}
        }

    while (window.isOpen())
    {
        sf::Event windowEvent;
        while (window.pollEvent(windowEvent))
        {
            switch (windowEvent.type)
            {
            case sf::Event::Closed:
                window.close();
                break;
            }
        }

        // Clear the screen to black
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
         glClear(GL_COLOR_BUFFER_BIT    | GL_DEPTH_BUFFER_BIT);
        // Calculate transformation
        glm::mat4 model;
        model = glm::rotate(model,/*(GLfloat)clock() / (GLfloat)CLOCKS_PER_SEC*/ 0.0f,glm::vec3(0.0f, 0.0f, 1.0f));

        glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model));

        // Draw cube


         glDrawArrays(GL_QUADS, 0, 48);

      //  glDrawArrays(GL_POINTS, 0, 36);

        // Swap buffers
        window.display();

    }
    glDeleteProgram(shaderProgram);
    glDeleteShader(fragmentShader);
    glDeleteShader(vertexShader);

    glDeleteBuffers(1, &vbo);

    glDeleteVertexArrays(1, &vao);
}

转换反馈返回的变换坐标为:

-2.71599 -2.41421 6.94444 7.5
2.71599 -2.41421 6.94444 7.5
2.71599 2.41421 6.94444 7.5
-2.71599 2.41421 6.94444 7.5
2.71599 -2.41421 10.6111 10.5
2.71599 2.41421 10.6111 10.5
2.71599 2.41421 6.94444 7.5
2.71599 -2.41421 6.94444 7.5
-2.71599 -2.41421 10.6111 10.5
-2.71599 2.41421 10.6111 10.5
2.71599 2.41421 10.6111 10.5
2.71599 -2.41421 10.6111 10.5
-2.71599 -2.41421 10.6111 10.5
-2.71599 -2.41421 6.94444 7.5
-2.71599 2.41421 6.94444 7.5
-2.71599 2.41421 10.6111 10.5

==在你给我的推荐之后我得到了什么 我做了你的推荐,这是我面对立方体的红脸时所得到的。

lookAt(glm :: vec3(0.0f,0.0f,9.0f),glm :: vec3(0.0f,0.0f,0.0f),glm :: vec3(0.0f,1.0f,0.0f) );

&#13;
&#13;
NDC before division by w
-2.71599 -2.41421 6.94444 7.5
2.71599 -2.41421 6.94444 7.5
2.71599 2.41421 6.94444 7.5
-2.71599 2.41421 6.94444 7.5
2.71599 -2.41421 10.6111 10.5
2.71599 2.41421 10.6111 10.5
2.71599 2.41421 6.94444 7.5
2.71599 -2.41421 6.94444 7.5
-2.71599 -2.41421 10.6111 10.5
-2.71599 2.41421 10.6111 10.5
2.71599 2.41421 10.6111 10.5
2.71599 -2.41421 10.6111 10.5
-2.71599 -2.41421 10.6111 10.5
-2.71599 -2.41421 6.94444 7.5
-2.71599 2.41421 6.94444 7.5
-2.71599 2.41421 10.6111 10.5
-2.71599 -2.41421 6.94444 7.5
2.71599 -2.41421 6.94444 7.5
2.71599 2.41421 6.94444 7.5
-2.71599 2.41421 6.94444 7.5
2.71599 -2.41421 10.6111 10.5
2.71599 2.41421 10.6111 10.5
2.71599 2.41421 6.94444 7.5
2.71599 -2.41421 6.94444 7.5
-2.71599 -2.41421 10.6111 10.5
-2.71599 2.41421 10.6111 10.5
2.71599 2.41421 10.6111 10.5
2.71599 -2.41421 10.6111 10.5
-2.71599 -2.41421 10.6111 10.5
-2.71599 -2.41421 6.94444 7.5
-2.71599 2.41421 6.94444 7.5
-2.71599 2.41421 10.6111 10.5


NDC after division by w (all component are divied by w)
-0.362132 -0.321895 0.925926 1
0.362132 -0.321895 0.925926 1
0.362132 0.321895 0.925926 1
-0.362132 0.321895 0.925926 1
0.258666 -0.229925 1.01058 1
0.258666 0.229925 1.01058 1
0.362132 0.321895 0.925926 1
0.362132 -0.321895 0.925926 1
-0.258666 -0.229925 1.01058 1
-0.258666 0.229925 1.01058 1
0.258666 0.229925 1.01058 1
0.258666 -0.229925 1.01058 1
-0.258666 -0.229925 1.01058 1
-0.362132 -0.321895 0.925926 1
-0.362132 0.321895 0.925926 1
-0.258666 0.229925 1.01058 1

window x and windoy coords
255.147 135.621
544.853 135.621
544.853 264.379
255.147 264.379
503.466 154.015
503.466 245.985
544.853 264.379
544.853 135.621
296.534 154.015
296.534 245.985
503.466 245.985
503.466 154.015
296.534 154.015
255.147 135.621
255.147 264.379
296.534 245.985

z depth buffer
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1

WindowZ  transformed into [-1 1]
0.962963
0.962963
0.962963
0.962963
1.00529
1.00529
0.962963
0.962963
1.00529
1.00529
1.00529
1.00529
1.00529
0.962963
0.962963
1.00529
&#13;
&#13;
&#13;

我不知道为什么Z自助餐的价值都等于1?

结果semms很好,因为可见顶点是那些具有&#34; WindowZ变换坐标为[-1 1]&#34; &LT; Z深度缓冲区。

当我用lookat(..)改变相机的位置时,&#34; WindowZ的值将坐标转换为[-1 1]&#34;成为所有&lt;尽管顶点是可见的! ?

1 个答案:

答案 0 :(得分:0)

这在技术上没有任何问题。

此处有4D坐标,w组件的非 1.0 值,这是坐标不在NDC空间中的死亡赠品。在从剪辑空间到NDC空间的转换过程中, 所有 组件除以w,这意味着NDC向量将始终具有{{1} 1.0 的组件。

这里有你的剪辑空间顶点位置。将所有内容除以w除了远离飞机的Z值的几个顶点之外的所有内容都很适合您的[ -1 1 ]查看量。

此顶点特别被远平面剪切:

w

因为这是除以w

之后的顶点
-2.71599 2.41421 10.6111 10.5