0

So, I am trying to make a basic "Drawable" class that handles a lot of the drawing for me in the background and I want to use modern OpenGL (no begin and end statements). I keep just getting a blank screen when I run draw().

I have run the debugger and checked, my array is initialized properly with 3xFLOAT for position and 4xFLOAT for color. Any idea what is going wrong? I am very new to this library. My example tries to draw a red cube at (+-0.5, +-0.5, 0.0), so the indexData array is just { 0, 1, 2, 3 }.

#define DRAWABLE_VERTEX_DEPTH 3
#define SIZE_OF_VERTEX_ELEMENT sizeof(GLfloat)
#define VERTEX_SIZE (DRAWABLE_VERTEX_DEPTH * SIZE_OF_VERTEX_ELEMENT)
#define DRAWABLE_COLOR_DEPTH 4
#define SIZE_OF_COLOR_ELEMENT sizeof(GLfloat)
#define COLOR_SIZE (DRAWABLE_COLOR_DEPTH * SIZE_OF_COLOR_ELEMENT)
#define INDEX_SIZE sizeof(GLushort)
#define DRAWABLE_STRIDE (VERTEX_SIZE + COLOR_SIZE)

inline Drawable(/*Arguments omitted for brevity...*/)
    {
        //Standard initialization omitted....

        glGenBuffers(1, &vboID);
        glGenBuffers(1, &vioID);
        glGenVertexArrays(1, &vaoID);

        glBindBuffer(GL_ARRAY_BUFFER, vboID);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vioID);

        glBufferData(GL_ARRAY_BUFFER, (VERTEX_SIZE + COLOR_SIZE) * vertexCount, vertexData, drawType);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, INDEX_SIZE * indexCount, indexData, drawType);

        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

        //Generate Vertex Array

        glBindVertexArray(vaoID);
        glBindBuffer(GL_ARRAY_BUFFER, vboID);
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(0, DRAWABLE_VERTEX_DEPTH, GL_FLOAT, GL_FALSE, DRAWABLE_STRIDE, 0);
        glVertexAttribPointer(1, DRAWABLE_COLOR_DEPTH, GL_FLOAT, GL_FALSE, DRAWABLE_STRIDE, (GLbyte*)VERTEX_SIZE);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vioID);
        glBindVertexArray(0);
    }

    inline void draw()
    {
        glBindVertexArray(vaoID);
        glDrawElements(drawMode, indexCount, GL_UNSIGNED_SHORT, NULL);
        glBindVertexArray(0);
    }

GLSL Vertex Shader:

#version 430\r\n

in layout(location=0) vec3 inPosition;
in layout(location=1) vec4 inColor;
out vec4 outVertexColor;

void main()
{
    gl_Position = vec4(inPosition, 1.0);
    outVertexColor = inColor;
}

GLSL Fragment Shader:

#version 430\r\n

in vec4 outVertexColor;
out vec4 outFragmentcolor;

void main()
{
    outFragmentcolor = outVertexColor;
}
guitar80
  • 716
  • 6
  • 19
  • You have to call `glEnableClientState(GL_VERTEX_ARRAY);` before calling `glBindVertexArray(vaoID);` and `glDisableClientState(GL_VERTEX_ARRAY);` after `glBindVertexArray(0);`. – ProXicT Oct 08 '15 at 00:31
  • Thx for the response! I just added that, but it seemed to have no effect. What exactly does that do? And do I need it in both places where I bind the Vertex Array? – guitar80 Oct 08 '15 at 00:33
  • 2
    I just took a quick look in your code and found this missing. It basicly enables/disables the capability specified in the parameter. Try to put `glEnableVertexAttribArray(0); glEnableVertexAttribArray(1);` there instead. And don't forget to disable it again. – ProXicT Oct 08 '15 at 00:38
  • Still no luck... Just a blank screen. I wondered if it maybe had something to do with the fact that I have interleaved color and vertex information in my VBO. – guitar80 Oct 08 '15 at 00:40
  • I think, you should also bind your VBO: `glBindVertexArray(vaoID); glBindBuffer(GL_ARRAY_BUFFER, vboID);`. Try it. If it doesn't help, I give up. I haven't seen OpenGL in a while and I'm too tired right now and getting up in 4 hours. Good luck! – ProXicT Oct 08 '15 at 00:50
  • Thanks for the effort. I'll up vote if it solves and you can add it as an answer. – guitar80 Oct 08 '15 at 00:51
  • 2
    Are you using shaders? Your code is using generic vertex attributes, which can only be used with shaders. Also, there's a mismatch in the index types. You're using `GLushort` to calculate the size, but `GL_UNSIGNED_INT` as the argument to `glDrawElements()`. – Reto Koradi Oct 08 '15 at 03:12
  • Yeah but the shaders are copied from another guys tutorial and I think they are right. I can upload them? – guitar80 Oct 08 '15 at 03:13

1 Answers1

2

Apart from the issues mentioned in the comments, your index array is GLushort (unsigned 16 bit), while your draw call specifies GL_UNSIGNED_INT (unsigned 32 bit). Replace with GL_UNSIGNED_SHORT.

Kornel Kisielewicz
  • 55,802
  • 15
  • 111
  • 149
  • Apart from the issues mentioned in the comments? This exact problem was already mentioned in the comments. – Reto Koradi Oct 08 '15 at 14:54
  • Yeah, I changed that but it doesn't work. That was a later change I tried to use to fix things.. I think it is an issue with my Vertex Arrays or enables.. Any idea? Do VArrays just repeat all stored enables/binds when they are bound? – guitar80 Oct 08 '15 at 14:56
  • Ugh.. so my shader code was missing a semi-colon as well as this issue. Thanks a ton! *Feeling stupid* – guitar80 Oct 08 '15 at 16:06
  • 1
    @guitar80: Make your [shader loader](http://pastebin.com/tQ3SB36E) scream bloody murder when things don't compile/link, helps prevent that class of head-scratchers :) – genpfault Oct 08 '15 at 17:32
  • @RetoKoradi sorry, didn't notice your comment, probably due to it not being expanded – Kornel Kisielewicz Oct 09 '15 at 14:46