gpt4 book ai didi

c++ - SDL2 程序仅在使用 SDL_RENDERER_SOFTWARE 创建渲染器时才有效

转载 作者:太空宇宙 更新时间:2023-11-04 16:03:49 26 4
gpt4 key购买 nike

我使用 C++ 和 SDL2 编写了一个程序:

  1. 创建一个窗口
  2. 获取窗口的表面
  3. 为窗口创建渲染器
  4. 在窗口上渲染一些填充的矩形
  5. 从窗口的表面创建一个纹理
  6. 清除屏幕
  7. 在窗口上渲染一些实心圆
  8. 从窗口的表面创建第二个纹理
  9. 进入一个事件循环,每次按下一个键时:
  10. 如果当前正在显示圆形,则使用 SDL_RenderCopy() 将正方形纹理复制到窗口。
  11. 否则,如果当前正在显示正方形,则将圆形纹理复制到窗口。

如果渲染器是使用 SDL_RENDERER_SOFTWARE 标志创建的,该程序将完美运行。

如果渲染器是使用 SDL_RENDERER_ACCELERATED 标志创建的,我发现虽然我可以直接渲染到屏幕,但如果我从窗口表面创建几个不同的纹理然后尝试复制它们使用 SDL_RenderCopy() 回到窗口;我只看到一个黑色的窗口。

我找不到任何失败的 SDL 调用。

我想知道纹理格式和渲染器之间是否可能存在一些不兼容 - 但我不确定如何跟进。

有什么帮助或建议吗?

我的环境是:

  • Windows 10
  • 2015 年 Visual Studio 社区
  • SDL2 版本 2.0.4

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

附加信息和源代码:

我添加了简化的源代码来演示下面的问题。

请注意,为了减小大小,我删除了所有错误检查并将相关代码合并到一个主函数中。

我得到的是,如果我取消注释第 40 行,那么程序会按预期工作,以便我使用 SDL_RENDERER_SOFTWARE 标志调用 SDL_CreateRenderer

如果我取消注释任何其他 SDL_CreateRenderer 行(第 41-43 行:使用硬件加速),我会在最初呈现到屏幕时看到红色和蓝色方 block 。

但是当我按键时,我看到的不是窗口在红色和蓝色方 block 之间闪烁,而是黑色窗口。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#include <SDL.h>
#include <SDL_image.h>
#include <stdio.h>
#include <string>


//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;


int main(int argc, char* args[])
{

//The window we'll be rendering to
SDL_Window* gWindow = NULL;

//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;

//And two textures, one for a red square, on for a blue square
SDL_Texture* texture_red = NULL;
SDL_Texture* texture_blue = NULL;

//The window renderer
SDL_Renderer* gRenderer = NULL;


//Initialize SDL
SDL_Init(SDL_INIT_VIDEO);

//Create window
gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);

//Get the screen surface
gScreenSurface = SDL_GetWindowSurface(gWindow);


//Create renderer for window
gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_SOFTWARE);
//gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED);
//gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_PRESENTVSYNC);
//gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);

/*###########################################################################################
# I can not figure out how to make this program work with hardware acceleration. It works #
# fine when I define the renderer using SDL_RENDERER_SOFTWARE, but doesn't display anything #
# if I define the renerer using the SDL_RENDERER_ACCELERATED flag #
###########################################################################################*/

//Initialize renderer color
SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF);


//Clear screen
SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(gRenderer);

//Render red filled quad
SDL_Rect fillRect = { 100, 75, 100, 100 };
SDL_SetRenderDrawColor(gRenderer, 0xFF, 0x00, 0x00, 0xFF);
SDL_RenderFillRect(gRenderer, &fillRect);

//Update the rendered image on screen
SDL_RenderPresent(gRenderer);

//Pause long enough to see it
SDL_Delay(200);

//Create texture_red texture from the screen surface
texture_red = SDL_CreateTextureFromSurface(gRenderer, gScreenSurface);


//Clear screen
SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(gRenderer);

//Render blue filled quad
fillRect = { 225, 250, 100, 100 };
SDL_SetRenderDrawColor(gRenderer, 0x00, 0x00, 0xFF, 0xFF);
SDL_RenderFillRect(gRenderer, &fillRect);

//Update the rendered image on screen
SDL_RenderPresent(gRenderer);

//Pause long enough to see it
SDL_Delay(200);

//Create texture_red texture from the screen surface
texture_blue = SDL_CreateTextureFromSurface(gRenderer, gScreenSurface);


//Main loop flag
bool quit = false;

//Flag to keep track of which colour we're currently looking at
bool blue = true;

//Event handler
SDL_Event e;

//While application is running
while (!quit)
{
//Handle events on queue
while (SDL_PollEvent(&e) != 0)
{
//User requests quit
if (e.type == SDL_QUIT)
{
quit = true;
}
//User presses a key
else if (e.type == SDL_KEYDOWN)
{
//Select surfaces based on key press
switch (e.key.keysym.sym)
{

case SDLK_ESCAPE:
quit = true;
break;

default:
if (blue)
{
//Copy surface used to store red image onto the screen surface
SDL_RenderCopy(gRenderer, texture_red, NULL, NULL);

//Update current colour flag
blue = false;
}
else
{

//Copy surface used to store blue image onto the screen surface
SDL_RenderCopy(gRenderer, texture_blue, NULL, NULL);

//Update current colour flag
blue = true;
}

//Update the screen with recent render activity
SDL_RenderPresent(gRenderer);

break;
}
}
}
}


//Deallocate surfaces
SDL_FreeSurface(gScreenSurface);

//Destroy window
SDL_DestroyWindow(gWindow);
gWindow = NULL;

//Quit SDL subsystems
SDL_Quit();

return 0;
}

最佳答案

SDL_GetWindowSurface() header comment特别禁止将其与 SDL_Renderer 功能一起使用:

/**
* \brief Get the SDL surface associated with the window.
*
* \return The window's framebuffer surface, or NULL on error.
*
* A new surface will be created with the optimal format for the window,
* if necessary. This surface will be freed when the window is destroyed.
*
* \note You may not combine this with 3D or the rendering API on this window.
*
* \sa SDL_UpdateWindowSurface()
* \sa SDL_UpdateWindowSurfaceRects()
*/
extern DECLSPEC SDL_Surface * SDLCALL SDL_GetWindowSurface(SDL_Window * window);

使用SDL_RENDERER_TARGETTEXTURE & SDL_SetRenderTarget()如果您想捕获 SDL_Renderer 输出。

您可以使用 SDL_GetRendererInfo()查询兼容的纹理格式。或者直接使用 SDL_PIXELFORMAT_ARGB8888 like testrendertarget.c does并希望最好的:)

关于c++ - SDL2 程序仅在使用 SDL_RENDERER_SOFTWARE 创建渲染器时才有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38813605/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com