0

I've tried to use this code for drawing triangle using VBO and shaders.

#include "gl.h"
#include <stdlib.h>
#include <GLFW/glfw3.h>

// utility libraries
#include "OGLShader.h"
#include "OGLProgram.h"
#include "OGLCommon.h"
#include "Shaders.h"
#include "OGLBuffer.h"

using namespace OpenGL;

GLFWwindow *window;
const int window_width = 800;
const int window_height = 600;

Shader **shaders;
Program *mainProgram;

int verticesCount = 3;
float triangle[] = {
    0.0f, 0.5f, 0.0f,
    0.5f, -0.5f, 0.0f,
    -0.5f, -0.5f, 0.0f,
};
int indicesCount = 3;
int indices[] = {
    0, 1, 2
};
Buffer *verticesBuffer;

void init() {
    glViewport(0, 0, window_width, window_height);
    glClearColor(0, 0, 0, 1);

    shaders = new OpenGL::Shader*[2];
     // this code creates and compiles shaders, links shader program
    shaders[0] = new OpenGL::Shader(GL_VERTEX_SHADER, OpenGL::vertexShaderSource);
    shaders[1] = new OpenGL::Shader(GL_FRAGMENT_SHADER, OpenGL::fragmentShaderSource);
    mainProgram = new OpenGL::Program(2, shaders);
    mainProgram->use(); // use program

    vertices_attrib_location = 0;
    colors_attrib_location = 1;
    glBindAttribLocation(mainProgram->getId(), vertices_attrib_location, "iVertex");
    glBindAttribLocation(mainProgram->getId(), colors_attrib_location, "iColor");

    verticesBuffer = new Buffer(GL_ARRAY_BUFFER);
    verticesBuffer->data(verticesCount*3*sizeof(float), triangle, GL_STATIC_DRAW);
}

void deinit() {
    delete verticesBuffer;

    delete shaders[0];
    delete shaders[1];
    delete []shaders;
    delete mainProgram;
}

void display() {
    glClear(GL_COLOR_BUFFER_BIT);

    glVertexAttrib3f(colors_attrib_location, 1, 0, 1);
    verticesBuffer->bind();
    glEnableVertexAttribArray(vertices_attrib_location);
    glVertexAttribPointer(vertices_attrib_location, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

    glDrawArrays(GL_TRIANGLES, 0, 3);
}

void update(double deltaTime) {

}

int main(int argc, char **argv) {
    if (!glfwInit()) {
        exit(1);
    }
    glfwWindowHint(GLFW_SAMPLES, 1);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
    window = glfwCreateWindow(window_width, window_height, "Test", nullptr, nullptr);
    if (!window) {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);
    init();

    double lastTime = 0.0;
    while (!glfwWindowShouldClose(window)) {
        display();
        double curTime = glfwGetTime();
        update(curTime - lastTime);
        lastTime = curTime;

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    deinit();
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

Here is my shaders:

namespace OpenGL {

std::string vertexShaderSource =
    "#version 120\n\
    attribute vec3 iVertex;\
    attribute vec3 iColor;\
    varying vec3 oColor;\
    void main(void)\n\
    {\n\
        oColor = iColor;\n\
        \n\
        gl_Position = vec4(iVertex, 1);\n\
    }\n\
    ";

    std::string fragmentShaderSource =
    "#version 120\n\
    varying vec3 oColor;\
    varying vec2 oTexCoord;\n\
    void main(void)\n\
    {\n\
        gl_FragColor = vec4(oColor, 1);\n\
    }\n\
    ";

}

I tried to run this code both on Intel and ATI videocards, but everything that I see on the screen is empty black window. What I'm doing wrong?

  • 1
    Try to see if you have some errors using glGetError to begin with. – Matic Oblak Jun 19 '15 at 12:40
  • One problem is that you're calling `glBindAttribLocation()` too late. See for example the first part of my answer here: http://stackoverflow.com/questions/25771993/vertex-locations-are-off-when-using-mesa-core-profile/25780255#25780255. – Reto Koradi Jun 19 '15 at 13:31
  • @MaticOblak no, I catch no errors using glGetError and OpenGL Profilers. – Dzhidzhoev Vladislav Jun 19 '15 at 13:34
  • Ok, great. Next try to use a different clear color which if the screen color changes will confirm the issue is actually in the drawing itself. – Matic Oblak Jun 19 '15 at 13:42
  • Also try changing the fragment shader to use gl_FragColor = vec4(1, 1, 1, 1); as how you use the color seems suspicious. This should draw a white triangle if that is the case. – Matic Oblak Jun 19 '15 at 13:44
  • The glVertexAttrib3f is used with glBegin, glEnd is it not? You should be using glVertexAttribPointer and set a pointer to a color array for each vertex you draw. Alternatively if you want a single color for a shape you should use an uniform. – Matic Oblak Jun 19 '15 at 13:47
  • @MaticOblak no. glVertexAttrib3f is also used when we wan't to specify single attribute value for any vertex that we draw. It is called "static vertex attribute". – Dzhidzhoev Vladislav Jun 19 '15 at 14:05
  • @MaticOblak I've already tried to change clear color and to put gl_FragColor = vec4(1, 1, 1, 1); in my fragment shader – Dzhidzhoev Vladislav Jun 19 '15 at 14:07
  • So did the clear produce the white background? – Matic Oblak Jun 19 '15 at 14:08
  • @MaticOblak glClear changes background, but I already don't see triangle in front of them. gl_FragColor = vec4(1, 1, 1, 1); doesn't change anything – Dzhidzhoev Vladislav Jun 19 '15 at 14:32
  • @RetoKoradi thanks, your advice helped me. – Dzhidzhoev Vladislav Jun 19 '15 at 16:22

0 Answers0