From b874151ca697386d74cfbd29e1c21bca1b4825e2 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Mon, 18 Jul 2022 11:52:02 +0300 Subject: [PATCH] gl: implement split screen --- src/game/renders/opengl/r_draw.pas | 63 +++++++++++++++++++--- src/game/renders/opengl/r_map.pas | 80 ++++++++++++++++++++-------- src/game/renders/opengl/r_render.pas | 35 +++++++----- 3 files changed, 137 insertions(+), 41 deletions(-) diff --git a/src/game/renders/opengl/r_draw.pas b/src/game/renders/opengl/r_draw.pas index b8b9021..2b42b48 100644 --- a/src/game/renders/opengl/r_draw.pas +++ b/src/game/renders/opengl/r_draw.pas @@ -30,12 +30,17 @@ interface procedure r_Draw_MultiTextureRepeatRotate (m: TGLMultiTexture; const anim: TAnimState; backanim: Boolean; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean; rx, ry, angle: Integer); procedure r_Draw_Filter (l, t, r, b: Integer; rr, gg, bb, aa: Byte); + procedure r_Draw_Rect (l, t, r, b: Integer; rr, gg, bb, aa: Byte); procedure r_Draw_FillRect (l, t, r, b: Integer; rr, gg, bb, aa: Byte); procedure r_Draw_InvertRect (l, t, r, b: Integer; rr, gg, bb, aa: Byte); procedure r_Draw_Text (const text: AnsiString; x, y: Integer; r, g, b, a: Byte; f: TGLFont); procedure r_Draw_GetTextSize (const text: AnsiString; f: TGLFont; out w, h: Integer); + procedure r_Draw_Setup (w, h: Integer); + procedure r_Draw_SetRect (l, t, r, b: Integer); + procedure r_Draw_GetRect (out l, t, r, b: Integer); + implementation uses @@ -45,8 +50,7 @@ implementation GL, GLEXT, {$ENDIF} SysUtils, Classes, Math, - e_log, utils, - g_game // gScreenWidth, gScreenHeight + e_log, utils ; const @@ -55,15 +59,24 @@ implementation NTB = $00; NTA = $FF; - procedure SetupMatrix; + var + sl, st, sr, sb: Integer; + ScreenWidth, ScreenHeight: Integer; + + procedure r_Draw_Setup (w, h: Integer); begin - glScissor(0, 0, gScreenWidth, gScreenHeight); - glViewport(0, 0, gScreenWidth, gScreenHeight); + ASSERT(w >= 0); + ASSERT(h >= 0); + ScreenWidth := w; + ScreenHeight := h; + glScissor(0, 0, w, h); + glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity; - glOrtho(0, gScreenWidth, gScreenHeight, 0, 0, 1); + glOrtho(0, w, h, 0, 0, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity; +// glTranslatef(0.5, 0.5, 0); end; procedure DrawQuad (x, y, w, h: Integer); @@ -221,6 +234,28 @@ implementation glEnd; end; + procedure r_Draw_Rect (l, t, r, b: Integer; rr, gg, bb, aa: Byte); + begin + ASSERT(r >= l); + ASSERT(b >= t); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_TEXTURE_2D); + glColor4ub(rr, gg, bb, aa); + glBegin(GL_LINE_LOOP); +{ + glVertex2i(l, t); + glVertex2i(r, t); + glVertex2i(r, b); + glVertex2i(l, b); +} + glVertex2f(l + 0.5, t + 0.5); + glVertex2f(r - 0.5, t + 0.5); + glVertex2f(r - 0.5, b - 0.5); + glVertex2f(l + 0.5, b - 0.5); + glEnd; + end; + procedure r_Draw_FillRect (l, t, r, b: Integer; rr, gg, bb, aa: Byte); begin ASSERT(r >= l); @@ -282,4 +317,20 @@ implementation end; end; + procedure r_Draw_SetRect (l, t, r, b: Integer); + var w, h: Integer; + begin + ASSERT(l <= r); + ASSERT(t <= b); + w := r - l + 1; + h := b - t + 1; + glScissor(l, ScreenHeight - h - t, w, h); + sl := l; st := t; sr := r; sb := b; + end; + + procedure r_Draw_GetRect (out l, t, r, b: Integer); + begin + l := sl; t := st; r := sr; b := sb; + end; + end. diff --git a/src/game/renders/opengl/r_map.pas b/src/game/renders/opengl/r_map.pas index 8737969..f010f29 100644 --- a/src/game/renders/opengl/r_map.pas +++ b/src/game/renders/opengl/r_map.pas @@ -55,6 +55,7 @@ implementation binheap, MAPDEF, utils, g_options, g_animations, g_basic, g_phys, g_game, g_map, g_panel, g_items, g_monsters, g_weapons, + g_console, {$IFDEF ENABLE_CORPSES} g_corpses, {$ENDIF} @@ -234,6 +235,7 @@ implementation TMonsterAnims = array [0..ANIM_LAST, TDirection] of TGLMultiTexture; var + DebugCameraScale: Single; SkyTexture: TGLTexture; RenTextures: array of record spec: LongInt; @@ -1264,34 +1266,44 @@ implementation end; procedure r_Map_Draw (x, y, w, h, camx, camy: Integer; player: TPlayer); - var iter: TPanelGrid.Iter; p: PPanel; cx, cy, xx, yy, ww, hh: Integer; sx, sy, sw, sh: LongInt; + var iter: TPanelGrid.Iter; p: PPanel; cx, cy, cw, ch, xx, yy, ww, hh: Integer; sx, sy, sw, sh: LongInt; l, t, r, b: Integer; begin - cx := camx - w div 2; - cy := camy - h div 2; - xx := x + cx; - yy := y + cy; - ww := w; - hh := h; + r_Draw_GetRect(l, t, r, b); + r_Draw_SetRect(x, y, x + w, y + h); + glTranslatef(x, y, 0); + (* camera rect *) + cx := (camx - w) + w div 2; + cy := (camy - h) + h div 2; + cw := w; + ch := h; + + (* camera bounds *) if g_dbg_ignore_bounds = false then begin - if xx + ww > gMapInfo.Width then - xx := gMapInfo.Width - ww; - if yy + hh > gMapInfo.Height then - yy := gMapInfo.Height - hh; - if xx < 0 then - xx := 0; - if yy < 0 then - yy := 0; - cx := xx - x; - cy := yy - y; + if cx + cw > gMapInfo.Width then + cx := gMapInfo.Width - cw; + if cy + ch > gMapInfo.Height then + cy := gMapInfo.Height - ch; + if cx < 0 then + cx := 0; + if cy < 0 then + cy := 0; end; - if SkyTexture <> nil then - begin - r_Map_CalcSkyParallax(cx, cy, ww, hh, SkyTexture.width, SkyTexture.height, gMapInfo.Width, gMapInfo.Height, sx, sy, sw, sh); - r_Draw_Texture(SkyTexture, x + sx, y + sy, sw, sh, false, 255, 255, 255, 255, false); - end; + (* map bounds *) + xx := cx; + yy := cy; + ww := cw; + hh := ch; + if xx + ww > gMapInfo.Width then + xx := gMapInfo.Width - ww; + if yy + hh > gMapInfo.Height then + yy := gMapInfo.Height - hh; + if xx < 0 then + xx := 0; + if yy < 0 then + yy := 0; plist.Clear; iter := mapGrid.ForEachInAABB(xx, yy, ww, hh, GridDrawableMask); @@ -1301,6 +1313,19 @@ implementation iter.Release; glPushMatrix; + if DebugCameraScale <> 1.0 then + begin + glTranslatef(cw div 2, ch div 2, 0); + glScalef(DebugCameraScale, DebugCameraScale, 1); + glTranslatef(-w div 2, -h div 2, 0); + end; + + if SkyTexture <> nil then + begin + r_Map_CalcSkyParallax(cx, cy, w, h, SkyTexture.width, SkyTexture.height, gMapInfo.Width, gMapInfo.Height, sx, sy, sw, sh); + r_Draw_Texture(SkyTexture, sx, sy, sw, sh, false, 255, 255, 255, 255, false); + end; + glTranslatef(-cx, -cy, 0); r_Map_DrawPanelType(PANEL_BACK); r_Map_DrawPanelType(PANEL_STEP); @@ -1332,12 +1357,20 @@ implementation // TODO draw monsters health bar // TODO draw players health bar // TODO draw players indicators + if DebugCameraScale <> 1.0 then + begin + r_Draw_Rect (cx, cy, cx + cw, cy + ch, 0, 255, 0, 255); + r_Draw_Rect (xx, yy, xx + ww, yy + hh, 255, 0, 0, 255); + end; glPopMatrix; r_Map_DrawScreenEffects(x, y, w, h, player); // TODO draw minimap (gShowMap) // TODO draw g_debug_player + + glTranslatef(-x, -y, 0); + r_Draw_SetRect(l, t, r, b); end; procedure r_Map_Update; @@ -1350,4 +1383,7 @@ implementation g_Anim_GetFrameByTime(FlagAnim, tick, count, FlagFrame); end; +initialization + conRegVar('r_debug_camera_scale', @DebugCameraScale, 0.0001, 1000.0, '', ''); + DebugCameraScale := 1.0; end. diff --git a/src/game/renders/opengl/r_render.pas b/src/game/renders/opengl/r_render.pas index 135141e..8b67f06 100644 --- a/src/game/renders/opengl/r_render.pas +++ b/src/game/renders/opengl/r_render.pas @@ -212,17 +212,6 @@ implementation r_Map_Update; end; - procedure SetupMatrix; - begin - glViewport(0, 0, gScreenWidth, gScreenHeight); - glScissor(0, 0, gScreenWidth, gScreenHeight); - glMatrixMode(GL_PROJECTION); - glLoadIdentity; - glOrtho(0, gScreenWidth, gScreenHeight, 0, 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity; - end; - procedure r_Render_GetBasePoint (x, y, w, h: Integer; p: TBasePoint; out xx, yy: Integer); begin case p of @@ -330,7 +319,11 @@ implementation end; procedure r_Render_DrawView (x, y, w, h: Integer; p: TPlayer); + var l, t, r, b: Integer; begin + r_Draw_GetRect(l, t, r, b); + r_Draw_SetRect(x, y, x + w, y + h); + if p <> nil then r_Map_Draw(x, y, w, h, p.obj.x + PLAYER_RECT_CX, p.obj.y + PLAYER_RECT_CY, p) else @@ -343,12 +336,18 @@ implementation if p.Spectator and p.NoRespawn then r_Render_DrawText(_lc[I_PLAYER_SPECT4], x div 2 + w div 2, y div 2 + h div 2, 255, 255, 255, 255, stdfont, TBasePoint.BP_CENTER); end; + + r_Draw_SetRect(l, t, r, b); end; procedure r_Render_DrawPlayerView (x, y, w, h: Integer; p: TPlayer); + var l, t, r, b: Integer; begin + r_Draw_GetRect(l, t, r, b); + r_Draw_SetRect(x, y, x + w, y + h); r_Render_DrawView(x, y, w - 196, h, p); r_Render_DrawHUDArea(x + w - 196, y, 196, h, p); + r_Draw_SetRect(l, t, r, b); end; procedure r_Render_Draw; @@ -356,12 +355,14 @@ implementation if gExit = EXIT_QUIT then exit; - SetupMatrix; + r_Draw_Setup(gScreenWidth, gScreenHeight); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); glColor4ub(255, 255, 255, 255); + glEnable(GL_SCISSOR_TEST); + r_Draw_SetRect(0, 0, gScreenWidth, gScreenHeight); //e_LogWritefln('r_render_draw: %sx%s', [gScreenWidth, gScreenHeight]); @@ -373,7 +374,15 @@ implementation // TODO setup player view siz // TODO draw player view + setup screen coords - r_Render_DrawPlayerView(0, 0, gScreenWidth, gScreenHeight, gPlayer1); + if (gPlayer1 <> nil) and (gPlayer2 <> nil) then + begin + r_Render_DrawPlayerView(0, 0, gScreenWidth, gScreenHeight div 2 - 2, gPlayer1); + r_Render_DrawPlayerView(0, gScreenHeight div 2 + 2, gScreenWidth, gScreenHeight div 2, gPlayer2); + end + else + begin + r_Render_DrawPlayerView(0, 0, gScreenWidth, gScreenHeight, gPlayer1); + end; // TODO draw holmes inspector -- 2.29.2