Как я могу создать Direct3d 11 рендерера, используя SDL 2.0.9 - PullRequest
0 голосов
/ 12 ноября 2018

В моем проекте я должен использовать SDL_BLENDOPERATION_MAXIMUM через SDL_ComposeCustomBlendMode(), который поддерживается в SDL 2.0.9 только для Direct3D11 рендерера. У меня Windows 8.1 и GeForce GTX750 Ti с обновленными драйверами. Моя система должна поддерживать рендеринг DirectX 11.

Изменение определений в SDL_config.h или SDL_config_windows.h (SDL_VIDEO_RENDER_D3D11 до 1 и SDL_VIDEO_RENDER_D3D до 0) не помогает. Я попытался заполнить различия препроцессора определениями SDL_VIDEO_RENDER_D3D11 или WINRT в соответствии с исходным кодом SDL. Но это не помогает.

Что я должен сделать, чтобы активировать 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 голосов
/ 13 ноября 2018

Обратите внимание, что вы устанавливаете SDL_VIDEO_RENDER_D3D, а друзья компилируют определения времени для построения SDL с поддержкой D3D.

Чтобы сделать это во время выполнения:

Через некоторое время после SDL_Init() и перед созданием окна / средства визуализации установите для него подсказку .

// 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

Я не могу представить, что вышеупомянутый блендер на самом деле комбинация факторов / операций, которые вы хотите, но вы не опубликовали свой действительный код для работы.

0 голосов
/ 12 ноября 2018
  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;
}
...