๐Ÿ“œ โฌ†๏ธ โฌ‡๏ธ

SDL 2 Tutorial: Lesson 5 - Textures

Hello everyone and welcome to the fifth lesson on SDL 2, in which we will analyze the texture, simplifying the work of the computer. All lessons in English can be found here .

In the second version of SDL, there is a very good ability to create textures and render them. Hardware rendering is much faster than drawing surfaces in a window.

Textures have their own data type - SDL_Texture . When working with textures, we need a render for rendering. Now we will announce all this.

#include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> using namespace std; int SCREEN_WIDTH = 640; int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Renderer *ren = NULL; SDL_Texture *flower = NULL; 

Here we announced the window, render and this flower.
Just hooked up the library and set the window size.
')
The Init function will also have to be changed.

  bool ok = true; if (SDL_Init(SDL_INIT_VIDEO) != 0) { cout << "Can't init: " << SDL_GetError() << endl; ok = false; } win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { cout << "Can't create window: " << SDL_GetError() << endl; ok = false; } 

To begin with, we will create the variable ok , in order not to finish the function immediately, but to find all the errors during initialization. Next, we initialize the SDL and create a window using a well-known method.

It's time to announce the render.

  ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (ren == NULL) { cout << "Can't create renderer: " << SDL_GetError() << endl; ok = false; } SDL_SetRenderDrawColor(ren, 0xFF, 0xFF, 0xFF, 0xFF); 

Render is declared by the SDL_CreateRenderer function. It takes 3 values: the window for which this render will be used, the driver index (or -1 if we want to find the first one that matches) and flags. I used the SDL_RENDERER_ACCELERATED and SDL_RENDERER_PRESENTVSYNC flags . Here is a list of all flags:

Flags
SDL_RENDERER_SOFTWARE - backup version of;
SDL_RENDERER_ACCELERATED - use hardware acceleration;
SDL_RENDERER_PRESENTVSYNC - vertical sync;
SDL_RENDERER_TARGETTEXTURE - support for rendering to texture.

Next we use the function SDL_SetRenderDrawColor , which sets the color for drawing primitives.

After that, we initialize the IMG and return ok .

  int flags = IMG_INIT_PNG; if (!(IMG_Init(flags) & flags)) { cout << "Can't init image: " << IMG_GetError() << endl; ok = false; } return ok; } 

Now we will write the Load function.

 bool load() { bool ok = true; SDL_Surface * temp_surf = NULL; temp_surf = IMG_Load("flower.png"); if (temp_surf == NULL) { cout << "Can't load image: " << IMG_GetError() << endl; ok = false; } 

Here we also created the variable ok , for the same needs. Created a temporary surface and uploaded images of a flower into it.

Next we need to make a surface texture.

  flower = SDL_CreateTextureFromSurface(ren, temp_surf); if (flower == NULL) { cout << "Can't create texture from surface: " << SDL_GetError() << endl; ok = false; } 

The SDL_CreateTextureFromSurface function will help us in creating the texture. It takes the values โ€‹โ€‹of the render and the surface. Returns an instance of the SDL_Texture class.

In order not to clog the memory, we need to clean the temporary surface. After that, we return ok and the function is ready.

The Quit function has taken a few more steps.

 void quit() { SDL_DestroyWindow(win); win = NULL; SDL_DestroyRenderer(ren); ren = NULL; SDL_DestroyTexture(flower); flower = NULL; SDL_Quit(); IMG_Quit(); } 

Here we removed the window, render, texture and exited SDL and IMG . I also assigned all deleted objects to NULL for even better memory cleaning.

We start writing the Main function.

 int main (int argc, char ** argv) { if (!init()) { quit(); return 1; } if (!load()) { quit(); return 1; } 

We wrote initialization and loading, we do not stop here.

The next step is to create 2 variables.

  bool run = true; SDL_Event e; 

This program will be with the main loop to refresh your memory, so let's start not writing it.

 while (run) { while(SDL_PollEvent(&e) != 0) { if (e.type == SDL_QUIT) { run = false; } } 

Handled the event of clicking the cross and that's it.

It's time to draw. When using textures and rendering for rendering, excellent functions are used from those we know. In order to clear the screen from the drawn textures, the function SDL_RenderClear is used . It paints the screen with the color we specified with the function SDL_SetRenderDrawColor . The SDL_RenderCopy function is used to draw the texture, and the SDL_RenderPresent is used to update the screen. Now we will write them.

  SDL_RenderClear(ren); SDL_RenderCopy(ren, flower, NULL, NULL); SDL_RenderPresent(ren); } 

We analyze only the function SDL_RenderCopy . It takes 4 values. The first is the render, the second is the texture, the third is the rectangle whose area we want to cut to draw, the fourth is the rectangle whose coordinates are used to draw, and the width and height are used to change the size of the texture.

Next, call the Quit function and return 0 .

  quit(); return 0; } 

At this point I will finish the lesson, if something was not clear - write, and I say goodbye, bye everyone!

By the way, here is the full code:

 #include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> using namespace std; int SCREEN_WIDTH = 640; int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Renderer *ren = NULL; SDL_Texture *flower = NULL; bool init() { bool ok = true; if (SDL_Init(SDL_INIT_VIDEO) != 0) { cout << "Can't init: " << SDL_GetError() << endl; ok = false; } win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { cout << "Can't create window: " << SDL_GetError() << endl; ok = false; } ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (ren == NULL) { cout << "Can't create renderer: " << SDL_GetError() << endl; ok = false; } SDL_SetRenderDrawColor(ren, 0xFF, 0xFF, 0xFF, 0xFF); int flags = IMG_INIT_PNG; if (!(IMG_Init(flags) & flags)) { cout << "Can't init image: " << IMG_GetError() << endl; ok = false; } return ok; } bool load() { bool ok = true; SDL_Surface * temp_surf = NULL; temp_surf = IMG_Load("flower.png"); if (temp_surf == NULL) { cout << "Can't load image: " << IMG_GetError() << endl; ok = false; } flower = SDL_CreateTextureFromSurface(ren, temp_surf); if (flower == NULL) { cout << "Can't create texture from surface: " << SDL_GetError() << endl; ok = false; } SDL_FreeSurface(temp_surf); return ok; } void quit() { SDL_DestroyWindow(win); win = NULL; SDL_DestroyRenderer(ren); ren = NULL; SDL_DestroyTexture(flower); flower = NULL; SDL_Quit(); IMG_Quit(); } int main (int argc, char ** argv) { if (!init()) { quit(); return 1; } if (!load()) { quit(); return 1; } bool run = true; SDL_Event e; while (run) { while(SDL_PollEvent(&e) != 0) { if (e.type == SDL_QUIT) { run = false; } } SDL_RenderClear(ren); SDL_RenderCopy(ren, flower, NULL, NULL); SDL_RenderPresent(ren); } quit(); return 0; } 

โ† Previous lesson | Next lesson โ†’

Source: https://habr.com/ru/post/456798/


All Articles