0
votes

I'm using transform feedback approach to capture the transformed coordinates vertices after loading them. I'm testing on a simple CUBE with 4 faces (the bottom and top faces are not considered).

Here is my code , and the results i got. You will notice that the coordinates i get back are outside the range of [-1 1]. In many tutorials, they say that they have to be inside this interval. Can you help me ?

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

The transformed coordinates returned by the transform feed back are:

-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

== what i got after the recommandations you gave me i did your recommendation, this is what i got when i'm facing the red face of the cube

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

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

I don't know why the values of the Z buffet are all equal to 1 ?

The result semms good, because the visible vertices are those having their "WindowZ transformed coordinates into [-1 1]" < Z depth buffer.

When i change the position of the camera with a lookat(..), the values of "WindowZ transformed coordinates into [-1 1]" become all < 1 despite the vertices are visible ! ?

1
i added "Hi everybody" in my msg, but i doesn't appear!Anouss
We don't really like greetings and signatures here, they often get edited out eventually anyway.ratchet freak
Can you add the code you use to read the depth buffer to your question? I can tell you right away that all of your vertices are very close to the far clipping plane (some of them are even beyond it). All of your vertices are very close to the far clip plane, you should move the near clipping plane farther out in this case to enhance depth buffer precision.Andon M. Coleman
for reading the depth buffer, i used : float x; ReadPixels(windowX ,windowY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &x); // I put 1, 1 in parameters because if a put 800,600 the program beug! i read on a discussion that they should be 1 ,1 if we want to read 1 pixel from the Z buffer. For the near and far planes i use the distances : proj = glm::perspective(45.0f, 800.0f / 600.0f, 1.0f, 10.0f);Anouss
I did the math to calculate your window-space Y coordinates and got something different. You have a window with dimensions 800x600, so that means the viewport height is 600. (-0.321895 * 0.5 + 0.5) * 600 = 203.432, not 135.621.Andon M. Coleman

1 Answers

0
votes

There is nothing technically wrong with this.

You have 4D coordinates here with a non-1.0 value for the w component, that is a dead giveaway that the coordinates are not in NDC space. During the transformation from clip-space to NDC space, all components are divided by w and this means that an NDC vector will always have a w component of 1.0.

What you have here are the clip-space vertex positions. Divide everything by w and everything except for a couple of vertices with Z values beyond the farplane will fit nicely into your [-1,1] viewing volume.

This vertex in particular is clipped by the far plane:

-2.71599 2.41421 10.6111 10.5

Because this is the vertex after division by w

-0.25866 0.22992 1.01058 1.0