[Q] Drawing a quad using modern OpenGL?

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

[Q] Drawing a quad using modern OpenGL?

Postby 0x0000000 on Wed Jul 16, 2014 7:29 am

Hello all.

Over the past couple of weeks I have been attempting to learn modern OpenGL. I have gotten to the point where I am going to begin drawing primitives to the screen. I would like to know how to draw a quad.

Back with legacy OpenGL all you had to do would be glBegin(GL_QUADS) ... glEnd() but now I have to supply my own vertices to the shader. I read about OpenGL VBOs and since they can be created from a static array of vertices would it be better for me to do this:
Code: Select all
const GLfloat _quadBase[] = {
    0, 0, 1,
    1, 0, 1,
    0, 1, 1,
    1, 0, 1,
    1, 1, 1,
    0, 1, 1
}
// Generate VBO here.
void drawQuad(KHVec2 pos, KHVec2 size) {
    scale(size.x, size.y); // Scale the _quadBase
    translate(pos.x, pos.y);
    // Submit _quadBase vertices to shader
}

Or should I just generate a new VBO with the vertices altered?

Any help is appreciated!
User avatar
0x0000000
Chaos Rift Newbie
Chaos Rift Newbie
 
Posts: 42
Joined: Tue Feb 12, 2013 1:46 am
Location: Memory Address 0x0000000 (in UTF-9 notation)

Re: [Q] Drawing a quad using modern OpenGL?

Postby Falco Girgis on Wed Jul 16, 2014 11:49 am

0x0000000 wrote:Hello all.

Over the past couple of weeks I have been attempting to learn modern OpenGL. I have gotten to the point where I am going to begin drawing primitives to the screen. I would like to know how to draw a quad.

Back with legacy OpenGL all you had to do would be glBegin(GL_QUADS) ... glEnd() but now I have to supply my own vertices to the shader. I read about OpenGL VBOs and since they can be created from a static array of vertices would it be better for me to do this:
Code: Select all
const GLfloat _quadBase[] = {
    0, 0, 1,
    1, 0, 1,
    0, 1, 1,
    1, 0, 1,
    1, 1, 1,
    0, 1, 1
}
// Generate VBO here.
void drawQuad(KHVec2 pos, KHVec2 size) {
    scale(size.x, size.y); // Scale the _quadBase
    translate(pos.x, pos.y);
    // Submit _quadBase vertices to shader
}

Or should I just generate a new VBO with the vertices altered?

Any help is appreciated!
It depends on the geometry. If its transform is static, you can save calculation time by pretransforming the vertices before uploading the VBO. If not, or if you want to use the same quad VBO for all quads, then you submit your modelview and/or projection matrices as uniforms to your vertex shader and do the transformations there.

WARNING: I've done plenty of experimenting and benchmarking on the subject, and if your geometry is just a series of quads (ie a 2D game), you are going to be wasting a shitload of time uploading an entire matrix uniform to your vertex shader to transform every single onscreen sprite into world space. It's actually faster to take your quad into world space on the CPU, then just keep the view and projection matrices on the GPU. It's even faster yet if you transform into world space on the CPU with SIMD/vector instructions (SEE on x86 or NEON on ARM) before submitting geometry to your vertex shader.
"So what happens if the Elysian Shadows Kickstarter fails?"
Image
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
 
Posts: 10693
Joined: Thu May 20, 2004 3:04 pm
Location: Studio Vorbis, AL

Re: [Q] Drawing a quad using modern OpenGL?

Postby 0x0000000 on Wed Jul 16, 2014 10:30 pm

Thanks for the reply!

So what you are saying is instead of calling glUniform4fv or something of the sort I would calculate the modelview matrix and transform the quads position on the CPU, then directly submit the transformed vertices to the vertex shader? And yes, my game is tile-based so I will be drawing many quads to the screen each frame.

Currently the graphics framework I have coded uses a modelview matrix and a projection matrix, however I could split the modelview into model and view if that's what you mean. I will reiterate by posting some pseudo-code:
Code: Select all
drawQuad(Vec2 pos, Vec2 size) {
    GLfloat vertices = {pos.x, pos.y, 1,
                        pos.x + size.x, pos.y, 1,
                        pos.x, pos.y + size.y, 1,
                        pos.x, pos.y + size.y, 1,
                        pos.x + size.x, pos.y + size. y, 1
                        pos.x + size.x, pos.y, 1};

    // Generate VBO, submit vertices to vertex shader.
}

// In vertex shader
in vec3 worldSpace;

uniform mat4 projection;
uniform mat4 view;

main() {
    gl_Position = worldSpace * view * projection; // Is this order correct?
}


EDIT:

You mentioned that if my transforms were static I could pre-calculate the vertices. Do you mean something like generating a gigantic VBO with all the tile vertices for the map, and just drawing the single VBO? Sorry if my understanding is completely off, I'm pretty new to this.
User avatar
0x0000000
Chaos Rift Newbie
Chaos Rift Newbie
 
Posts: 42
Joined: Tue Feb 12, 2013 1:46 am
Location: Memory Address 0x0000000 (in UTF-9 notation)


Return to Programming Discussion

Who is online

Users browsing this forum: Yahoo [Bot] and 2 guests

cron