User-92
User-92

Reputation: 374

OpenGL triangle isn't rendering

I was following an OpenGL tutorial when I ran into an issue where I wasn't getting the expected outcome. I was expecting to see a triangle in a window, but instead, I got an empty window. I have made many changes to the code to help it run on my machine, but none fixed the issue. Some of these changes include adding:

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

to request the core profile context, adding a VAO with the VBO, I even downloaded the code from the tutorial, but to no avail. Does anyone know a way to fix my issue?

Code:

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

static unsigned int CompileShader(unsigned int type, const std::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);
        std::cout << "Failed to compile " << (type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " shader!" << std::endl;
        std::cout << message << std::endl;
        glDeleteShader(id);
        return 0;
    }
    
    return id;
}

static unsigned int CreateShader(const std::string& vertexshader, const std::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(void)
{
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;
        
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context  current */
    glfwMakeContextCurrent(window);
    
    if(glewInit() != GLEW_OK){
        std::cout << "REEEEEEEEEEE" << std::endl;
    }
    
    float vertices[6] = {
        -0.5f, -0.5f,
         0.0f,  0.5f,
        -0.5f, -0.5f
    };
    
    unsigned int buf;
    glGenBuffers(1, &buf);
    glBindBuffer(GL_ARRAY_BUFFER, buf);
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), vertices, GL_STATIC_DRAW);
    
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
    
    std::string vertexshader = 
    "#version 330 core\n"
    "\n"
    "in vec4 position;\n"
    "out vec4 color;\n"
    "\n"
    "void main(){\n"
    "   gl_Position = position;\n"
    "   color = position;\n"
    "}\n";
    
    std::string fragmentshader = 
    "#version 330 core\n"
    "\n"
    "in vec4 in_color;\n"
    "out vec4 color;\n"
    "\n"
    "void main(){\n"
    "   color = in_color;\n"
    "}\n";
    
    unsigned int shader = CreateShader(vertexshader, fragmentshader);
    glUseProgram(shader);
    
    glClearColor(0.33f, 0.33f, 0.33f, 1.0f);
    
    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

CMakeLists:

cmake_minimum_required (VERSION 3.5)

if(POLICY CMP0072)
    cmake_policy(SET CMP0072 NEW)
else(NOT POLICY CMP0072)
    message(STATUS "Error")
endif(POLICY CMP0072)

project (opengl-learning)

find_package(PkgConfig REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3)
include_directories(${GLFW_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR})

set (GCC_COVERAGE_LINK_FLAGS "-lglfw3 -pthread -ldl -lGLU -lGL -lrt -lXrandr -lXxf86vm -lXi -lXinerama -lX11 -lGLEW -lGLU -lGL")

add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})

set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++14")
set (source_dir "${PROJECT_SOURCE_DIR}/src/")

file (GLOB source_files "${source_dir}/*.cpp")

add_executable (opengl-learning ${source_files})

find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)

target_link_libraries(opengl-learning ${GLFW_LIBRARIES} ${GLEW_LIBRARIES} ${OPENGL_LIBRARIES})

Versions (requesting core profile)

glGetString(GL_VERSION) >> 3.3 (Core Profile) Mesa 18.3.6
glGetString(GL_SHADING_LANGUAGE_VERSION) >> 3.30

OS: Linux Debian 10

If any extra information is required, feel free to ask.

Upvotes: 2

Views: 322

Answers (1)

Rabbid76
Rabbid76

Reputation: 210878

When you use a core profile OpenGL Context you must create a Vertex Array Object:

GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

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

The default Vertex Array Object (0) is only valid using a compatibility profile OpenGL context:

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

I recommend reading Vertex Specification.

Upvotes: 3

Related Questions