Рисование треугольника не работает: я вижу только черный экран и мышь

Я использую GLEW для современных функций OpenGL и GLFW для окна. Я пытаюсь нарисовать треугольник, но что-то не так, он компилируется и запускается, но не рисует треугольник, я просто вижу черный экран и свою мышь. Вот мой код:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <glew.h>
#include <GLFW\glfw3.h>
#include <glm\glm.hpp>

const GLchar* vertexSource =
"#version 150 core\n"
"in ver2 position;"
"void main(){"
"   gl_Position = vec4(position, 0.0, 1.0);"
"}";

const GLchar* fragmentSource =
"#version 150 core\n"
"out vec4 outColor;"
"void main(){"
"   outColor = vec4(1.0, 1.0, 1.0, 1.0);"
"}";

int main(){

    //GLFW init:
    if (!glfwInit()){
        fprintf(stderr, "Failed to init GLFW");
        glfwTerminate();
    }

    //Hints:
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

    //Creating window:
    GLFWwindow* window = glfwCreateWindow(800, 600, "Engine", glfwGetPrimaryMonitor(), nullptr);
    glfwMakeContextCurrent(window);

    //Glew initialize:
    glewExperimental = GL_TRUE;
    glewInit();

    //Create vertex array object:
    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    //Create vertex buffer object:
    GLuint vbo;
    glGenBuffers(1, &vbo);

    //Our triangle data:
    GLfloat vertices[] = {
         0.0f,  0.5f, //Vertex 1 (X, Y)
         0.5f, -0.5f, //Vertex 2 (X, Y)
        -0.5f, -0.5f  //Vertex 3 (X, Y)
    };

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

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

    //Creating shaders program:
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glBindFragDataLocation(shaderProgram, 0, "outColor");
    glLinkProgram(shaderProgram);
    glUseProgram(shaderProgram);

    GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
    glEnableVertexAttribArray(posAttrib);
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);



    //The loop:
    while (!glfwWindowShouldClose(window)){

        //Escape key:
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS){
            glfwSetWindowShouldClose(window, GL_TRUE);
        }

        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }



    return 0;
}

person Casper    schedule 23.05.2014    source источник


Ответы (2)


"in ver2 position;"
    ^^^^

Что такое ver2? Я сомневаюсь, что ваш компилятор GLSL тоже это знает.

Попробуйте vec2 и проверьте компиляцию шейдера/состояние ссылки/журналы:

struct Program
{
    static GLuint Load( const char* vert, const char* geom, const char* frag )
    {
        GLuint prog = glCreateProgram();
        if( vert ) AttachShader( prog, GL_VERTEX_SHADER, vert );
        if( geom ) AttachShader( prog, GL_GEOMETRY_SHADER, geom );
        if( frag ) AttachShader( prog, GL_FRAGMENT_SHADER, frag );
        glLinkProgram( prog );
        CheckStatus( prog );
        return prog;
    }

private:
    static void CheckStatus( GLuint obj )
    {
        GLint status = GL_FALSE;
        if( glIsShader(obj) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
        if( glIsProgram(obj) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
        if( status == GL_TRUE ) return;
        GLchar log[ 1 << 15 ] = { 0 };
        if( glIsShader(obj) ) glGetShaderInfoLog( obj, sizeof(log), NULL, log );
        if( glIsProgram(obj) ) glGetProgramInfoLog( obj, sizeof(log), NULL, log );
        std::cerr << log << std::endl;
        exit( -1 );
    }

    static void AttachShader( GLuint program, GLenum type, const char* src )
    {
        GLuint shader = glCreateShader( type );
        glShaderSource( shader, 1, &src, NULL );
        glCompileShader( shader );
        CheckStatus( shader );
        glAttachShader( program, shader );
        glDeleteShader( shader );
    }
};
person genpfault    schedule 23.05.2014
comment
Вау, я не могу поверить, что это была проблема .. ты. - person Casper; 23.05.2014

вам не нужно использовать glBindFragDataLocation, вместо этого напишите gl_FragColor во фрагментном шейдере:

const GLchar* fragmentSource =
"#version 150 core\n"
"void main(){"
"   gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);"
"}";

в противном случае вам нужно указать, в какой буфер он записывается с помощью glDrawBuffers

person ratchet freak    schedule 23.05.2014
comment
Плакат использует основной профиль, где gl_FragColor устарел. Но вызов glBindFragDataLocation все равно не нужен. Если фрагментный шейдер имеет только один out, он автоматически записывается в первый буфер отрисовки (который по умолчанию равен GL_BACK для фреймбуфера по умолчанию и GL_COLOR_ATTACHMENT0 для FBO). - person Reto Koradi; 24.05.2014
comment
@RetoKoradi: На самом деле, я никогда не мог найти такую ​​​​гарантию в спецификации. Все, что говорится в спецификации, это то, что GL автоматически назначит любые выходы, где местоположение не назначено вручную какому-то неиспользуемому номеру цвета. Каждая реальная реализация начинает присваивание с 0 по очевидным причинам, но полагаться на это по-прежнему неопределённое поведение, если говорить о спецификации. - person derhass; 24.05.2014
comment
@derhass: это указано. Спецификация GLSL 4.4: если выходная переменная без местоположения или индекса, назначенного в тексте шейдера, имеет местоположение, указанное через API OpenGL, будет использоваться местоположение, назначенное API. В противном случае компоновщик присвоит место таким переменным. Все такие присваивания будут иметь нулевой цветовой индекс. Спецификация ES 3.0 GLSLS: если есть только один выход, местоположение не нужно указывать, и в этом случае по умолчанию оно равно нулю. - person Reto Koradi; 24.05.2014
comment
@RetoKoradi: на самом деле это не так. Я сделал ту же самую ошибку ранее: есть разница между цветом number и цветом index. Здесь важна номер цвета. index предназначен только для смешивания нескольких входов. Обратите внимание, что было бы также странно, если бы спецификация требовала, чтобы все выходы (если используется более одного) были привязаны к одному и тому же числу 0... Однако спецификация ES 3.0 - это другое. - person derhass; 24.05.2014
comment
@derhass: Хорошо, да, я понимаю, что ты говоришь. Действительно, явно не указано, что компоновщик будет назначать местоположения, начинающиеся с 0. Есть много программного обеспечения, которое сломается, если драйвер не обработает его таким образом, но теоретически вы правы. Ссылка на ES имеет значение, потому что они очень стараются, чтобы спецификации ES были подмножеством полного OpenGL. Поэтому, если поведение гарантировано в ES, но не в OpenGL, это было бы очень нежелательно. - person Reto Koradi; 24.05.2014