SDL,将图像粘贴到屏幕的一部分
SDL, pasting image on a part of the screen
我有一个使用矩阵在内部运行的棋盘游戏。我为它创建了一个非常简单的图形用户界面,其中包含一个使用矩形生成的板。板函数 gimprimir() 详述如下:它获取矩阵并在需要时将其转换为创建不同类型的矩形。
现在我需要在屏幕的一部分上插入图像。 None 到目前为止我找到的教程。其中一些要么已经过时(不适用于 SDL2),要么根本没有考虑将图像放在屏幕的一部分中的可能性。例如本教程:
http://lazyfoo.net/tutorials/SDL/02_getting_an_image_on_the_screen/index.php
教您如何将图像放在屏幕上,但不教您如何将其加载到屏幕的一部分。
每当我尝试修改它时,都会出现分段错误。
我想保持简单。图片格式为.bmp.
这是我当前的代码:
bool loadMedia();
void close();
SDL_Texture* loadTexture( std::string path );
SDL_Window* gWindow = NULL;
SDL_Renderer* gRenderer = NULL;
const int SCREEN_WIDTH = 1200;
const int SCREEN_HEIGHT = 680;
int main(int argc, char* args[]){
nodo a;
if( !init() ){
cout << "Failed to initialize!\n" ;
}
else{
if(!loadMedia()){
cout << "Failed to load media!\n";
}
else{
bool quit = false; // flag ciclo principal
SDL_Event e; // variables manejo de eventos
SDL_Event t;
gimprimir(a);
}
}
}
函数 gimprimir() 使用结构 a:
打印一个简单的板
struct nodo {
array<array<int,19>,19> tablero; // Estado tablero
array<int,2> p1,p2; // Posiciones
int d1,d2; // Distancias mínimas
int paredes1;
int paredes2;
} a;
函数gimprimir是这样的(只使用空矩形和填充矩形):
void gimprimir(nodo aa){
//Clear screen
SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
SDL_RenderClear( gRenderer );
int i,j;
for (i=1; i<=17; i++){
if (i%2==1){
for (j=1; j<=17 ; j++){
if (j%2==1){
if (aa.p1[0]==i && aa.p1[1]==j){ // FICHA 1
SDL_Rect fillRect = {(50+SCREEN_WIDTH/11)+(SCREEN_WIDTH/11)*(j-1)/2+34, (SCREEN_HEIGHT/11)+(SCREEN_HEIGHT/11)*(i-1)/2+34, SCREEN_WIDTH/12, SCREEN_HEIGHT/12};
SDL_SetRenderDrawColor( gRenderer, 0xff, 0xcc, 0x66, 0xFF );
SDL_RenderFillRect( gRenderer, &fillRect );
}
else{
if (aa.p2[0]==i && aa.p2[1]==j){ // FICHA 2
SDL_Rect fillRect = {(50+SCREEN_WIDTH/11)+(SCREEN_WIDTH/11)*(j-1)/2+34, (SCREEN_HEIGHT/11)+(SCREEN_HEIGHT/11)*(i-1)/2+34, SCREEN_WIDTH/12, SCREEN_HEIGHT/12};
SDL_SetRenderDrawColor( gRenderer, 0x6E, 0x2C, 0x67, 0xFF );
SDL_RenderFillRect( gRenderer, &fillRect );
}
else{ // CASILLA VACÍA
SDL_Rect fillRect = {(50+SCREEN_WIDTH/11)+(SCREEN_WIDTH/11)*(j-1)/2+34, (SCREEN_HEIGHT/11)+(SCREEN_HEIGHT/11)*(i-1)/2+34, SCREEN_WIDTH/12, SCREEN_HEIGHT/12};
SDL_SetRenderDrawColor( gRenderer, 0x8B, 0x45, 0x13, 0xFF);
SDL_RenderFillRect( gRenderer, &fillRect );
}
}
}
}
}
}
SDL_RenderPresent( gRenderer );
}
如果需要,这是loadMedia():
bool loadMedia()
{
//Loading success flag
bool success = true;
//Nothing to load
return success;
}
我想把两者都显示在屏幕上。这个想法是首先加载图像,让它永远留在屏幕的一部分,然后更新用 gimprimir();
生成的矩形
SDL_BlitSurface is the SDL function used to blit (copy) from a surface to another, it takes two SDL_Rect 个参数,srcrect 用于源,dstrect 用于目标。
SDL_BlitSurface 从 SDL1.2 到 SDL2 没有太大变化,因此,使用它的旧示例应该仍然有效。
在 getting_an_image_on_the_screen
示例中,您建议将 NULL 指针用于 src 和 dst rect,NULL rect意味着将整个 src 表面复制到 top, left = 0, 0
的目标,最大尺寸等于目标尺寸(如果源更大应该被裁剪)。
要blit 局部图像只需指定 src 和 dst rect:
SDL_Rect srcrect = { 0, 0, 100, 100 };
SDL_Rect dstrect = { 50, 50, 100, 100 };
//Apply the image
SDL_BlitSurface( gHelloWorld, &srcrect, gScreenSurface, &dstrect );
在这种情况下 top, left = 0, 0
与 width, height = 100, 100
从源表面 (gHelloWorld
) 是 blit 到目标表面的 top, left = 50, 50
(gScreenSurface
).
how to load it with other types of objects
抱歉,我不清楚你说的其他类型的对象
是什么意思
SDL_BlitSurface() 会起作用,但由于您使用的是 SDL2,因此您可能主要使用 SDL_Textures 而不是 SDL_Surfaces。如果是这种情况,将一个纹理复制到另一个纹理或屏幕上的最简单方法是使用 keltar 提到的 SDL_RenderCopy()
。这里解释了使用 SDL_Texture 的优点:http://wiki.libsdl.org/MigrationGuide#Video
如此处所述,SDL_RenderCopy()
有四个参数:指向 SDL_Renderer 的指针、指向源纹理的指针、指向源矩形的指针和指向目标矩形的指针。默认情况下,纹理将被复制到屏幕上,但您可以通过使用 SDL_SetRenderTarget().
设置目标纹理来复制到其他纹理上
关于源矩形和目标矩形的所有内容都来自 SDL_BlitSurface。
我有一个使用矩阵在内部运行的棋盘游戏。我为它创建了一个非常简单的图形用户界面,其中包含一个使用矩形生成的板。板函数 gimprimir() 详述如下:它获取矩阵并在需要时将其转换为创建不同类型的矩形。
现在我需要在屏幕的一部分上插入图像。 None 到目前为止我找到的教程。其中一些要么已经过时(不适用于 SDL2),要么根本没有考虑将图像放在屏幕的一部分中的可能性。例如本教程:
http://lazyfoo.net/tutorials/SDL/02_getting_an_image_on_the_screen/index.php
教您如何将图像放在屏幕上,但不教您如何将其加载到屏幕的一部分。
每当我尝试修改它时,都会出现分段错误。
我想保持简单。图片格式为.bmp.
这是我当前的代码:
bool loadMedia();
void close();
SDL_Texture* loadTexture( std::string path );
SDL_Window* gWindow = NULL;
SDL_Renderer* gRenderer = NULL;
const int SCREEN_WIDTH = 1200;
const int SCREEN_HEIGHT = 680;
int main(int argc, char* args[]){
nodo a;
if( !init() ){
cout << "Failed to initialize!\n" ;
}
else{
if(!loadMedia()){
cout << "Failed to load media!\n";
}
else{
bool quit = false; // flag ciclo principal
SDL_Event e; // variables manejo de eventos
SDL_Event t;
gimprimir(a);
}
}
}
函数 gimprimir() 使用结构 a:
打印一个简单的板struct nodo {
array<array<int,19>,19> tablero; // Estado tablero
array<int,2> p1,p2; // Posiciones
int d1,d2; // Distancias mínimas
int paredes1;
int paredes2;
} a;
函数gimprimir是这样的(只使用空矩形和填充矩形):
void gimprimir(nodo aa){
//Clear screen
SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
SDL_RenderClear( gRenderer );
int i,j;
for (i=1; i<=17; i++){
if (i%2==1){
for (j=1; j<=17 ; j++){
if (j%2==1){
if (aa.p1[0]==i && aa.p1[1]==j){ // FICHA 1
SDL_Rect fillRect = {(50+SCREEN_WIDTH/11)+(SCREEN_WIDTH/11)*(j-1)/2+34, (SCREEN_HEIGHT/11)+(SCREEN_HEIGHT/11)*(i-1)/2+34, SCREEN_WIDTH/12, SCREEN_HEIGHT/12};
SDL_SetRenderDrawColor( gRenderer, 0xff, 0xcc, 0x66, 0xFF );
SDL_RenderFillRect( gRenderer, &fillRect );
}
else{
if (aa.p2[0]==i && aa.p2[1]==j){ // FICHA 2
SDL_Rect fillRect = {(50+SCREEN_WIDTH/11)+(SCREEN_WIDTH/11)*(j-1)/2+34, (SCREEN_HEIGHT/11)+(SCREEN_HEIGHT/11)*(i-1)/2+34, SCREEN_WIDTH/12, SCREEN_HEIGHT/12};
SDL_SetRenderDrawColor( gRenderer, 0x6E, 0x2C, 0x67, 0xFF );
SDL_RenderFillRect( gRenderer, &fillRect );
}
else{ // CASILLA VACÍA
SDL_Rect fillRect = {(50+SCREEN_WIDTH/11)+(SCREEN_WIDTH/11)*(j-1)/2+34, (SCREEN_HEIGHT/11)+(SCREEN_HEIGHT/11)*(i-1)/2+34, SCREEN_WIDTH/12, SCREEN_HEIGHT/12};
SDL_SetRenderDrawColor( gRenderer, 0x8B, 0x45, 0x13, 0xFF);
SDL_RenderFillRect( gRenderer, &fillRect );
}
}
}
}
}
}
SDL_RenderPresent( gRenderer );
}
如果需要,这是loadMedia():
bool loadMedia()
{
//Loading success flag
bool success = true;
//Nothing to load
return success;
}
我想把两者都显示在屏幕上。这个想法是首先加载图像,让它永远留在屏幕的一部分,然后更新用 gimprimir();
生成的矩形SDL_BlitSurface is the SDL function used to blit (copy) from a surface to another, it takes two SDL_Rect 个参数,srcrect 用于源,dstrect 用于目标。
SDL_BlitSurface 从 SDL1.2 到 SDL2 没有太大变化,因此,使用它的旧示例应该仍然有效。
在 getting_an_image_on_the_screen
示例中,您建议将 NULL 指针用于 src 和 dst rect,NULL rect意味着将整个 src 表面复制到 top, left = 0, 0
的目标,最大尺寸等于目标尺寸(如果源更大应该被裁剪)。
要blit 局部图像只需指定 src 和 dst rect:
SDL_Rect srcrect = { 0, 0, 100, 100 };
SDL_Rect dstrect = { 50, 50, 100, 100 };
//Apply the image
SDL_BlitSurface( gHelloWorld, &srcrect, gScreenSurface, &dstrect );
在这种情况下 top, left = 0, 0
与 width, height = 100, 100
从源表面 (gHelloWorld
) 是 blit 到目标表面的 top, left = 50, 50
(gScreenSurface
).
how to load it with other types of objects
抱歉,我不清楚你说的其他类型的对象
是什么意思SDL_BlitSurface() 会起作用,但由于您使用的是 SDL2,因此您可能主要使用 SDL_Textures 而不是 SDL_Surfaces。如果是这种情况,将一个纹理复制到另一个纹理或屏幕上的最简单方法是使用 keltar 提到的 SDL_RenderCopy()
。这里解释了使用 SDL_Texture 的优点:http://wiki.libsdl.org/MigrationGuide#Video
如此处所述,SDL_RenderCopy()
有四个参数:指向 SDL_Renderer 的指针、指向源纹理的指针、指向源矩形的指针和指向目标矩形的指针。默认情况下,纹理将被复制到屏幕上,但您可以通过使用 SDL_SetRenderTarget().
关于源矩形和目标矩形的所有内容都来自 SDL_BlitSurface。