ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c – 仅当使用SDL_RENDERER_SOFTWARE创建渲染器时,SDL2程序才有效

2019-09-28 03:05:27  阅读:199  来源: 互联网

标签:sdl-2 c sdl


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

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

如果使用SDL_RENDERER_SOFTWARE标志创建渲染器,则该程序可以正常工作.

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

我找不到任何失败的SDL呼叫.

我想知道纹理格式和渲染器之间是否存在某些不兼容性 – 但我不确定如何跟进它.

任何帮助或建议?

我的环境是:

> Windows 10
> Visual Studio社区2015
> SDL2版本2.0.4

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

其他信息和源代码:

我添加了减少的源代码来演示下面的问题.

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

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

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

但是当我按下按键时,而不是在红色和蓝色方块之间轻弹的窗口,我正在看一个黑色的窗口.

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

#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并希望最好:)

标签:sdl-2,c,sdl
来源: https://codeday.me/bug/20190928/1825607.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有