rial
rial

Reputation: 1015

Black screen output in opengl 3.3

I am trying to draw a red triangle to the screen in OpenGL. glClearColor(x, x, x, 1) works fine and changes the background color. However no triangle appears and no errors show up.

#include <GL\glew.h>
#include <GL\GL.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>

using namespace std;

const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

static unsigned int CompileShader(unsigned int type, const string &source) {
    unsigned int id = glCreateShader(type);
    const char* src = source.c_str();
    glShaderSource(id, 1, &src, nullptr);
    glCompileShader(id);

    int result;
    glGetShaderiv(id, GL_COMPILE_STATUS, &result);
    if (result == GL_FALSE) {
        int length;
        glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
        char *message = (char*)alloca(length * sizeof(char));
        glGetShaderInfoLog(id, length, &length, message);
        cout << "Failed to compile " << (type == GL_VERTEX_SHADER ? "vertex shader " : "fragment shader ") << endl;
        cout << message << endl;
    }

    return id;
}

static unsigned int CreateShader(const string &vertexShader, const string &fragmentShader) {
    unsigned int program = glCreateProgram();
    unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
    unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);

    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program);
    glValidateProgram(program);

    glDeleteShader(vs);
    glDeleteShader(fs);

    return program;
}

int main() {
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow *window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "window", NULL, NULL);

    if (window == NULL) {
        cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }

    cout << glfwGetVersionString() << endl;

    glfwMakeContextCurrent(window);

    glewInit();
    if (glewInit()) {
        cout << "Glew initialization failed! " << endl;
        return -1;
    }


    float positions[6] = {
        -0.5f, -0.5f,
        0.0f, 0.5f,
        0.5f, -0.5f
    };

    unsigned int buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
    glEnableVertexAttribArray(0);

    const string vertexShader =
        "#version 330 core\n"
        "\n"
        "layout (location = 0) in vec4 position;\n"
        "\n"
        "void main() {\n"
        "   gl_Position = position;\n"
        "}\n";

    const string fragmentShader =
        "#version 330 core\n"
        "\n"
        "layout (location = 0) out vec4 color;\n"
        "\n"
        "void main() \n"
        "{\n"
        "\n"
        "   color = vec4(1.0, 0.0, 0.0, 1.0);\n"
        "}\n";

    unsigned int shader = CreateShader(vertexShader, fragmentShader);
    glUseProgram(shader);

    while (!glfwWindowShouldClose(window)) {

        glClear(GL_COLOR_BUFFER_BIT);
        glClearColor(0.0f, 0.0f, 0.0f, 1);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glfwSwapBuffers(window);
        glfwPollEvents();

    }

    glfwTerminate();
    return 0;
}

Upvotes: 1

Views: 708

Answers (2)

Amadeus
Amadeus

Reputation: 10655

You need to use a Vertex Array Object. So, change your program to:

(...)
unsigned int vao;                                                           
glGenVertexArrays(1, &vao);                                                 
glBindVertexArray(vao);                                                     

unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);

glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
glEnableVertexAttribArray(0);

glBindVertexArray(0);
(...)

And, then when rendering:

(...)
glBindVertexArray(vao);                                                     
    while (!glfwWindowShouldClose(window)) {               
(...)

Upvotes: 4

Quimby
Quimby

Reputation: 19123

You are missing an Vertex array object which holds those VertexAttrib settings. Also your vertex buffer format is set to vec2 points but the vertex shader expects vec4.

Correct shader:

const string vertexShader =
        "#version 330 core\n"
        "\n"
        "layout (location = 0) in vec2 position;\n"
        "\n"
        "void main() {\n"
        "   gl_Position = vec4(position,0.0f,1.0f);\n"
        "}\n";

Creating and binding the VAO:

unsigned int buffer;
unsigned int VAO;

glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &buffer);

You initialized glew twice, not sure if that matters.

glewExperimental = GL_TRUE;//Recommended for compatibility
    if (glewInit()!= GLEW_OK) {
        cout << "Glew initialization failed! " << endl;
        return -1;
    }

Upvotes: 2

Related Questions