SDL2-Programm funktioniert nur, wenn Renderer mit SDL_RENDERER_SOFTWARE erstellt wurde
Ich habe ein Programm mit C ++ und SDL2 geschrieben, das:
Erstellt ein Fensterget die Oberfläche des Fensters Erstellt einen Renderer für das Fensterrendert einige gefüllte Rechtecke auf das Fenster Erstellt eine Textur von der Fensteroberfläche löscht den Bildschirmrendert einige gefüllte Kreise auf das Fenster Erstellt eine zweite Textur von der Fensteroberflächeruft eine Ereignisschleife auf, in der bei jedem Tastendruck Folgendes ausgeführt wird:wenn gerade Kreise angezeigt werden, wird SDL_RenderCopy () verwendet, um die Textur der Quadrate in das Fenster zu kopieren.wenn gerade Quadrate angezeigt werden, wird die Kreisstruktur in das Fenster kopiert.Das Programm funktioniert einwandfrei, wenn der Renderer mit dem @ erstellt wiSDL_RENDERER_SOFTWARE
Flagge
Wenn der Renderer mit dem @ erstellt wiSDL_RENDERER_ACCELERATED
flag finde ich, dass ich zwar direkt auf dem Bildschirm rendern kann, wenn ich jedoch ein paar verschiedene Texturen aus der Fensteroberfläche erstelle und dann versuche, sie mit @ wieder in das Fenster zu kopiereSDL_RenderCopy()
; Ich sehe nur ein schwarzes Fenster.
Ich kann keine fehlgeschlagenen SDL-Aufrufe finden.
Ich habe mich gefragt, ob es eine Inkompatibilität zwischen dem Texturformat und dem Renderer geben könnte - aber ich bin mir nicht sicher, wie ich dem nachgehen soll.
Hilfe oder Vorschläge?
Meine Umgebung ist:
Windows 10Visual Studio Community 2015 SDL2 Version 2.0.4~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Zusätzliche Informationen und Quellcode:
Ich habe den Quellcode gekürzt, um das Problem unten zu demonstrieren.
Hinweis, um die Größe zu verringern, habe ich alle Fehlerprüfungen entfernt und den entsprechenden Code in einer einzigen Hauptfunktion zusammengefasst.
Was ich bekomme ist, dass das Programm für mich wie erwartet funktioniert, wenn ich Zeile 40 auskommentiere, so dass ich @ anruSDL_CreateRenderer
mit demSDL_RENDERER_SOFTWARE
Flagge
Wenn ich einen der anderen @ auskommentieSDL_CreateRenderer
Zeilen stattdessen (Zeile 41-43: Hardware-Beschleunigung verwenden), sehe ich die roten und blauen Quadrate, wenn sie anfänglich auf dem Bildschirm gerendert werden.
Aber während ich die Tasten drücke, sehe ich, anstatt das Fenster zwischen roten und blauen Quadraten zu wechseln, ein schwarzes Fenster.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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;
}