From 5f9e5c63eb04e2fdfee780157e8586a6071a9470 Mon Sep 17 00:00:00 2001 From: Cong Date: Thu, 8 Feb 2018 01:15:00 +1100 Subject: [PATCH] Fix editor build (#500) Don't move window when resizing Fix background texture rendering Note: editor redraw still broken --- src/cdogs/camera.c | 4 --- src/cdogs/grafx.c | 40 ++++++++++++++++++++++-------- src/cdogs/grafx.h | 2 ++ src/cdogs/grafx_bg.c | 51 ++++++++++++++++++++++++++++++-------- src/cdogs/window_context.c | 31 ++++++++++++++--------- src/cdogs/window_context.h | 5 ++-- src/cdogsed/cdogsed.c | 10 +++----- 7 files changed, 97 insertions(+), 46 deletions(-) diff --git a/src/cdogs/camera.c b/src/cdogs/camera.c index 4c1621473..52463e78b 100644 --- a/src/cdogs/camera.c +++ b/src/cdogs/camera.c @@ -43,10 +43,6 @@ void CameraInit(Camera *camera) memset(camera, 0, sizeof *camera); DrawBufferInit( &camera->Buffer, svec2i(X_TILES, Y_TILES), &gGraphicsDevice); - if (SDL_SetRenderTarget(gGraphicsDevice.gameWindow.renderer, NULL) != 0) - { - LOG(LM_MAIN, LL_ERROR, "cannot set render target: %s", SDL_GetError()); - } camera->lastPosition = svec2_zero(); HUDInit(&camera->HUD, &gGraphicsDevice, &gMission); camera->shake = ScreenShakeZero(); diff --git a/src/cdogs/grafx.c b/src/cdogs/grafx.c index 76da2b60a..1a5246a16 100644 --- a/src/cdogs/grafx.c +++ b/src/cdogs/grafx.c @@ -209,21 +209,25 @@ void GraphicsInitialize(GraphicsDevice *g) if (initRenderer) { - Uint32 sdlFlags = SDL_WINDOW_RESIZABLE; + Uint32 windowFlags = SDL_WINDOW_RESIZABLE; if (g->cachedConfig.Fullscreen) { - sdlFlags |= SDL_WINDOW_FULLSCREEN; + windowFlags |= SDL_WINDOW_FULLSCREEN; } LOG(LM_GFX, LL_INFO, "graphics mode(%dx%d %dx)", w, h, g->cachedConfig.ScaleFactor); - // Get the previous window's size and recreate it - struct vec2i windowSize = svec2i( - w * g->cachedConfig.ScaleFactor, h * g->cachedConfig.ScaleFactor); + // Get the previous window's dimensions and recreate it + Rect2i windowDim = Rect2iNew( + svec2i(SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED), + svec2i_scale(svec2i(w, h), (float)g->cachedConfig.ScaleFactor) + ); if (g->gameWindow.window) { + SDL_GetWindowPosition( + g->gameWindow.window, &windowDim.Pos.x, &windowDim.Pos.y); SDL_GetWindowSize( - g->gameWindow.window, &windowSize.x, &windowSize.y); + g->gameWindow.window, &windowDim.Size.x, &windowDim.Size.y); } LOG(LM_GFX, LL_DEBUG, "destroying previous renderer"); WindowContextDestroy(&g->gameWindow); @@ -235,7 +239,7 @@ void GraphicsInitialize(GraphicsDevice *g) g->cachedConfig.IsEditor ? "Editor " : "", CDOGS_SDL_VERSION); if (!WindowContextCreate( - &g->gameWindow, windowSize, sdlFlags, title, g->icon, + &g->gameWindow, windowDim, windowFlags, title, g->icon, svec2i(w, h))) { return; @@ -243,7 +247,7 @@ void GraphicsInitialize(GraphicsDevice *g) if (g->cachedConfig.SecondWindow) { if (!WindowContextCreate( - &g->secondWindow, windowSize, sdlFlags, title, g->icon, + &g->secondWindow, windowDim, windowFlags, title, g->icon, svec2i(w, h))) { return; @@ -288,18 +292,32 @@ void GraphicsInitialize(GraphicsDevice *g) CFREE(g->buf); CCALLOC(g->buf, GraphicsGetMemSize(&g->cachedConfig)); + g->bkgTgt = WindowContextCreateTexture( + &g->gameWindow, SDL_TEXTUREACCESS_TARGET, svec2i(w, h), + SDL_BLENDMODE_NONE, 255, true); + if (g->bkgTgt == NULL) + { + return; + } g->bkg = WindowContextCreateTexture( &g->gameWindow, SDL_TEXTUREACCESS_STATIC, svec2i(w, h), - SDL_BLENDMODE_NONE, 255, true); + SDL_BLENDMODE_BLEND, 255, true); if (g->bkg == NULL) { return; } if (g->cachedConfig.SecondWindow) { - g->bkg2 = WindowContextCreateTexture( - &g->secondWindow, SDL_TEXTUREACCESS_STATIC, svec2i(w, h), + g->bkgTgt2 = WindowContextCreateTexture( + &g->gameWindow, SDL_TEXTUREACCESS_TARGET, svec2i(w, h), SDL_BLENDMODE_NONE, 255, true); + if (g->bkgTgt2 == NULL) + { + return; + } + g->bkg2 = WindowContextCreateTexture( + &g->secondWindow, SDL_TEXTUREACCESS_TARGET, svec2i(w, h), + SDL_BLENDMODE_BLEND, 255, true); if (g->bkg2 == NULL) { return; diff --git a/src/cdogs/grafx.h b/src/cdogs/grafx.h index 2595650cc..c40542916 100644 --- a/src/cdogs/grafx.h +++ b/src/cdogs/grafx.h @@ -102,6 +102,8 @@ typedef struct Uint32 *buf; SDL_Texture *bkg; SDL_Texture *bkg2; + SDL_Texture *bkgTgt; + SDL_Texture *bkgTgt2; SDL_Texture *brightnessOverlay; } GraphicsDevice; diff --git a/src/cdogs/grafx_bg.c b/src/cdogs/grafx_bg.c index 6a2142087..6c0ad1605 100644 --- a/src/cdogs/grafx_bg.c +++ b/src/cdogs/grafx_bg.c @@ -37,8 +37,10 @@ #include "objs.h" #include "pickup.h" #include "quick_play.h" +#include "texture.h" #include "triggers.h" + void GrafxMakeRandomBackground( GraphicsDevice *device, CampaignOptions *co, struct MissionOptions *mo, Map *map) @@ -59,38 +61,60 @@ void GrafxMakeRandomBackground( } static void DrawBackground( - GraphicsDevice *g, SDL_Texture *t, DrawBuffer *buffer, Map *map, - const HSV tint, const struct vec2 pos, GrafxDrawExtra *extra); + GraphicsDevice *g, SDL_Texture *tTgt, SDL_Texture *t, DrawBuffer *buffer, + Map *map, const HSV tint, const struct vec2 pos, GrafxDrawExtra *extra); void GrafxDrawBackground( GraphicsDevice *g, DrawBuffer *buffer, const HSV tint, const struct vec2 pos, GrafxDrawExtra *extra) { - if (SDL_SetRenderTarget(g->gameWindow.renderer, g->bkg) != 0) + SDL_RendererInfo ri; + if (SDL_GetRendererInfo(g->gameWindow.renderer, &ri) != 0) { - LOG(LM_MAIN, LL_ERROR, "cannot set render target: %s", SDL_GetError()); + LOG(LM_GFX, LL_ERROR, "cannot set render target: %s", SDL_GetError()); + } + else + { + if (!(ri.flags & SDL_RENDERER_TARGETTEXTURE)) + { + LOG(LM_GFX, LL_ERROR, + "renderer does not support render to texture"); + } + } + if (SDL_SetRenderTarget(g->gameWindow.renderer, g->bkgTgt) != 0) + { + LOG(LM_GFX, LL_ERROR, "cannot set render target: %s", SDL_GetError()); } if (g->cachedConfig.SecondWindow) { - if (SDL_SetRenderTarget(g->gameWindow.renderer, g->bkg2) != 0) + if (SDL_SetRenderTarget(g->secondWindow.renderer, g->bkgTgt2) != 0) { - LOG(LM_MAIN, LL_ERROR, "cannot set render target: %s", + LOG(LM_GFX, LL_ERROR, "cannot set render target: %s", SDL_GetError()); } DrawBackground( - g, g->bkg, buffer, &gMap, tint, + g, g->bkgTgt, g->bkg, buffer, &gMap, tint, svec2(pos.x - g->cachedConfig.Res.x / 2, pos.y), extra); DrawBackground( - g, g->bkg2, buffer, &gMap, tint, + g, g->bkgTgt2, g->bkg2, buffer, &gMap, tint, svec2(pos.x + g->cachedConfig.Res.x / 2, pos.y), extra); + if (SDL_SetRenderTarget(g->secondWindow.renderer, NULL) != 0) + { + LOG(LM_GFX, LL_ERROR, "cannot set render target: %s", + SDL_GetError()); + } } else { - DrawBackground(g, g->bkg, buffer, &gMap, tint, pos, extra); + DrawBackground(g, g->bkgTgt, g->bkg, buffer, &gMap, tint, pos, extra); + } + if (SDL_SetRenderTarget(g->gameWindow.renderer, NULL) != 0) + { + LOG(LM_GFX, LL_ERROR, "cannot set render target: %s", SDL_GetError()); } } static void DrawBackground( - GraphicsDevice *g, SDL_Texture *t, DrawBuffer *buffer, Map *map, - const HSV tint, const struct vec2 pos, GrafxDrawExtra *extra) + GraphicsDevice *g, SDL_Texture *tTgt, SDL_Texture *t, DrawBuffer *buffer, + Map *map, const HSV tint, const struct vec2 pos, GrafxDrawExtra *extra) { DrawBufferSetFromMap(buffer, map, pos, X_TILES); DrawBufferDraw(buffer, svec2i_zero(), extra); @@ -102,6 +126,11 @@ static void DrawBackground( LOG(LM_GFX, LL_ERROR, "cannot set background tint: %s", SDL_GetError()); } + if (SDL_SetTextureColorMod(tTgt, mask.r, mask.g, mask.b) != 0) + { + LOG(LM_GFX, LL_ERROR, "cannot set background tint: %s", + SDL_GetError()); + } } void GrafxRedrawBackground(GraphicsDevice *g, const struct vec2 pos) diff --git a/src/cdogs/window_context.c b/src/cdogs/window_context.c index 43cf4cc6f..2392428fc 100644 --- a/src/cdogs/window_context.c +++ b/src/cdogs/window_context.c @@ -30,25 +30,32 @@ bool WindowContextCreate( - WindowContext *wc, const struct vec2i windowSize, const int sdlFlags, - const char *title, SDL_Surface *icon, const struct vec2i rendererLogicalSize) + WindowContext *wc, const Rect2i windowDim, const int windowFlags, + const char *title, SDL_Surface *icon, + const struct vec2i rendererLogicalSize) { CArrayInit(&wc->texturesBkg, sizeof(SDL_Texture *)); CArrayInit(&wc->textures, sizeof(SDL_Texture *)); - LOG(LM_GFX, LL_DEBUG, "creating window %dx%d flags(%X)", - windowSize.x, windowSize.y, sdlFlags); - if (SDL_CreateWindowAndRenderer( - windowSize.x, windowSize.y, sdlFlags, - &wc->window, &wc->renderer) == -1 || - wc->window == NULL || wc->renderer == NULL) + LOG(LM_GFX, LL_DEBUG, "creating window (%d, %d) %dx%d flags(%X)", + windowDim.Pos.x, windowDim.Pos.y, windowDim.Size.x, windowDim.Size.y, + windowFlags); + wc->window = SDL_CreateWindow( + title, windowDim.Pos.x, windowDim.Pos.y, + windowDim.Size.x, windowDim.Size.y, windowFlags); + if (wc->window == NULL) { - LOG(LM_GFX, LL_ERROR, "cannot create window or renderer: %s", - SDL_GetError()); + LOG(LM_GFX, LL_ERROR, "cannot create window: %s", SDL_GetError()); + return false; + } + wc->renderer = SDL_CreateRenderer( + wc->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); + if (wc->renderer == NULL) + { + LOG(LM_GFX, LL_ERROR, "cannot create renderer: %s", SDL_GetError()); return false; } - LOG(LM_GFX, LL_DEBUG, "setting title(%s) and icon", title); - SDL_SetWindowTitle(wc->window, title); + LOG(LM_GFX, LL_DEBUG, "setting icon"); SDL_SetWindowIcon(wc->window, icon); if (SDL_RenderSetLogicalSize( diff --git a/src/cdogs/window_context.h b/src/cdogs/window_context.h index b377df055..34bc18850 100644 --- a/src/cdogs/window_context.h +++ b/src/cdogs/window_context.h @@ -40,8 +40,9 @@ typedef struct } WindowContext; bool WindowContextCreate( - WindowContext *wc, const struct vec2i windowSize, const int sdlFlags, - const char *title, SDL_Surface *icon, const struct vec2i rendererLogicalSize); + WindowContext *wc, const Rect2i windowDim, const int windowFlags, + const char *title, SDL_Surface *icon, + const struct vec2i rendererLogicalSize); void WindowContextDestroy(WindowContext *wc); void WindowContextDestroyTextures(WindowContext *wc); diff --git a/src/cdogsed/cdogsed.c b/src/cdogsed/cdogsed.c index 50195644c..dd8f5c22c 100644 --- a/src/cdogsed/cdogsed.c +++ b/src/cdogsed/cdogsed.c @@ -151,14 +151,13 @@ static void MakeBackground(const bool changedMission) } // Clear background first - memset(ec.g->buf, 0, GraphicsGetMemSize(&ec.g->cachedConfig)); + BlitClearBuf(ec.g); GrafxDrawExtra extra; extra.guideImage = brush.GuideImageSurface; extra.guideImageAlpha = brush.GuideImageAlpha; DrawBufferTerminate(&sDrawBuffer); - DrawBufferInit( - &sDrawBuffer, svec2i(X_TILES, Y_TILES), &gGraphicsDevice, true); + DrawBufferInit(&sDrawBuffer, svec2i(X_TILES, Y_TILES), &gGraphicsDevice); GrafxMakeBackground( ec.g, &sDrawBuffer, &gCampaign, &gMission, &gMap, tintNone, true, ec.camera, &extra); @@ -191,7 +190,7 @@ static void Display(HandleInputResult result) if (result.RemakeBg || brush.IsGuideImageNew) { // Clear background first - memset(ec.g->buf, 0, GraphicsGetMemSize(&ec.g->cachedConfig)); + BlitClearBuf(ec.g); brush.IsGuideImageNew = false; GrafxDrawExtra extra; extra.guideImage = brush.GuideImageSurface; @@ -1378,8 +1377,7 @@ int main(int argc, char *argv[]) // Note: must do this after text init since positions depend on text height sObjs = CreateMainObjs(&gCampaign, &brush, svec2i(320, 240)); memset(&sDrawObjs, 0, sizeof sDrawObjs); - DrawBufferInit( - &sDrawBuffer, svec2i(X_TILES, Y_TILES), &gGraphicsDevice, true); + DrawBufferInit(&sDrawBuffer, svec2i(X_TILES, Y_TILES), &gGraphicsDevice); // Reset campaign (graphics init may have created dummy campaigns) CampaignSettingTerminate(&gCampaign.Setting);