PDA

View Full Version : Drawing 2 triangles generates weird bugs



gedamial
03-15-2016, 02:33 PM
Hello guys.

I'm drawing 2 triangles on the screen, but they have a weird effect: they always blink



#include <SDL.h>
#include <glew.h>
#include <conio.h>
#include <iostream>

void BindInput(bool &quit_flag)
{
SDL_Event _event;

SDL_PollEvent(&_event);

if (_event.type == SDL_QUIT)
{
quit_flag = true;
}

if(_event.type == SDL_MOUSEMOTION)
{
}
}

void DrawTriangle(SDL_Window* Win, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3)
{
glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

GLfloat vertices[]
{
x1, y1,
1.0f, 0.0f, 0.0f,
x2, y2,
0.0f, 1.0f, 0.0f,
x3, y3,
0.0f, 0.0f, 1.0f,
};

// Create a Vertex Buffer Object (VBO)
GLuint vbo;

// Generate a buffer on our VBO
glGenBuffers(1, &vbo);

// Now bind the buffer on our VBO
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

/* SETTING THE POSITION ATTRIBUTE */
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, 0);

/* SETTING THE COLOR ATTRIBUTE */
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (const void*)(sizeof(GLfloat) * 2));


/* DRAWING THE TRIANGLE */
glDrawArrays(GL_TRIANGLES, 0, 3);

// After drawing, disable all the VertexAttribArrays
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

// Unbind buffer
glBindBuffer(GL_ARRAY_BUFFER, 0);

SDL_GL_SwapWindow(Win);
}

int main(int argc, char** argv)
{
bool quit = false;

SDL_Init(SDL_INIT_EVERYTHING);

SDL_Window* window = SDL_CreateWindow("GraphicsTest", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1024, 768, SDL_WINDOW_OPENGL);

// ... glew initialization ...

SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

while (!quit)
{
BindInput(quit);

DrawTriangle(window, -1.0f, -1.0f, +1.0f, -1.0f, +0.0f, +1.0f);
DrawTriangle(window, +0.5f, +0.5f, +0.5f, +1.0f, +1.0f, +1.0f);
}

SDL_DestroyWindow(window);
SDL_Quit();

return 0;
}


Can you tell me why that happens?

I just want to draw those 2 triangles on the screen and I want them to be static

Spoops
03-15-2016, 03:58 PM
glClear and SwapWindow shouldn't be in DrawTriangle. Those two functions determine the beginning and end of a frame; that means your code displays a frame with one triangle and another frame with the other one.

mhagain
03-15-2016, 11:28 PM
You've also got a memory leak - you're creating a new VBO each time you draw a triangle. Don't do that, create it once during startup and reuse it instead.

gedamial
03-16-2016, 02:36 AM
glClear and SwapWindow shouldn't be in DrawTriangle. Those two functions determine the beginning and end of a frame; that means your code displays a frame with one triangle and another frame with the other one.

I got it work removing those two functions from the DrawTriangle() function and putting them into the main as follows:



int main(int argc, char** argv)
{
// initializations ...

glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

DrawTriangle(window, -1.0f, -1.0f, +1.0f, -1.0f, +0.0f, +1.0f);
DrawTriangle(window, +0.5f, +0.5f, +0.5f, +1.0f, +1.0f, +1.0f);

SDL_GL_SwapWindow(window);

while (!quit)
{
BindInput(quit);
}

std::cout << "Press any key to quit...";
getch();

SDL_DestroyWindow(window);
SDL_Quit();

return 0;
}


This draws the two triangles.

Also, if I add a third triangle



DrawTriangle(window, -1.0f, +1.0f, +0.0f, +1.0f, -1.0f, -1.0f);
SDL_GL_SwapWindow(window);


right after the SwapWindow(), I only see the third triangle get printed out.

I want to understand how this really works.


I thought that glClear() is the beginning of a new frame and SwapWindow() the end of it.

But If I look at my ChangeWindowBackground() function:




void ChangeBgColor(SDL_Window* Win, GLint r, GLint g, GLint b, GLfloat a = 1)
{
glClearColor(r / 255.0f, g / 255.0f, b / 255.0f, a);

glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

SDL_GL_SwapWindow(Win);
}


Well, in this case I'm changing the background color and THEN I begin a new frame with glClear() and terminate it with SwapWindow()

I'd like to understand how this is happening. What's the logic of this.

Spoops
03-16-2016, 03:03 AM
glClear clears everything you have drawn, while SwapWindow renders it to screen. A standard game loop looks like this:


resource initialization (vbo creation, filling...)

while (!quit)
{
input management
clear
draw
swap window
}

resource destruction

gedamial
03-16-2016, 03:06 AM
glClear clears everything you have drawn, while SwapWindow renders it to screen. A standard game loop looks like this:


resource initialization (vbo creation, filling...)

while (!quit)
{
input management
clear
draw
swap window
}

resource destruction


Thanks for that man!

What about the question about changing the background color?

This code:



void ChangeBgColor(SDL_Window* Win, GLint r, GLint g, GLint b, GLfloat a = 1)
{
glClearColor(r / 255.0f, g / 255.0f, b / 255.0f, a);

glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

SDL_GL_SwapWindow(Win);
}


Changes my background color.

But I'm calling the glClearColor() BEFORE the glClearDepth(), glClear() and SwapWindow()

How does this work?

Spoops
03-16-2016, 03:20 AM
Just call glClearColor, each glClear call will use the color of the latest glClearColor call.

gedamial
03-16-2016, 03:26 AM
Just call glClearColor, each glClear call will use the color of the latest glClearColor call.

The strange thing is that even though I set the alpha color to 0 (no alpha), the color is shown like if the alpha were 1

mhagain
03-16-2016, 07:35 AM
The strange thing is that even though I set the alpha color to 0 (no alpha), the color is shown like if the alpha were 1


This is normal and expected behaviour if your framebuffer has 0 alpha bits.

gedamial
03-16-2016, 03:30 PM
This is normal and expected behaviour if your framebuffer has 0 alpha bits.

What do u mean by that?

How do I change that?

Spoops
03-17-2016, 08:27 AM
It's up to your window manager. With SDL use SDL_GL_SetAttribute with SDL_GL_ALPHA_SIZE.