DEADSOFTWARE

render: separate map logic and drawing
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Mon, 7 Jun 2021 18:30:05 +0000 (21:30 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Tue, 29 Jun 2021 09:51:11 +0000 (12:51 +0300)
src/game/Doom2DF.lpr
src/game/g_map.pas
src/game/opengl/r_game.pas
src/game/opengl/r_map.pas [new file with mode: 0644]

index bec1c219b15a4f119489624e4609290ce3b708c6..05b5025776403adb1c14e97012033480cf76d4aa 100644 (file)
@@ -157,6 +157,7 @@ uses
   r_game in 'opengl/r_game.pas',
   r_gfx in 'opengl/r_gfx.pas',
   r_items in 'opengl/r_items.pas',
+  r_map in 'opengl/r_map.pas',
 
 {$IFDEF USE_FMOD}
   fmod in '../lib/FMOD/fmod.pas',
index 20bfa3bf1bee93ff29bc5471cb86a60cf214941a..92ce86baa347358063dd0affc4388b7a6b51437f 100644 (file)
@@ -65,10 +65,6 @@ procedure g_Map_Update();
 
 function g_Map_PanelByGUID (aguid: Integer): TPanel; inline;
 
-procedure g_Map_DrawPanels (PanelType: Word; hasAmbient: Boolean; constref ambColor: TDFColor); // unaccelerated
-procedure g_Map_CollectDrawPanels (x0, y0, wdt, hgt: Integer);
-
-procedure g_Map_DrawBack(dx, dy: Integer);
 function  g_Map_CollidePanel(X, Y: Integer; Width, Height: Word;
                              PanelType: Word; b1x3: Boolean=false): Boolean;
 function  g_Map_CollideLiquid_Texture(X, Y: Integer; Width, Height: Word): DWORD;
@@ -94,13 +90,10 @@ function  g_Map_GetRandomPointType(): Byte;
 function  g_Map_HaveFlagPoints(): Boolean;
 
 procedure g_Map_ResetFlag(Flag: Byte);
-procedure g_Map_DrawFlags();
 
 procedure g_Map_SaveState (st: TStream);
 procedure g_Map_LoadState (st: TStream);
 
-procedure g_Map_DrawPanelShadowVolumes(lightX: Integer; lightY: Integer; radius: Integer);
-
 // returns panel or nil
 // sets `ex` and `ey` to `x1` and `y1` when no hit was detected
 function g_Map_traceToNearestWall (x0, y0, x1, y1: Integer; hitx: PInteger=nil; hity: PInteger=nil): TPanel;
@@ -530,12 +523,6 @@ begin
   result := (a.arrIdx < b.arrIdx);
 end;
 
-procedure dplClear ();
-begin
-  if (gDrawPanelList = nil) then gDrawPanelList := TBinHeapPanelDraw.Create() else gDrawPanelList.clear();
-end;
-
-
 var
   Textures: TLevelTextureArray = nil;
   TextNameHash: THashStrInt = nil; // key: texture name; value: index in `Textures`
@@ -2624,71 +2611,6 @@ begin
   end;
 end;
 
-
-// old algo
-procedure g_Map_DrawPanels (PanelType: Word; hasAmbient: Boolean; constref ambColor: TDFColor);
-
-  procedure DrawPanels (constref panels: TPanelArray; drawDoors: Boolean=False);
-  var
-    idx: Integer;
-  begin
-    if (panels <> nil) then
-    begin
-      // alas, no visible set
-      for idx := 0 to High(panels) do
-      begin
-        if not (drawDoors xor panels[idx].Door) then panels[idx].Draw(hasAmbient, ambColor);
-      end;
-    end;
-  end;
-
-begin
-  case PanelType of
-    PANEL_WALL:       DrawPanels(gWalls);
-    PANEL_CLOSEDOOR:  DrawPanels(gWalls, True);
-    PANEL_BACK:       DrawPanels(gRenderBackgrounds);
-    PANEL_FORE:       DrawPanels(gRenderForegrounds);
-    PANEL_WATER:      DrawPanels(gWater);
-    PANEL_ACID1:      DrawPanels(gAcid1);
-    PANEL_ACID2:      DrawPanels(gAcid2);
-    PANEL_STEP:       DrawPanels(gSteps);
-  end;
-end;
-
-
-// new algo
-procedure g_Map_CollectDrawPanels (x0, y0, wdt, hgt: Integer);
-var
-  mwit: PPanel;
-  it: TPanelGrid.Iter;
-begin
-  dplClear();
-  it := mapGrid.forEachInAABB(x0, y0, wdt, hgt, GridDrawableMask);
-  for mwit in it do if (((mwit^.tag and GridTagDoor) <> 0) = mwit^.Door) then gDrawPanelList.insert(mwit^);
-  it.release();
-  // list will be rendered in `g_game.DrawPlayer()`
-end;
-
-
-procedure g_Map_DrawPanelShadowVolumes (lightX: Integer; lightY: Integer; radius: Integer);
-var
-  mwit: PPanel;
-  it: TPanelGrid.Iter;
-begin
-  it := mapGrid.forEachInAABB(lightX-radius, lightY-radius, radius*2, radius*2, (GridTagWall or GridTagDoor));
-  for mwit in it do mwit^.DrawShadowVolume(lightX, lightY, radius);
-  it.release();
-end;
-
-
-procedure g_Map_DrawBack(dx, dy: Integer);
-begin
-  if gDrawBackGround and (BackID <> DWORD(-1)) then
-    e_DrawSize(BackID, dx, dy, 0, False, False, gBackSize.X, gBackSize.Y)
-  else
-    e_Clear(GL_COLOR_BUFFER_BIT, 0, 0, 0);
-end;
-
 function g_Map_CollidePanelOld(X, Y: Integer; Width, Height: Word;
                             PanelType: Word; b1x3: Boolean=false): Boolean;
 var
@@ -3157,46 +3079,6 @@ begin
   end;
 end;
 
-procedure g_Map_DrawFlags();
-var
-  i, dx: Integer;
-  Mirror: TMirrorType;
-begin
-  if gGameSettings.GameMode <> GM_CTF then
-    Exit;
-
-  for i := FLAG_RED to FLAG_BLUE do
-    with gFlags[i] do
-      if State <> FLAG_STATE_CAPTURED then
-      begin
-        if State = FLAG_STATE_NONE then
-          continue;
-
-        if Direction = TDirection.D_LEFT then
-          begin
-            Mirror := TMirrorType.Horizontal;
-            dx := -1;
-          end
-        else
-          begin
-            Mirror := TMirrorType.None;
-            dx := 1;
-          end;
-
-        Animation.Draw(Obj.X+dx, Obj.Y+1, Mirror);
-
-        if g_debug_Frames then
-        begin
-          e_DrawQuad(Obj.X+Obj.Rect.X,
-                     Obj.Y+Obj.Rect.Y,
-                     Obj.X+Obj.Rect.X+Obj.Rect.Width-1,
-                     Obj.Y+Obj.Rect.Y+Obj.Rect.Height-1,
-                     0, 255, 0);
-        end;
-      end;
-end;
-
-
 procedure g_Map_SaveState (st: TStream);
 var
   str: String;
index aa13e6bccfd4af398f3d86c32d779ea0a19b9d00..0d623dd29481b56f03311aef5873ef3b61b2474d 100644 (file)
@@ -32,7 +32,7 @@ implementation
     g_textures, e_input, e_sound,
     g_language, g_console, g_menu, g_triggers, g_player, g_options, g_monsters, g_map, g_panel, g_window,
     g_items, g_weapons, g_gfx, g_phys, g_net, g_gui, g_netmaster,
-    g_game, r_console, r_gfx, r_items
+    g_game, r_console, r_gfx, r_items, r_map
   ;
 
   var
@@ -1106,7 +1106,7 @@ begin
     glDisable(GL_TEXTURE_2D);
     glDisable(GL_BLEND);
     glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // no need to modify color buffer
-    if (lrad > 4) then g_Map_DrawPanelShadowVolumes(lx, ly, lrad);
+    if (lrad > 4) then r_Map_DrawPanelShadowVolumes(lx, ly, lrad);
     // render light texture
     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // modify color buffer
     glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); // draw light, and clear stencil buffer
@@ -1186,7 +1186,7 @@ var
     end
     else
     begin
-      if doDraw then g_Map_DrawPanels(panType, hasAmbient, ambColor);
+      if doDraw then r_Map_DrawPanels(panType, hasAmbient, ambColor);
     end;
     if (profileFrameDraw <> nil) then profileFrameDraw.sectionEnd();
   end;
@@ -1206,12 +1206,12 @@ begin
   if (profileFrameDraw <> nil) then profileFrameDraw.sectionBegin('collect');
   if gdbg_map_use_accel_render then
   begin
-    g_Map_CollectDrawPanels(sX, sY, sWidth, sHeight);
+    r_Map_CollectDrawPanels(sX, sY, sWidth, sHeight);
   end;
   if (profileFrameDraw <> nil) then profileFrameDraw.sectionEnd();
 
   if (profileFrameDraw <> nil) then profileFrameDraw.sectionBegin('skyback');
-  g_Map_DrawBack(backXOfs, backYOfs);
+  r_Map_DrawBack(backXOfs, backYOfs);
   if (profileFrameDraw <> nil) then profileFrameDraw.sectionEnd();
 
   if setTransMatrix then
@@ -1248,7 +1248,7 @@ begin
   drawOther('itemdrop', @r_Items_DrawDrop);
   drawPanelType('*door', PANEL_CLOSEDOOR, g_rlayer_door);
   drawOther('gfx', @r_GFX_Draw);
-  drawOther('flags', @g_Map_DrawFlags);
+  drawOther('flags', @r_Map_DrawFlags);
   drawPanelType('*acid1', PANEL_ACID1, g_rlayer_acid1);
   drawPanelType('*acid2', PANEL_ACID2, g_rlayer_acid2);
   drawPanelType('*water', PANEL_WATER, g_rlayer_water);
@@ -1304,7 +1304,7 @@ begin
   if (p = nil) or (p.FDummy) then
   begin
     glPushMatrix();
-    g_Map_DrawBack(0, 0);
+    r_Map_DrawBack(0, 0);
     glPopMatrix();
     Exit;
   end;
diff --git a/src/game/opengl/r_map.pas b/src/game/opengl/r_map.pas
new file mode 100644 (file)
index 0000000..eb50ad9
--- /dev/null
@@ -0,0 +1,143 @@
+(* Copyright (C)  Doom 2D: Forever Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License ONLY.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *)
+{$INCLUDE ../../shared/a_modes.inc}
+unit r_map;
+
+interface
+
+  uses MAPDEF; // TDFColor
+
+  procedure r_Map_DrawBack (dx, dy: Integer);
+  procedure r_Map_DrawPanels (PanelType: Word; hasAmbient: Boolean; constref ambColor: TDFColor); // unaccelerated
+  procedure r_Map_CollectDrawPanels (x0, y0, wdt, hgt: Integer);
+  procedure r_Map_DrawPanelShadowVolumes (lightX: Integer; lightY: Integer; radius: Integer);
+  procedure r_Map_DrawFlags;
+
+implementation
+
+  uses
+    {$INCLUDE ../nogl/noGLuses.inc}
+    SysUtils, Classes, Math,
+    e_graphics,
+    g_basic, g_game, g_options,
+    g_panel, g_map
+  ;
+
+procedure dplClear ();
+begin
+  if (gDrawPanelList = nil) then gDrawPanelList := TBinHeapPanelDraw.Create() else gDrawPanelList.clear();
+end;
+
+// old algo
+procedure r_Map_DrawPanels (PanelType: Word; hasAmbient: Boolean; constref ambColor: TDFColor);
+
+  procedure DrawPanels (constref panels: TPanelArray; drawDoors: Boolean=False);
+  var
+    idx: Integer;
+  begin
+    if (panels <> nil) then
+    begin
+      // alas, no visible set
+      for idx := 0 to High(panels) do
+      begin
+        if not (drawDoors xor panels[idx].Door) then panels[idx].Draw(hasAmbient, ambColor);
+      end;
+    end;
+  end;
+
+begin
+  case PanelType of
+    PANEL_WALL:       DrawPanels(gWalls);
+    PANEL_CLOSEDOOR:  DrawPanels(gWalls, True);
+    PANEL_BACK:       DrawPanels(gRenderBackgrounds);
+    PANEL_FORE:       DrawPanels(gRenderForegrounds);
+    PANEL_WATER:      DrawPanels(gWater);
+    PANEL_ACID1:      DrawPanels(gAcid1);
+    PANEL_ACID2:      DrawPanels(gAcid2);
+    PANEL_STEP:       DrawPanels(gSteps);
+  end;
+end;
+
+// new algo
+procedure r_Map_CollectDrawPanels (x0, y0, wdt, hgt: Integer);
+var
+  mwit: PPanel;
+  it: TPanelGrid.Iter;
+begin
+  dplClear();
+  it := mapGrid.forEachInAABB(x0, y0, wdt, hgt, GridDrawableMask);
+  for mwit in it do if (((mwit^.tag and GridTagDoor) <> 0) = mwit^.Door) then gDrawPanelList.insert(mwit^);
+  it.release();
+  // list will be rendered in `g_game.DrawPlayer()`
+end;
+
+procedure r_Map_DrawPanelShadowVolumes (lightX: Integer; lightY: Integer; radius: Integer);
+var
+  mwit: PPanel;
+  it: TPanelGrid.Iter;
+begin
+  it := mapGrid.forEachInAABB(lightX-radius, lightY-radius, radius*2, radius*2, (GridTagWall or GridTagDoor));
+  for mwit in it do mwit^.DrawShadowVolume(lightX, lightY, radius);
+  it.release();
+end;
+
+procedure r_Map_DrawBack(dx, dy: Integer);
+begin
+  if gDrawBackGround and (BackID <> DWORD(-1)) then
+    e_DrawSize(BackID, dx, dy, 0, False, False, gBackSize.X, gBackSize.Y)
+  else
+    e_Clear(GL_COLOR_BUFFER_BIT, 0, 0, 0);
+end;
+
+procedure r_Map_DrawFlags();
+var
+  i, dx: Integer;
+  Mirror: TMirrorType;
+begin
+  if gGameSettings.GameMode <> GM_CTF then
+    Exit;
+
+  for i := FLAG_RED to FLAG_BLUE do
+    with gFlags[i] do
+      if State <> FLAG_STATE_CAPTURED then
+      begin
+        if State = FLAG_STATE_NONE then
+          continue;
+
+        if Direction = TDirection.D_LEFT then
+          begin
+            Mirror := TMirrorType.Horizontal;
+            dx := -1;
+          end
+        else
+          begin
+            Mirror := TMirrorType.None;
+            dx := 1;
+          end;
+
+        Animation.Draw(Obj.X+dx, Obj.Y+1, Mirror);
+
+        if g_debug_Frames then
+        begin
+          e_DrawQuad(Obj.X+Obj.Rect.X,
+                     Obj.Y+Obj.Rect.Y,
+                     Obj.X+Obj.Rect.X+Obj.Rect.Width-1,
+                     Obj.Y+Obj.Rect.Y+Obj.Rect.Height-1,
+                     0, 255, 0);
+        end;
+      end;
+end;
+
+end.