Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

My openGL square does not render at all (or renders black if I add an error to the shaders)

I am struggling to figure out why my GLEW/GLFW application won’t render a simple square, so I have dismantelled it into a single file to try to figure out what’s missing.

The code below successfully opens a window, clears to the off green/blue colour I set, but does not render the square. If I add a mistake to the frag shader, it renders the pixels black where the square should be drawn (but suprisingly doesn’t crash the program).

I get no errors returned from the glGetError() calls in render_func().

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I have googled a bit, checked openGL docs and read through the suggested SO posts for clues, and found nothing wrong yet. Here is the code I am running with everything except the shader compilation code (which I lifted straight from another project that works fine) to cut down on the example code I’m sharing.

#ifndef GLEW_STATIC
#define GLEW_STATIC
#endif
#include "GL/glew.h"
#ifndef GLFW_INCLUDE_NONE
#define GLFW_INCLUDE_NONE
#endif
#include "GLFW/glfw3.h"
#ifndef GLM_FORCE_CTOR_INIT
#define GLM_FORCE_CTOR_INIT
#endif
#include "glm/glm.hpp"

#include <array>
#include <memory>


constexpr static std::array<glm::vec3, 4> vertices {{ {-0.5, -0.5, 0.0}, {-0.5, 0.5, 0.0}, {0.5, 0.5, 0.0}, {0.5, -0.5, 0.0} }};
constexpr static std::array<uint32_t , 6> indices {{  0, 1, 2,  2, 3, 0  }};


const std::string vertex_shader_source = R"(
    #version 460 core
    layout (location = 0) in vec3 attrib_pos;

    out vec3 frag_pos;

    void main()
    {
        frag_pos = attrib_pos;
    }
)";

const std::string fragment_shader_source = R"(
    #version 460 core

    in vec3 frag_pos;
    out vec4 o_frag_colour;

    void main()
    {
        o_frag_colour = vec4(1.0, 0.5, 0.0, 1.0);
    }
)";


GLFWwindow* init_window()
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
    GLFWwindow* window = glfwCreateWindow(800, 600, "GLFW Window", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, [](GLFWwindow* window, int width, int height){ glViewport(0, 0, width, height); });

    glfwSetErrorCallback([](int error, const char* description){
        std::cout << "nodget::App::init_glfw() - ERROR - " << std::to_string(error) << ":\n" << description << std::endl;
        throw;
    });

    glewExperimental = GL_TRUE;
    glewInit();
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glFrontFace(GL_CW);
    glEnable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);

    return window;
}

uint32_t init_vertex_array()
{
    using VERTEX_ELEMENT_TYPE = decltype(vertices)::value_type;
    using INDEX_ELEMENT_TYPE = decltype(indices)::value_type;

    uint32_t VAO, VBO, EBO;

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindVertexArray(VAO);

    std::cout << "vertices.size() * sizeof(Vertex) " << vertices.size() * sizeof(VERTEX_ELEMENT_TYPE) << std::endl;
    std::cout << "indices.size() * sizeof(uint32_t) " << indices.size() * sizeof(INDEX_ELEMENT_TYPE) << std::endl;

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(VERTEX_ELEMENT_TYPE), vertices.data(), GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(INDEX_ELEMENT_TYPE), indices.data(), GL_STATIC_DRAW);

    enum {
        VERTEX_POSITION_ATTRIB_INDEX = 0
    };

    glEnableVertexAttribArray(VERTEX_POSITION_ATTRIB_INDEX);
    glVertexAttribPointer(VERTEX_POSITION_ATTRIB_INDEX, 3, GL_FLOAT, false, sizeof(glm::vec3), (void*)0);

    glBindVertexArray(0);

    return VAO;
}

void render_func(GLFWwindow* window, uint32_t vao_id, uint32_t shader_id)
{
    auto error = glGetError();
    if (error != GL_NO_ERROR) {
        std::cout << "Pre Loop Error: " << error << std::endl;
    }

    while(true) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(shader_id);

        glBindVertexArray(vao_id);
        glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, nullptr);
        glBindVertexArray(0);

        glfwSwapBuffers(window);
        glfwPollEvents();

        error = glGetError();
        if (error != GL_NO_ERROR) {
            std::cout << "Mid Loop Error: " << error << std::endl;
        }
    }
}

int main()
{
    auto window = init_window();
    auto vao_id = init_vertex_array();

    const std::shared_ptr<nodget::Shader> shader = std::make_shared<nodget::Shader>(std::move(vertex_shader_source), std::move(fragment_shader_source));
    shader->init_func();

    render_func(window, vao_id, shader->id);
}

>Solution :

You must write the clip space coordinate to gl_Position. gl_Position is used for primitive assembly:

#version 460 core
layout (location = 0) in vec3 attrib_pos;

out vec3 frag_pos;

void main()
{
    frag_pos = attrib_pos;
    gl_Position = vec4(attrib_pos, 1.0);
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading