SDL2不使用纹理绘制图像

时间:2014-03-25 07:16:13

标签: c++ c image sdl sdl-2

我一直试图让一个简单的SDL2程序显示图像,然后退出。我有这段代码:

/* compile with `gcc -lSDL2 -o main main.c` */

#include <SDL2/SDL.h>
#include <SDL2/SDL_video.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_surface.h>
#include <SDL2/SDL_timer.h>

int main(void){
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window * w = SDL_CreateWindow("Hi", 0, 0, 640, 480, 0);
    SDL_Renderer * r = SDL_CreateRenderer(w, -1, 0);

    SDL_Surface * s = SDL_LoadBMP("../test.bmp");
    SDL_Texture * t = SDL_CreateTextureFromSurface(r, s);
    SDL_FreeSurface(s);

    SDL_RenderClear(r);
    SDL_RenderCopy(r, t, 0, 0);
    SDL_RenderPresent(r);

    SDL_Delay(2000);

    SDL_DestroyTexture(t);
    SDL_DestroyRenderer(r);
    SDL_DestroyWindow(w);

    SDL_Quit();
}

我知道我省略了每个功能成功的正常检查 - 它们都成功了,为了便于阅读,它们被删除了。我也知道我使用了0而不是空指针或正确的枚举值,这也不是问题的原因(因为当我正确构建程序时出现同样的问题,这是一个快速测试案例,用于测试最简单的情况)

意图是出现一个窗口并显示图像(肯定在该目录中),等待几秒钟然后退出。但结果是窗口显示正确但窗口充满黑色。

额外备注SDL_ShowSimpleMessageBox()似乎可以正常使用。我不知道这与框架的其他部分有什么关系。

3 个答案:

答案 0 :(得分:2)

我只是清楚这一点,你想制作一个纹理,直接做它以便于控制,另外这可以让你更好地控制图像,尝试使用这个代码,经过全面测试和工作,你想要的只是你想要的是为窗口显示图像并在2秒内关闭对吗?如果图片无法加载,那么它就是您图片的位置。

/* compile with `gcc -lSDL2 -o main main.c` */

#include <SDL.h>
#include <SDL_image.h>  
#include <iostream> //I included it since I used cout


int main(int argc, char* argv[]){
bool off = false;
int time;

SDL_Init(SDL_INIT_VIDEO);
SDL_Window * w = SDL_CreateWindow("Hi", 0, 0, 640, 480, SDL_WINDOW_SHOWN);
SDL_Renderer * r = SDL_CreateRenderer(w, -1, SDL_RENDERER_ACCELERATED);

SDL_Texture * s = NULL;
s = IMG_LoadTexture(r, "../test.bmp"); // LOADS A TEXTURE DIRECTLY FROM THE IMAGE
if (s == NULL)
{
cout << "FAILED TO FIND THE IMAGE" << endl; //we did this to check if IMG_LoadTexture found the image, if it showed this message in the cmd window (the black system-like one) then it means that the image can't be found
}
SDL_Rect s_rect; // CREATES THE IMAGE'S SPECS
s_rect.x = 100;    // just like the window, the x and y values determine it's displacement from the origin which is the top left of your window
s_rect.y = 100;
s_rect.w = 640; //width of the texture
s_rect.h = 480; // height of the texture

time = SDL_GetTicks(); //Gets the current time

while (time + 2000 < SDL_GetTicks()) //adds 2 seconds to the past time you got and waits for the present time to surpass that
{
SDL_RenderClear(r);
SDL_RenderCopy(r, s, NULL, &s_rect); // THE NULL IS THE AREA YOU COULD USE TO CROP THE IMAGE
SDL_RenderPresent(r);

}

SDL_DestroyTexture(s);
SDL_DestroyRenderer(r);
SDL_DestroyWindow(w);

return 0;   //returns 0, closes the program.
}

如果你想在窗口上看到一个关闭按钮并希望它生效然后创建一个事件然后将其添加到while区域以检查它是否等于SDL_Quit();我没有&#39 ; t包括它,因为你希望它在2秒内立即关闭,因此,使关闭按钮无效。

快乐编码:D

答案 1 :(得分:1)

SDL_RENDERER_SOFTWARE用于渲染器标记时,这有效。它也适用于不同的机器。猜猜我的配置肯定会出现问题,虽然我不确定它是什么,因为我仍然没有显示错误。好吧,标记为已解决。

答案 2 :(得分:0)

由于这行代码,我相信这是(不是100%肯定,但相当确定):

SDL_Renderer * r = SDL_CreateRenderer(w, -1, 0);

根据SDL wiki文章SDL_CreateRenderer,您传入的参数所需的参数如下:

  • SDL_Window * window
  • int index
  • Uint32 flags

您正确地传递了指向窗口的指针以及正确的索引,但缺少标志意味着SDL SDL应该使用默认渲染器。 对于应该使用渲染器的应用程序,大多数系统都有一个默认设置,这可以在应用程序的基础上进行修改。如果没有为特定应用程序提供默认设置,则渲染查找会立即检查默认渲染设置列表。 SDL wiki通过备注部分底部的以下行简要引用此列表:

“请注意,不提供标志会优先考虑可用的SDL_RENDERER_ACCELERATED渲染器。”

wiki中没有解释的是wiki引用的“渲染器”来自默认的渲染器列表。

这让我相信您已经在计算机历史记录的某个位置更改了设置,或者在Visual Studio设置中的其他位置更改了设置,导致找不到列表。因此,您必须明确告知SDL由于您的计算机设置而使用哪个渲染器。否则使用0的参数应该可以正常工作。最后这不会有害,因为最好在你的代码中明确而不是隐含,如果可能的话。

(也就是说,我所有的推论都是基于这样一个事实,即我假设你所说的一切都有效,工作。如果不是这样,那么问题可能是因为由于缺乏错误检查,原因各种各样。)