如何使用SDL 2.0.9创建Direct3d 11渲染器

时间:2018-11-12 19:41:13

标签: sdl-2

在我的项目中,我必须通过SDL_BLENDOPERATION_MAXIMUM使用SDL_ComposeCustomBlendMode(),仅在Direct3d11渲染器的SDL 2.0.9中支持。我有Windows 8.1和带有更新驱动程序的GeForce GTX750 Ti。我的系统应支持DirectX 11渲染。

更改SDL_config.hSDL_config_windows.h中的定义(SDL_VIDEO_RENDER_D3D11为1,SDL_VIDEO_RENDER_D3D为0)无济于事。 我试图根据SDL源代码用定义SDL_VIDEO_RENDER_D3D11或WINRT来填充预处理程序定义。但这无济于事。

我应该怎么做才能激活Direct3d11渲染器,以便可以使用混合模式最大值?

我的测试代码:

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

using namespace std;

int main( int argc, char *argv[] ) {
    SDL_Init( SDL_INIT_VIDEO );
    IMG_Init( IMG_INIT_PNG );
    SDL_SetHintWithPriority( SDL_HINT_RENDER_DRIVER, "direct3d11", SDL_HINT_OVERRIDE );
    SDL_Window *window = SDL_CreateWindow( "Testing", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                                             1200, 600, SDL_WINDOW_RESIZABLE );
    SDL_Renderer *renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED );
    SDL_RendererInfo *rendererInfo = new SDL_RendererInfo();
    SDL_RendererInfo *driverInfo = new SDL_RendererInfo();
    SDL_GetRendererInfo( renderer, rendererInfo );
    int drivers = SDL_GetNumRenderDrivers();
    string availableDrivers = " (";
    for ( int i = 0; i < drivers; ++i ) {
        SDL_GetRenderDriverInfo( i, driverInfo );
        string driverName = driverInfo->name;
        if ( i == drivers - 1 ) {
            availableDrivers += driverName;
        }
        else {
            availableDrivers += driverName + ", ";
        }
    }
    availableDrivers += ")";
    string path = SDL_GetBasePath();
    SDL_Surface *surfRed = IMG_Load( (path + "\\Red.png").c_str() );
    SDL_Texture *textRed = SDL_CreateTextureFromSurface( renderer, surfRed );
    SDL_FreeSurface( surfRed );
    SDL_Surface *surfBlue = IMG_Load( ( path + "\\Blue.png" ).c_str() );
    SDL_Texture *textBlue = SDL_CreateTextureFromSurface( renderer, surfBlue );
    SDL_FreeSurface( surfBlue );
    SDL_Rect destRed, destBlue;
    destRed.x = 128;
    destRed.y = 128;
    destBlue.x = 196;
    destBlue.y = 196;
    SDL_QueryTexture( textRed, NULL, NULL, &destRed.w, &destRed.h );
    SDL_QueryTexture( textBlue, NULL, NULL, &destBlue.w, &destBlue.h );
    SDL_BlendMode blendMode = SDL_ComposeCustomBlendMode( SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_MAXIMUM,
        SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_MAXIMUM );         
    SDL_SetTextureBlendMode( textRed, blendMode );
    SDL_SetTextureBlendMode( textBlue, blendMode );
//  SDL_SetRenderDrawBlendMode( renderer, blendMode );
    string info = rendererInfo->name + availableDrivers + " " + SDL_GetError();
    SDL_SetWindowTitle( window, info.c_str() );
    SDL_SetRenderDrawColor( renderer, 0, 0, 0, 255 );
    SDL_Event event;
    bool isRunning = true;
    while ( isRunning ) {
        if ( SDL_PollEvent( &event ) ) {
            if ( event.type == SDL_QUIT ) {
                isRunning = false;
            }
        }
        SDL_RenderClear( renderer );
        SDL_RenderCopy( renderer, textRed, NULL, &destRed );
        SDL_RenderCopy( renderer, textBlue, NULL, &destBlue );
        SDL_RenderPresent( renderer );
    }
    delete driverInfo;
    delete rendererInfo;
    SDL_DestroyTexture( textRed );
    SDL_DestroyTexture( textBlue );
    SDL_DestroyRenderer( renderer );
    SDL_DestroyWindow( window );
    IMG_Quit();
    SDL_Quit();
    return 0;
}

窗口标题为“ direct3d(direct3d,opengl,opengles2,软件)。不支持此操作”。当我更改为SDL_BLENDOPERATION_ADD时,它可以正常工作,但这不是我想要的。如果我取消注释渲染器混合模式,也无济于事。

2 个答案:

答案 0 :(得分:1)

  1. 通过SDL_GetNumRenderDrivers()SDL_GetRenderDriverInfo()枚举受支持的渲染器后端。
  2. 请注意direct3d11驱动程序的索引(如果存在)。
  3. 将索引传递到SDL_CreateRenderer()

一起:

SDL_Init( SDL_INIT_VIDEO );
SDL_Window* window = SDL_CreateWindow( "SDL2", 0, 0, 640, 480, SDL_WINDOW_SHOWN );

SDL_Renderer* renderer = nullptr;
for( int i = 0; i < SDL_GetNumRenderDrivers(); ++i )
{
    SDL_RendererInfo rendererInfo = {};
    SDL_GetRenderDriverInfo( i, &rendererInfo );
    if( rendererInfo.name != std::string( "direct3d11" ) )
    {
        continue;
    }

    renderer = SDL_CreateRenderer( window, i, 0 );
    break;
}

答案 1 :(得分:0)

请注意,您为SDL_VIDEO_RENDER_D3D和朋友设置的内容是 compile 时间定义,用于使用D3D支持构建SDL。

要在运行时执行此操作:

SDL_Init()之后到创建窗口/渲染器之前的某个时间,请设置hint for it

// returns true on success or false on failure
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "direct3d11");

但是,这仅适用于Windows,我相信d3d已经是Windows的默认渲染器。如果您的Windows版本支持d3d11,则应使用SDL 我强烈怀疑您已经拥有d3d11渲染器,而您的问题在于如何实例化或使用自定义混合模式。

要验证您是否拥有d3d11渲染器:

SDL_RendererInfo info;
SDL_GetRendererInfo(renderer, &info);
printf("%s", info.name);

使用SDL_BLENDOPERATION_MAXIMUM创建自定义混合模式

SDL_BlendMode blender = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA, // change this to suit your needs
                                                   SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, // change this to suit your needs
                                                   SDL_BLENDOPERATION_MAXIMUM,
                                                   SDL_BLENDFACTOR_ONE, // change this to suit your needs
                                                   SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, // change this to suit your needs
                                                   SDL_BLENDOPERATION_MAXIMUM);

SDL_SetTextureBlendMode(texture, blender); // blender is your custom mode
SDL_SetRenderDrawBlendMode(renderer, blender); // blender is your custom mode

我无法想象上面的搅拌器实际上是您想要的因素/操作的组合,但是您并没有发布实际的代码来解决问题。