Ir ao conteúdo
  • Cadastre-se

C SDL 2.0: Como desenhar um simples retângulo?


Cris.Pavani
Ir à solução Resolvido por arfneto,

Posts recomendados

Boa noite pessoal!! É o seguinte minha intenção é aprender a biblioteca SDL 2 para fazer pequenos joguinhos; só pra ter uma noção de como funciona (até hoje só mexi em console). Eu pesquisei e acabei copiando o código abaixo; ele compila sem erro e roda mas não imprime o retângulo:

#include <SDL/SDL.h>

int main(int argc, char** argv)
{
   printf("Iniciando SDL...\n");

   int width = 10, height = 10;

   SDL_Surface *screen; //cria uma surface SDL

   screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE); //inicia o vídeo


   printf("SDL iniciado...\n");


   SDL_Surface *retangulo; //declara o retângulo
   retangulo = SDL_CreateRGBSurface(0, width, height, 32, 0, 0, 0, 0); //cria o retângulo
   SDL_Rect rect = {350, 250, 100, 100};
   SDL_FillRect(retangulo, NULL, SDL_MapRGB(screen->format, 255, 0, 0)); //pinta o retângulo
   SDL_BlitSurface(retangulo, &rect, screen, NULL);


   SDL_UpdateRect(screen, 0, 0, 0, 0);
   SDL_UpdateRect(retangulo, 0, 0, 0, 0);
   SDL_FreeSurface(retangulo);
   SDL_FreeSurface(screen);


   //aqui implementa o modo de fechar o software
   SDL_Event event;
   while(1)
   {
       while (SDL_PollEvent(&event))
       {
           switch (event.type)
           {
           case SDL_KEYDOWN: //caso alguma tecla seja pressionada
               {
                   switch (event.key.keysym.sym) //para detectar a tecla pressionada
                   {
                       case SDLK_ESCAPE:
                        printf("ESC pressionado.\n");
                        exit(0);
                        break;
                       case SDLK_UP:
                        printf("Seta para cima pressionanda.\n");
                        exit(0);
                        break;
                       case SDLK_a:
                        printf("A pressionado.\n");
                        exit(0);
                        break;
                    }
                    break;
               }
           }
           if(event.type == SDL_QUIT) //fecha através do botão fechar
           {
               printf("Fechado pelo botão fechar...\n");
               exit(0);
           }
        }
   }
}

Alguém pode me dizer o que tem de errado? E me ajudar na maneira certa de declarar e renderizar um retângulo? Eu pesquisei esse código e fui codificando meio que sem saber o que estava acontecendo.

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Esse código que você postou parece não estar em conformidade com o SDL2, provável que seja SDL1 ou algum versão bem inicial do SDL2.

 

Na própria pagina do SDL2 tem um exemplo de como desenhar um triangulo.

 

https://wiki.libsdl.org/SDL_RenderDrawLines

 

#include "SDL2/SDL.h"

#define POINTS_COUNT 4

static SDL_Point points[POINTS_COUNT] = {
	{320, 200},
	{300, 240},
	{340, 240},
	{320, 200}
};

int main(int argc, char* argv[])
{
	if (SDL_Init(SDL_INIT_VIDEO) == 0)
	{
		SDL_Window* window = NULL;
		SDL_Renderer* renderer = NULL;

		if (SDL_CreateWindowAndRenderer(640, 480, 0, &window, &renderer) == 0)
		{
			SDL_bool done = SDL_FALSE;

			while (!done)
			{
				SDL_Event event;
				
				SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
				SDL_RenderClear(renderer);

				SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
				SDL_RenderDrawLines(renderer, points, POINTS_COUNT);

				// ou diretamente com RenderDrawLine sem usar essa struct bidimensional SDL_Point.
				// SDL_RenderDrawLine(renderer, 320, 200, 300, 240);
				// SDL_RenderDrawLine(renderer, 300, 240, 340, 240);
				// SDL_RenderDrawLine(renderer, 340, 240, 320, 200);
				
				SDL_RenderPresent(renderer);

				while (SDL_PollEvent(&event))
				{
					if (event.type == SDL_QUIT)
					{
						done = SDL_TRUE;
					}
				}
			}
		}

		if (renderer)
		{
			SDL_DestroyRenderer(renderer);
		}
		if (window)
		{
			SDL_DestroyWindow(window);
		}
	}
	SDL_Quit();
	return 0;
}

 

Link para o comentário
Compartilhar em outros sites

4 horas atrás, Benjamin Breeg disse:

Esse código que você postou parece não estar em conformidade com o SDL2, provável que seja SDL1 ou algum versão bem inicial do SDL2.

 

Na própria pagina do SDL2 tem um exemplo de como desenhar um triangulo.

 

https://wiki.libsdl.org/SDL_RenderDrawLines

 


#include "SDL2/SDL.h"

#define POINTS_COUNT 4

static SDL_Point points[POINTS_COUNT] = {
	{320, 200},
	{300, 240},
	{340, 240},
	{320, 200}
};

int main(int argc, char* argv[])
{
	if (SDL_Init(SDL_INIT_VIDEO) == 0)
	{
		SDL_Window* window = NULL;
		SDL_Renderer* renderer = NULL;

		if (SDL_CreateWindowAndRenderer(640, 480, 0, &window, &renderer) == 0)
		{
			SDL_bool done = SDL_FALSE;

			while (!done)
			{
				SDL_Event event;
				
				SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
				SDL_RenderClear(renderer);

				SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
				SDL_RenderDrawLines(renderer, points, POINTS_COUNT);

				// ou diretamente com RenderDrawLine sem usar essa struct bidimensional SDL_Point.
				// SDL_RenderDrawLine(renderer, 320, 200, 300, 240);
				// SDL_RenderDrawLine(renderer, 300, 240, 340, 240);
				// SDL_RenderDrawLine(renderer, 340, 240, 320, 200);
				
				SDL_RenderPresent(renderer);

				while (SDL_PollEvent(&event))
				{
					if (event.type == SDL_QUIT)
					{
						done = SDL_TRUE;
					}
				}
			}
		}

		if (renderer)
		{
			SDL_DestroyRenderer(renderer);
		}
		if (window)
		{
			SDL_DestroyWindow(window);
		}
	}
	SDL_Quit();
	return 0;
}

 

O Benjamim, muito obrigado pela atenção cara. Então, criei um novo projeto SDL no code blocks e tentei esse código mas deu os erros seguintes:

 

desktop:~/CodeBlocksProject/projeto_08/main$ g++ main.cpp -o main -lSDL
/tmp/cc5jquci.o: Na função "main":
main.cpp:(.text+0x63): referência não definida para "SDL_CreateWindowAndRenderer"
main.cpp:(.text+0xa2): referência não definida para "SDL_SetRenderDrawColor"
main.cpp:(.text+0xae): referência não definida para "SDL_RenderClear"
main.cpp:(.text+0xcf): referência não definida para "SDL_SetRenderDrawColor"
main.cpp:(.text+0xe7): referência não definida para "SDL_RenderDrawLines"
main.cpp:(.text+0xf3): referência não definida para "SDL_RenderPresent"
main.cpp:(.text+0x134): referência não definida para "SDL_DestroyRenderer"
main.cpp:(.text+0x149): referência não definida para "SDL_DestroyWindow"
collect2: error: ld returned 1 exit status

 

Você já passou por isso e saberia me explicar o por quê disso e como resolver?

Olha eu utilizo o linux mint e compilo no terminal através do comando "g++ main.cpp -o main -lSDL", não sei se essa informação ajuda....

 

Mas muito obrigado mesmo!

Link para o comentário
Compartilhar em outros sites

28 minutos atrás, Benjamin Breeg disse:

Então cara eu não sou familiarizado com Linux mas o que parece é que você instalou a versão mais antiga do SDL.. tente instalar o SDL2.

 

Veja se esse vídeo ajuda.

 

 

 

O Benjamim agora deu certo aqui. Valeu mesmo. O meu erro na verdade estava sendo bem bobo: na hora de compilar estava utilizando o comando "g++ main.cpp -o main -lSDL". Mas o comando estava incompleto, o correto é assim "g++ main.cpp -o main -lSDL -lSDL2". Estava só faltando o termo -lSDL2. :-). Descobri através do vídeo.

Link para o comentário
Compartilhar em outros sites

7 horas atrás, arfneto disse:

Esse código que você postou funcionou? Só mudando o parâmetro de compilação? Poda postar o código como funcionou? Queria rodar no Windows

Bom dia. Veja, o código que eu postei na pergunta já rodava mesmo sem o parâmetro. O problema é que não renderizava o retângulo que eu queria. O parâmetro não fez ele renderizar também.

Agora, o código que o Benjamim postou é que deu erro na compilação e que se resolveu com a inclusão do parâmetro -lSDL2. E esse sim imprimiu um triângulo na tela. Não sei se você trabalha no linux mas esse termo "g++ main.cpp -o main -lSDL -lSDL2" temos, pelo menos eu tenho, que digitar no terminal do linux para compilar o código. No windows eu não saberia como fazer. Sorry :(

Link para o comentário
Compartilhar em outros sites

Acho que esse primeiro código dele não aparece nada porque ele tentou implementar uma especie de "blit" que copia uma superfície para outra, só que não tenha certeza se com esses comandos que ele usou tinha algo na memoria para ser copiado para a superfície screen. No SDL2 eu uso a biblioteca SDL_image para manipular imagens, implementar esse blit na "unha" não deve ser tão simples assim já que envolve enviar os padrões, imagens  ou matrizes com as imagens desenhadas pixel a pixel como faziam antigamente para a memoria e fazer a copia entre superfícies. 

 

Adaptando o programa dele em SDL1 seria mais ou menos assim.

 

#include <SDL/SDL.h>

int main(int argc, char** argv)
{
    printf("Iniciando SDL...\n");

    SDL_Surface *screen, *retangulo; //cria uma surface SDL

    screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE); //inicia o vídeo

    Uint32 color = SDL_MapRGB(screen->format, 255,0,0);

    printf("SDL iniciado...\n");

    retangulo = SDL_LoadBMP("rect.bmp");

    SDL_Event event;
    while(1) {
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_KEYDOWN: { //caso alguma tecla seja pressionada
                switch (event.key.keysym.sym) { //para detectar a tecla pressionada
                case SDLK_ESCAPE:
                    printf("ESC pressionado.\n");
                    exit(0);
                    break;
                case SDLK_UP:
                    printf("Seta para cima pressionanda.\n");
                    exit(0);
                    break;
                case SDLK_a:
                    printf("A pressionado.\n");
                    exit(0);
                    break;
                }
                break;
            }
            }
            if(event.type == SDL_QUIT) { //fecha através do botão fechar
                printf("Fechado pelo botão fechar...\n");
                exit(0);
            }
        }

        SDL_FillRect(screen, &screen->clip_rect, color);
        SDL_BlitSurface(retangulo, NULL, screen, NULL);
        SDL_Flip(screen);

    }
    SDL_FreeSurface(retangulo);
    SDL_Quit();
    return 0;
}

 

 

rect.bmp

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Solução
8 horas atrás, Cris.Pavani disse:

rodava mesmo sem o parâmetro. O problema é que não renderizava o retângulo que eu queria. O parâmetro não fez ele renderizar também

 

Oh rodava que dizer que apenas compilava. Agora entendo. Só com as Surfaces eu não via como mostrar algo e aí fiquei curioso! Seria preciso carregar algo, mesmo que seja um bitmap como no exemplo acima. Ou criar o normal, window, renderer e textures. Obrigado por responder

 

9 horas atrás, Cris.Pavani disse:

No windows eu não saberia como fazer. Sorry

 

Pode usar exatamente o mesmo comando no Windows!
 

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!