Something about programming

Textures in SDL2

Previous tutorial: SDL2 loading images (bmp, jpg, png)
SDL2 textures and image rotation. Python language

In previous tutorials we learned how to load images and blit them on the program window using surfaces. In this tutorial we'll learn how to rotate images.

We have two options for rotating of images. First, do all the math ourselves. That's a good idea actually but it requires separate tutorial (and there will be one later). Second: using SDL textures.

SDL2 renderer

SDL gives us API of 2d accelerated rendering. To use it we need to get renderer (in C language it's SDL_Renderer type and in Python language it's just a variable we get from result of special function). There are different functions to work with blitting and rendering. When we talk about blitting, we assume use of surfaces (just two-dimensional array of pixels), in case of rendering we use textures (SDL_Texture type). Texture is a structure which contains efficient representation of image data.

Now, let's create the SDL2_Renderer in Python programming language. To do this we need to use window variable:

window = sdl2.SDL_CreateWindow(b"Renderer", 100, 20, width, height, sdl2.SDL_WINDOW_SHOWN) renderer = sdl2.SDL_CreateRenderer(window, -1, 0)

SDL_CreateRenderer accepts 3 arguments. First - window which rendering context we want to get, second - index of driver. -1 means we'll get the first one which supports capabilities that defined in third argument. Third - flags which define acceleration: software, hardware, we'll use 0 - it's software acceleration which will work on any computer.

Now we have a renderer and it's time to create a texture.

SDL_Texture in Python language

We can create SDL2 texture two ways: using SDL_image library and loading from surface.

To create texture from surface we need to use SDL_CreateTextureFromSurface function:

window = sdl2.SDL_CreateWindow(b"Renderer", 100, 20, width, height, sdl2.SDL_WINDOW_SHOWN) renderer = sdl2.SDL_CreateRenderer(window, -1, 0) surface = sdl2.SDL_LoadBMP(b"tank.bmp") texture = sdl2.SDL_CreateTextureFromSurface(renderer, surface)

First we get renderer, then load surface and then from surface we create texture. The function accepts renderer and surface.

Another way to create texture:

window = sdl2.SDL_CreateWindow(b"Renderer", 100, 20, width, height, sdl2.SDL_WINDOW_SHOWN) renderer = sdl2.SDL_CreateRenderer(window, -1, 0) texture = sdl2.sdlimage.IMG_LoadTexture(renderer, b"filename");

IMG_LoadTexture creates texture directly from file. First argument - rendering context, second - file name (any format).

Clearing renderer and presenting it

Before we'll draw texture in the window let's check how to work with SDL2 renderer in Python programming language. Later we'll render contents of the window each iteration of the loop and though in this tutorial we'll do the work before it, it can be placed in the loop without changes.

sdl2.SDL_RenderClear(renderer); sdl2.SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255) sdl2.SDL_RenderFillRect(renderer, sdl2.SDL_Rect(0, 0, width, height)) sdl2.SDL_RenderPresent(renderer);

SDL_RenderClear - clears the window from any data on it. SDL_RenderPresent shows drawn content. Between these two calls you need to draw what you want. In this case I set the color and fill the window with this color. SDL_SetRenderDrawColor last 4 arguments are color channels in order RGBA. Here it's white. SDL_RenderFillRect fills specified rectangular area of window. In this case it fills full window.

SDL2 rendering texture in window in Python

SDL library allows to draw texture in window with SDL_RenderCopy.

sdl2.SDL_RenderCopy(renderer, texture, None, sdl2.SDL_Rect(50, 50, 50, 50));

First two arguments are self-explanatory, third - rectangle from the source, in our case we want to render full texture and fourth argument - rectangle on window where we want to draw texture.

Drawing SDL2 texture with rotation on window in Python language

SDL provides extended version of render copy, it's called SDL_RenderCopyEx. First 4 arguments are the same as for SDL_RenderCopy. But additionally it takes rotation angle, point around which the rotation will occur and the last one - flipping of image (vertically or horizontally).

Here is the final version of the program with the tank image rotated:

import ctypes import sdl2 import sdl2.sdlimage sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO) width = 300 height = 300 window = sdl2.SDL_CreateWindow(b"Texture rendering and image rotation", 100, 20, width, height, sdl2.SDL_WINDOW_SHOWN) renderer = sdl2.SDL_CreateRenderer(window, -1, 0) texture = sdl2.sdlimage.IMG_LoadTexture(renderer, b"tank.png"); sdl2.SDL_RenderClear(renderer); sdl2.SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255) sdl2.SDL_RenderFillRect(renderer, sdl2.SDL_Rect(0, 0, width, height)) sdl2.SDL_RenderCopyEx(renderer, texture, None, sdl2.SDL_Rect(50, 50, 50, 50), 109.0, None, sdl2.SDL_FLIP_NONE) sdl2.SDL_RenderPresent(renderer); is_running = True event = sdl2.SDL_Event() while is_running: while sdl2.SDL_PollEvent(ctypes.byref(event)) != 0: if event.type == sdl2.SDL_QUIT: is_running = False break sdl2.SDL_DestroyWindow(window) sdl2.SDL_Quit()

Tank is rotated by 109 degrees. Rotation point is set to None, it means rotation will happen around center of destination rectangle, and there is no flipping of image.

Conclusion. 2d graphics in SDL2

Till now we talk only about 2d graphics. SDL can be used for 3d graphics too - it has a wrapper functions for OpenGL. And we'll work with 3d graphics later. But firstly we'll practice with 2d. We know everything we need to develop simple examples for different game concepts.

In next tutorial we'll start to build library in Python programming language that we'll use later to demonstrate different kind of algorithms.

Comments:

No comments yet