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\$

1 Answer 1

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\$
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .