Coordinate values act as if they were much bigger

Viewed 52

I was trying to draw with coordinates being of integer type, but failed. Then I tried to draw a simple triangle as if from tutorial. In the result half of the screen was of triangle's color, other was glClearColor I set. I started changing values, and corners started to show up when coordinates were smaller than 0.00000000000000000005f (which i suspect would be of higher precision than a float), though should have been already with smaller than 1.0f. Trying to search didn't have any results, perhaps because I don't know the right words.

Here's code I ended up with:

Includes and function I quickly moved here:

#include <GL/glew.h>

#include <glfw3.h>

#include <unistd.h>
#include <stdio.h>

/* function that creates shader */
GLuint makeShader(const GLchar* vertexShaderSource, const GLchar* fragmentShaderSource,
                                  GLchar*& infoLog, const GLchar* geometryShaderSource = NULL)
{

    GLint isSuccess;
    infoLog = nullptr;

    GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShaderID, 1, &vertexShaderSource, nullptr);
    glCompileShader(vertexShaderID);

    glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &isSuccess);

    if(!isSuccess)
    {
        infoLog = new GLchar[1024];
        glGetShaderInfoLog(vertexShaderID, 1024, nullptr, infoLog);
        printf("Error compiling vertex shader: %s\n", infoLog);
        printf("\n%s\n\n", vertexShaderSource);
        return 0;
    }

    GLuint geometryShaderID;
    if(geometryShaderSource!=NULL){

        geometryShaderID = glCreateShader(GL_GEOMETRY_SHADER);
        glShaderSource(geometryShaderID, 1, &geometryShaderSource, nullptr);
        glCompileShader(geometryShaderID);

        glGetShaderiv(geometryShaderID, GL_COMPILE_STATUS, &isSuccess);

        if(!isSuccess)
        {
            infoLog = new GLchar[1024];
            glGetShaderInfoLog(geometryShaderID, 1024, nullptr, infoLog);
            printf("Error compiling geometry shader: %s\n", infoLog);
            printf("\n%s\n\n", geometryShaderSource);
            return 0;
        }
    }

    GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShaderID, 1, &fragmentShaderSource, nullptr);
    glCompileShader(fragmentShaderID);

    glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &isSuccess);

    if(!isSuccess)
    {
        infoLog = new GLchar[1024];
        glGetShaderInfoLog(fragmentShaderID, 1024, nullptr, infoLog);
        printf("Error compiling fragment shader: %s\n", infoLog);
        printf("\n%s\n\n", fragmentShaderSource);
        return 0;
    }

    GLuint shaderID = glCreateProgram();
    glAttachShader(shaderID, vertexShaderID);
    glAttachShader(shaderID, fragmentShaderID);
    if(geometryShaderSource!=NULL){
        glAttachShader(shaderID, geometryShaderID);
    }
    glLinkProgram    (shaderID);
    glValidateProgram(shaderID);

    glDeleteShader(vertexShaderID);
    glDeleteShader(fragmentShaderID);
    if(geometryShaderSource!=NULL){
        glDeleteShader(geometryShaderID);
    }

    glGetProgramiv(shaderID, GL_LINK_STATUS, &isSuccess);

    if (!isSuccess)
    {
        infoLog = new GLchar[1024];
        glGetProgramInfoLog(shaderID, 1024, nullptr, infoLog);     // Generate error as infoLog
        //std::cout << "Error " << infoLog << std::endl;  // Display
        printf("Error linking shader %s\n", infoLog);
        return 0;
    }
    return shaderID;
}

Main:

int main(void)
{
    GLFWwindow* window;
    float FPSlimit = 60;
    int windowSX = 800, windowSY = 600;

    /* Initialize the library */
    if (!glfwInit()){
        return -1;}

    /* Create window */
    window = glfwCreateWindow(windowSX, windowSY, "abc", NULL, NULL);
    if (!window)
    {
        printf("Failed to create window\n");
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(0);

    /* Initialize GLEW */
    if(glewInit()){
        printf("Failed to initialize GLEW\n");
        glfwTerminate();
        return -1;
    }

    glClearColor(0.1, 0.3f, 0.2f, 1.0f);
    double timeDeltaFPSmaintain = 0;

    GLuint vao;
    GLuint vbo;
    glGenVertexArrays(1, &vao);
    glGenBuffers(1, &vbo);

    glBindVertexArray(vao);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    //changing normalisation to GL_TRUE didnt do anything

    float dat[] = {-0.000000000000000000024f, -0.000000000000000000024f, 0.f,
                    1.f, -1.f, 0.f,
                    0.f, 0.000000000000000000054f, 0.f};
    glBufferData(GL_ARRAY_BUFFER, 3*3*sizeof(float), dat, GL_STATIC_DRAW);

    GLchar* log;
    const GLchar* v = "#version 330 \n layout (location = 0) in vec3 pos;\n void main(){gl_Position = vec4(pos.xyz, 0);}";
    const GLchar* f = "#version 330 \n out vec4 color; void main(){color = vec4(1, 0, 0, 0);}";
    GLuint sha = makeShader(v, f, log);
    printf("%i\n", glGetError());//Shows 0

    /* Main loop: */
    while (!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glUseProgram(sha);
        glBindVertexArray(vao);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glfwSwapBuffers(window);

        glfwPollEvents();

        // nvidia starts to use 100% of one of CPU cores with vSync for some reason
        timeDeltaFPSmaintain = (glfwGetTime() - timeDeltaFPSmaintain)*1000000;
        if(FPSlimit>1){
            usleep(1000000/FPSlimit-unsigned(timeDeltaFPSmaintain));}
        timeDeltaFPSmaintain = glfwGetTime();
    }

    glfwTerminate();
    return 0;
}

Compiler also tells me about corrupt .drective at the end of def file but I doubt it matters much.

1 Answers

The transformation in your vertex shader is just broken:

gl_Position = vec4(pos.xyz, 0);

Setting w_clip = 0 will mean that conceptually, your points are infinitly far away into the direction of x,y,z, and the GPU will clip your primitive to the intersection with the viewing volume (which still is finite).

Also:

I started changing values, and corners started to show up when coordinates were smaller than 0.00000000000000000005f (which i suspect would be of higher precision than a float),

That's not how floating point numbers work, the precision approaching zero is quite high, the smallest non-denormalized single precision floating point number will be 2^(-126), which is approximately 0.000000000000000000000000000000000000012, and you can get down to 2^-149 if you go into the de-normalized range.

Related