0
\$\begingroup\$

I have been following this tutorial to try and start learning OpenGL. However, upon compiling my code, my triangle turns out to be black. At first I thought that there was something wrong with the fragment shader, but when I tried hard-coding x-values for the vertex shader, I noticed that it had no effect (notice the 0.7f x-value on the vertex shader).

main.cpp

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



GLfloat verticies[] = {
    -1.0f, -1.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
    1.0f, -1.0f, 0.0f
};

// Objects
GLuint VBO;
GLuint VAO;
GLuint vertShader;
GLuint fragShader;

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
    if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
    glfwSetWindowShouldClose(window, GL_TRUE);
}

std::string readFile(const char* filePath)
{
    std::string content;
    std::ifstream fileStream(filePath);

    if(!fileStream.is_open())
    {
    std::cout << "Failed to open " << filePath << "." << std::endl;     
    return "";
    }

    std::string line = "";
    while(!fileStream.eof())
    {
    std::getline(fileStream, line);
    content.append(line + "\n");
    }

    fileStream.close();
    return content;
}

void createShader(const GLenum shaderType, const char* shaderPath, GLuint& shaderObject)
{
    // Create the shader.
    shaderObject = glCreateShader(shaderType);

    // Read the shader code from the shader file.
    const GLchar* shaderCode = readFile(shaderPath).c_str();

    // DEBUG:
    std::cout << shaderCode << std::endl;

    // Assign the shader code to the shader object.
    glShaderSource(shaderObject, 1, &shaderCode, NULL);

    // Compile the shader.
    glCompileShader(shaderObject);

    // Check to see if it compiled successfully.
    GLint success;
    GLchar infoLog[512];
    glGetShaderiv(shaderObject, GL_COMPILE_STATUS, &success);
    if(!success)
    {
    glGetShaderInfoLog(shaderObject, 512, NULL, infoLog);
    std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n"
          << infoLog
          << std::endl;

    }
}

int main(int argc, char *argv[])
{
    // Initialize GLFW.
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

    // Create OpenGL window. Exit if fails.
    GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);
    if (window == nullptr)
    {
    std::cout << "Failed to create GLFW window" << std::endl;
    glfwTerminate();
    return -1;
    }

    // Make window current
    glfwMakeContextCurrent(window);

    // Initialize GLEW.
    glewExperimental = GL_TRUE;
    if (glewInit() != GLEW_OK)
    {
    std::cout << "Failed to initialize GLEW" << std::endl;
    return -1;
    }

    // Set viewport size and position.
    glViewport(0, 0, 800, 600);

    // Set callback functions.
    glfwSetKeyCallback(window, key_callback);

    // Set clear color state.
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);


    // Create vertex and fragment shaders.
    createShader(GL_VERTEX_SHADER, "../src/shaders/vertex.vert", vertShader);
    createShader(GL_FRAGMENT_SHADER, "../src/shaders/fragment.frag", fragShader);

    // Attach then link shaders
    GLuint shaderProgram;
    glAttachShader(shaderProgram, vertShader);
    glAttachShader(shaderProgram, fragShader);
    glLinkProgram(shaderProgram);

    // Delete the shaders
    glDeleteShader(vertShader);
    glDeleteShader(fragShader);

    // Check if it succeeded.
    GLint linkSucceeded;
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &linkSucceeded);
    if(!linkSucceeded)
    {
    GLchar infoLog[512];
    glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
    std::cout << "ERROR::SHADER::PROGRAM::LINK_FAILED\n"
          << infoLog
          << std::endl;
    }

    // Generate the VAO and bind it.
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    // Create VBO and bind to it.
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);

    // Send verticies to buffer's memory.
    glBufferData(GL_ARRAY_BUFFER, sizeof(verticies), verticies, GL_STATIC_DRAW);

    // Set up vertex attributes
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    // Unbind VBO
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // Unbind VAO
    glBindVertexArray(0);

    // Game loop.
    while(!glfwWindowShouldClose(window))
    {
    // Get input.
    glfwPollEvents();

    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(shaderProgram);
    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glBindVertexArray(0);

    // Swap buffers.
    glfwSwapBuffers(window);
    }

    // De-allocate resources.
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);

    // Terminate and close.
    glfwTerminate();
    return 0;
}

Vertex Shader

#version 330 core

layout(location = 0) in vec3 position;

void main()
{
    gl_Position = vec4(0.7f, position.y, position.z, 1.0f);
}

Fragment Shader

#version 330 core

out vec4 color;

void main()
{
    color = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
\$\endgroup\$
0
\$\begingroup\$

Of course right after I post this I realize what I did wrong:

// Attach then link shaders
GLuint shaderProgram;

should be

// Attach then link shaders
GLuint shaderProgram = glCreateProgram();
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.