【问题标题】:SDL, pasting image on a part of the screenSDL,将图像粘贴到屏幕的一部分
【发布时间】:2015-04-19 23:42:39
【问题描述】:

我有一个使用矩阵在内部工作的棋盘游戏。我为它创建了一个非常简单的图形用户界面,它包含一个使用矩形生成的板。板函数 gimprimir() 详细说明如下:它获取矩阵并在需要时将其转换为不同类型的矩形。

现在我需要在屏幕的一部分上插入图像。到目前为止,我没有找到任何教程。其中一些要么已经过时(不适用于 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_RenderCopy

标签: c++ sdl


【解决方案1】:

SDL_BlitSurface 是用于将blit(复制)从一个表面到另一个表面的 SDL 函数,它需要两个 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, 0width, height = 100, 100 从源表面 (gHelloWorld) 是 blit 到目标表面 (gScreenSurface) 的 top, left = 50, 50

如何与其他类型的对象一起加载它

对不起,我不清楚你说的其他类型的对象是什么意思

【讨论】:

  • 所以,如果我想将整个图像粘贴到屏幕的一部分,我可以使用SDL_Rect srcrect = NULL;SDL_Rect dstrect = { 50, 50, 100, 100 };
  • 好的,现在我可以将图像加载到屏幕的一部分。问题是如果我加载它并添加 SDL_RenderPresent( gRenderer ); //Apply the image SDL_BlitSurface( cont, NULL, gScreenSurface, &amp;dstrect ); SDL_UpdateWindowSurface( gWindow );gimprimir() 中创建的矩形消失。我希望两者都出现在屏幕上。这个想法是首先加载图像,使其永远留在屏幕的一部分,然后更新使用 gimprimir(); 生成的矩形
  • @D1X 1. 绘制 gimprimir 矩形,2. blit 图像,3. renderpresent 然后 4. updatewindowsurface,应该可以工作
  • @D1X 很高兴它工作。如果您想解释其他类型的对象,也许我可以提供帮助(您是指其他类型的图像文件吗?)
  • 是的,我指的是其他类型的图像文件,但我找到了涵盖它的教程。再次感谢您。
【解决方案2】:

SDL_BlitSurface() 会起作用,但由于您使用的是 SDL2,因此您可能主要使用 SDL_Textures 而不是 SDL_Surfaces。如果是这种情况,将一个纹理复制到另一个纹理或屏幕上的最简单方法是使用 SDL_RenderCopy(),正如 keltar 所述。这里解释了使用 SDL_Texture 的优点:http://wiki.libsdl.org/MigrationGuide#Video

如此处所述,SDL_RenderCopy() 采用四个参数:指向 SDL_Renderer 的指针、指向源纹理的指针、指向源矩形的指针和指向目标矩形的指针。默认情况下,纹理将被复制到屏幕上,但您可以通过使用 SDL_SetRenderTarget() 设置目标纹理来复制到其他纹理。

关于源矩形和目标矩形的所有内容都继承自 SDL_BlitSurface。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    • 2011-02-03
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多