Tutorial OpenGL v2.0

Finalmente chegou! Após quase 1 ano depois de meu primeiro artigo sobre OpenGL, chegou a versão 2.0. Clique e fique mais Geek.

[ Hits: 20.386 ]

Por: Thiago Henrique Hüpner em 08/05/2015


A jornada é longa parte 1 - Colisão Mouse e Retângulo



Agora que já estamos "cheios" de apenas criar retângulos, introduzirei um novo conceito a vocês: Colisão.

Esse é o maior 'medo' dos iniciantes e é o que deixa as coisas mais interessantes, mas para melhorar, saiba que não é tão complexo assim (bom , essa parte).

Essa colisão de Mouse e Retângulo também é conhecida como Colisão de um Ponto e um Retângulo. Exemplo:

#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <time.h>

#define LARGURA 400
#define ALTURA 400

int colisao(int x,int y,SDL_Rect a){
	// É verificado primeiro no eixo X
	if(x >= a.x && x <= a.x + a.w){
		// Depois no eixo Y
		if(y >= a.y && y <= a.y + a.h){
			// Se aconteceu a colisão irá retornar 1
			return 1;
		}
	}

	// Se passou pelos if's e não retornou significa que nao houve colisao
	return 0;
}

void inicializaOpenGL(){
	glClearColor(255,255,255,1);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0,LARGURA,ALTURA,0);
	glMatrixMode(GL_MODELVIEW);
	glClear(GL_COLOR_BUFFER_BIT);
}
// Simulando o SDL_FillRect
void GL_FillRect(SDL_Rect a,int r,int g,int b){
glClear(GL_COLOR_BUFFER_BIT);
	glLoadIdentity();

	glColor3ub(r,g,b);
	glBegin(GL_QUADS);
		// Lado Superior Esquerdo
		glVertex2f(a.x,a.y);
		// Lado Superior Direito
		glVertex2f(a.x+a.w,a.y);
		// Lado Inferior Direito
		glVertex2f(a.x+a.w,a.y+a.h);
		// Lado Inferior Esquerdo
		glVertex2f(a.x,a.y+a.h);
	glEnd();
}
int main(int argc,char *argv[]){
	if(SDL_Init(SDL_INIT_VIDEO) < 0){
		printf("Erro : %s
",SDL_GetError());
		return -1;
	}

	// Para sempre ter valores pseudo-aleatorios
	srand((unsigned)time(NULL));

	SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
	SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
	SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
	SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );
	SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 2 );

	SDL_Surface * tela = SDL_SetVideoMode(LARGURA,ALTURA,32,SDL_OPENGL);

	if(tela == NULL){
		printf("Erro : %s
",SDL_GetError());
		SDL_Quit();
		return -1;
	}

	SDL_WM_SetCaption("Colisão nem é tão complexo assim",NULL);

	SDL_Event evento;

	int estaRodando = 1;

	SDL_Rect retangulo;

inicializaOpenGL();

	int r = 255;
	int g = 0;
	int b = 0;

	int posX = 10;
	int posY = 10;

	while(estaRodando){
		while(SDL_PollEvent(&evento)){
			switch(evento.type){
				case SDL_QUIT:
					estaRodando = 0;
				break;

				case SDL_MOUSEBUTTONDOWN:
					if(evento.button.button == SDL_BUTTON_LEFT){
						// Se apertar no botão esquerdo e o mouse estiver em cima do retangulo ...
						if(colisao(evento.button.x,evento.button.y,retangulo)){
							// Muda a cor R,G e B e consequentemente a cor do retangulo muda
							// NOTA : Tem que ser 256 e não 256 , pois a chance de ser 255 é muito pequena e usando o 256 , a chance aumenta
							// de ser 255
							r = rand() % 256;
							g = rand() % 256;
							b = rand() % 256;
						}
					}else if(evento.button.button == SDL_BUTTON_RIGHT){
						// Se apertar com o botão direito , o retangulo assume a posição do mouse
						posX = evento.button.x;
						posY = evento.button.y;

					}

				break;

				default:
				break;

			}
		}

		// Propriedades do Retangulo

		// Posição X
		retangulo.x = posX;

		// Posição Y
		retangulo.y = posY;

		// Aqui a coisa começa a ficar interessante ...

		// Largura do Retangulo
		retangulo.w = 50;

		// Altura do Retangulo
		retangulo.h = 50;

		GL_FillRect(retangulo,r,g,b);

		SDL_Delay(30);

		SDL_GL_SwapBuffers();
	}
	SDL_Quit();

	return 0;

}

Compile e execute esse código:

gcc -o ColisoesAtacar ColisoesAtacar.c -lSDL -lGL -lGLU

E após clicar no retângulo com os dois botões, ficou assim para mim (poderá ser diferente):
Linux: Tutorial OpenGL v2.0
Se observaram bem, o diferente é a função de colisão e como ela é chamada (dentro de um "if").

Agora vamos entender como o "if" trabalha:

Se a posição X do mouse for maior ou igual ao lado superior esquerdo do retângulo e for menor ou igual ao lado superior direito (a.x + a.w), colidiu. Agora, só nos resta detectar a colisão do eixo Y , que segue a mesma logica (até aqui).
Agora um desafio: elabore um programa que tenha 3 (ou mais) retângulos e que se o usuário clicar no retângulo certo, ele muda de cor. Senão, o programa continuará sendo executado até que acerte.

Não é tão complexo assim, só é necessário pensar um pouco mais, mas nada difícil. Como existem várias formas de elaborar um mesmo programa, poderá ser diferente do meu, mas será a mesma lógica.

Eu elaborei esse programa a lá Thiago:

#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <time.h>

#define LARGURA 400
#define ALTURA 400

int colisao(int x,int y,SDL_Rect a) {
// É verificado primeiro no eixo X
    if(x >= a.x && x <= a.x + a.w) {
// Depois no eixo Y
        if(y >= a.y && y <= a.y + a.h) {
// Se aconteceu a colisão irá retornar 1
            return 1;
        }
    }

// Se passou pelos if's e não retornou significa que nao houve colisao
    return 0;
}

void inicializaOpenGL() {
    glClearColor(255,255,255,1);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0,LARGURA,ALTURA,0);
    glMatrixMode(GL_MODELVIEW);
    glClear(GL_COLOR_BUFFER_BIT);
}

void definicoesRetangulo(int posX ,int posY,SDL_Rect * a) {

    glClear(GL_COLOR_BUFFER_BIT);

// Propriedades do Retangulo

// Posição X
    a->x = posX;

// Posição Y
    a->y = posY;

// Aqui a coisa começa a ficar interessante ...

// Largura do Retangulo
    a->w = 50;

// Altura do Retangulo
    a->h = 50;
}

// Simulando o SDL_FillRect
void GL_FillRect(SDL_Rect a,int r,int g,int b) {
    glLoadIdentity();

    glColor3ub(r,g,b);
    glBegin(GL_QUADS);
// Lado Superior Esquerdo
    glVertex2f(a.x,a.y);
// Lado Superior Direito
    glVertex2f(a.x+a.w,a.y);
// Lado Inferior Direito
    glVertex2f(a.x+a.w,a.y+a.h);
// Lado Inferior Esquerdo
    glVertex2f(a.x,a.y+a.h);
    glEnd();
}
int main(int argc,char *argv[]) {
    if(SDL_Init(SDL_INIT_VIDEO) < 0) {
// ... imprima a mensagem de erro e ...
        printf("Erro : %s
",SDL_GetError());
        return -1;
    }

// Para sempre ter valores pseudo-aleatorios
    srand((unsigned)time(NULL));

    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 2 );

    SDL_Surface * tela = SDL_SetVideoMode(LARGURA,ALTURA,32,SDL_OPENGL);

    if(tela == NULL) {
        printf("Erro : %s
",SDL_GetError());
        SDL_Quit();
        return -1;
    }

    SDL_WM_SetCaption("Colisão nem é tão complexo assim",NULL);

    SDL_Event evento;

    int estaRodando = 1;

    SDL_Rect r1,r2,r3;

    inicializaOpenGL();

    int r = 255;
    int g = 0;
    int b = 0;

    while(estaRodando) {
        while(SDL_PollEvent(&evento)) {
            switch(evento.type) {
            case SDL_QUIT:
                estaRodando = 0;
                break;

            case SDL_MOUSEBUTTONDOWN:
                if(evento.button.button == SDL_BUTTON_LEFT) {
// Se apertar no botão esquerdo e o mouse estiver em cima do retangulo (2) ...
                    if(colisao(evento.button.x,evento.button.y,r2)) {
// Muda a cor R,G e B e consequentemente a cor do retangulo muda
// NOTA : Tem que ser 256 e não 256 , pois a chance de ser 255 é muito pequena e usando o 256 , a chance aumenta
// de ser 255
                        r = rand() % 256;
                        g = rand() % 256;
                        b = rand() % 256;
                    }
                }

                break;

            default:
                break;

            }
        }

        definicoesRetangulo(50,50,&r1);

        definicoesRetangulo(150,50,&r2);

        definicoesRetangulo(250,50,&r3);

        GL_FillRect(r2,r,g,b);

        GL_FillRect(r1,255,0,255);

        GL_FillRect(r3,0,255,0);

        SDL_Delay(30);

        SDL_GL_SwapBuffers();
    }
    SDL_Quit();

    return 0;

}

Salve e compile como quiser, é um desafio. Agora quem decide é você. =D

Como ficou o meu, após clicar no retângulo correto:
Linux: Tutorial OpenGL v2.0
Agora é possível criar "menus" para seus programas, mas é necessário uma máquina de estados, porém, levaria 1 artigo inteiro apenas para explicar essa parte (deixemos essa parte para outra hora).

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Inicializando o SDL
   3. OpenGL e SDL botando pra quebrar
   4. Simulando uma Gambiarra
   5. A jornada é longa parte 1 - Colisão Mouse e Retângulo
   6. A jornada é longa parte 2 - Colisão entre 2 Retângulos
   7. "Imagine" seu programa
   8. Agradecimentos, links úteis e fontes
Outros artigos deste autor

Ubuntu/Debian/Kali Linux e outros no Android

Visual Studio no Linux

Tutorial SFML

Tutorial OpenGL v3.0

Tutorial OpenGL

Leitura recomendada

Detectando assalto na multidão com visão computacional

Gerencie suas contas financeiras pessoais com Terminal Finances

Criando programas com suporte a arquivos de configuração com a libConfuse

Reprodução de arquivos WAV com SDL_mixer e linguagem C

Apreendendo a utilizar o GNU Debugger (parte 2)

  
Comentários
[1] Comentário enviado por fabio em 08/05/2015 - 10:30h

Muito bom! Vou tentar criar um game simples pra minha filha ficar clicando no retângulo com a cor certa com base neste tutorial.

[2] Comentário enviado por Thihup em 08/05/2015 - 11:21h


[1] Comentário enviado por fabio em 08/05/2015 - 10:30h

Muito bom! Vou tentar criar um game simples pra minha filha ficar clicando no retângulo com a cor certa com base neste tutorial.


Fábio, mais uma vez, muito obrigado !

E boa sorte com o aplicativo, espero que sua filha goste.

Qualquer dúvida só pedir =D

[]'s

T+

[3] Comentário enviado por UmCaraAToa em 08/05/2015 - 11:25h

Bom artigo!
Favoritado e pega meu 10!

Até

[4] Comentário enviado por Thihup em 08/05/2015 - 11:30h


[3] Comentário enviado por UmCaraAToa em 08/05/2015 - 11:25h

Bom artigo!
Favoritado e pega meu 10!

Até


Valeu fera

T+

[5] Comentário enviado por xerxeslins em 08/05/2015 - 11:49h


Favoritado. Vou ler depois com calma. Mas só de dar uma olhada por rápida vi que é material interessante!
--
http://pastebin.com/aji5Qp05

[6] Comentário enviado por Thihup em 08/05/2015 - 11:55h


[5] Comentário enviado por xerxeslins em 08/05/2015 - 11:49h


Favoritado. Vou ler depois com calma. Mas só de dar uma olhada por rápida vi que é material interessante!
--
http://pastebin.com/aji5Qp05


Valeu fera, Obrigado!

[]'s

T+

[7] Comentário enviado por preroeb em 08/05/2015 - 19:02h

Parabéns pelo artigo escrito, é uns dos melhores (e únicos) artigos sobre OpenGL aqui no VOL.

[8] Comentário enviado por Thihup em 08/05/2015 - 19:04h


[7] Comentário enviado por preroeb em 08/05/2015 - 19:02h

Parabéns pelo artigo escrito, é uns dos melhores (e únicos) artigos sobre OpenGL aqui no VOL.


Valew pela força!

Dando duro pra trazer um artigo de qualidade pra vocês, meu povinho do "Volzinho"!

[]'s

T+

[9] Comentário enviado por Felipeigor em 08/05/2015 - 19:43h

Ae Parabéns brother excelente artigo , favoritado aqui tbm :)

Igor Felipe
Cadastrado desde: 25/09/2009

[b]If it moves , compile it.[/b]

[10] Comentário enviado por Thihup em 08/05/2015 - 19:44h


[9] Comentário enviado por Felipeigor em 08/05/2015 - 19:43h

Ae Parabéns brother excelente artigo , favoritado aqui tbm :)

Igor Felipe
Cadastrado desde: 25/09/2009

[b]If it moves , compile it.[/b]


Valew Tambem pelo apoio!

[]'s

T+

[11] Comentário enviado por SamL em 09/05/2015 - 12:50h

Legal cara, bem explicada a parte sobre colisão. Um bom artigo como um todo. Parabéns.

[12] Comentário enviado por Thihup em 09/05/2015 - 13:40h


[11] Comentário enviado por SamL em 09/05/2015 - 12:50h

Legal cara, bem explicada a parte sobre colisão. Um bom artigo como um todo. Parabéns.


Valew Sam! Sempre me apoiando!

[]'s

T+

[13] Comentário enviado por Ang em 09/05/2015 - 16:14h

Oi, Thiago!
Dei uma rápida lida no seu artigo.
Está muito bom!
Continue assim, com essas ótimas contribuições!

Ang,
Manaus, AM, Brasil.
Usuário de sistemas operacionais livres/abertos tipo Unix ou tipo DOS,
Distros Favoritas: FreeBSD, Free-DOS, , PC-DOS, Bodhi Linux, Ubuntu, Big Linux, Kurumim, OpenSUSE, Slackware e Slax.

[14] Comentário enviado por Thihup em 09/05/2015 - 16:18h


[13] Comentário enviado por Ang em 09/05/2015 - 16:14h

Oi, Thiago!
Dei uma rápida lida no seu artigo.
Está muito bom!
Continue assim, com essas ótimas contribuições!

Ang,
Manaus, AM, Brasil.
Usuário de sistemas operacionais livres/abertos tipo Unix ou tipo DOS,
Distros Favoritas: FreeBSD, Free-DOS, , PC-DOS, Bodhi Linux, Ubuntu, Big Linux, Kurumim, OpenSUSE, Slackware e Slax.


Valew !
Obrigado por ter lido!

[]'s

T+


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts