DEADSOFTWARE

gl: colorize and blend textures
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Wed, 8 Jun 2022 12:53:28 +0000 (15:53 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Fri, 9 Jun 2023 08:40:20 +0000 (11:40 +0300)
src/game/renders/opengl/r_draw.pas
src/game/renders/opengl/r_map.pas

index 379080004e5c0a2f5f68711ee12eba48bc6b3546..212043e93e25f730476450fa3e274ec26f392b1d 100644 (file)
@@ -22,11 +22,11 @@ interface
     r_textures
   ;
 
-  procedure r_Draw_Texture (img: TGLTexture; x, y, w, h: Integer; flip: Boolean);
-  procedure r_Draw_TextureRepeat (img: TGLTexture; x, y, w, h: Integer; flip: Boolean);
+  procedure r_Draw_Texture (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
+  procedure r_Draw_TextureRepeat (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
 
-  procedure r_Draw_MultiTextureRepeat (m: TGLMultiTexture; const a: TAnimState; x, y, w, h: Integer; flip: Boolean);
-  procedure r_Draw_MultiTextureRepeatRotate (img: TGLMultiTexture; const anim: TAnimState; x, y, w, h: Integer; flip: Boolean; rx, ry, a: Integer);
+  procedure r_Draw_MultiTextureRepeat (m: TGLMultiTexture; const anim: TAnimState; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
+  procedure r_Draw_MultiTextureRepeatRotate (m: TGLMultiTexture; const anim: TAnimState; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; rx, ry, angle: Integer; blend: Boolean);
 
   procedure r_Draw_Filter (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
 
@@ -43,6 +43,12 @@ implementation
     g_game // gScreenWidth, gScreenHeight
   ;
 
+  const
+    NTR = $FF;
+    NTG = $00;
+    NTB = $00;
+    NTA = $FF;
+
   procedure SetupMatrix;
   begin
     glScissor(0, 0, gScreenWidth, gScreenHeight);
@@ -64,15 +70,15 @@ implementation
     glEnd();
   end;
 
-  procedure DrawTile (tile: TGLAtlasNode; x, y, w, h: Integer; flip: Boolean);
+  procedure DrawTile (tile: TGLAtlasNode; x, y, w, h: Integer; flip: Boolean; rr, gg, bb, aa: Byte; blend: Boolean);
     var nw, nh, ax, bx, ay, by: GLfloat; l, t, r, b: Integer;
   begin
     if tile = nil then
     begin
-      glColor3ub(255, 0, 0);
-      glDisable(GL_BLEND);
-      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+      glColor4ub(rr, gg, bb, aa);
+      if blend then glBlendFunc(GL_SRC_ALPHA, GL_ONE) else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
       glDisable(GL_TEXTURE_2D);
+      glEnable(GL_BLEND);
       DrawQuad(x, y, w, h);
     end
     else
@@ -84,11 +90,11 @@ implementation
       ay := (tile.t) / nw;
       by := (tile.b + 1) / nh;
       l := x; t := y; r := x + w; b := y + h;
-      glColor3ub(255, 255, 255);
       glBindTexture(GL_TEXTURE_2D, tile.id);
+      glColor4ub(rr, gg, bb, aa);
+      if blend then glBlendFunc(GL_SRC_ALPHA, GL_ONE) else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
       glEnable(GL_TEXTURE_2D);
       glEnable(GL_BLEND);
-      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
       glBegin(GL_QUADS);
         glTexCoord2f(ax, ay); glVertex2i(r, t);
         glTexCoord2f(bx, ay); glVertex2i(l, t);
@@ -100,43 +106,13 @@ implementation
     end
   end;
 
-(*
-  procedure r_Draw_Texture (img: TGLTexture; x, y, w, h: Integer; flip: Boolean);
-    var i, j, offx, offy, nw, nh: Integer; n: TGLAtlasNode;
-  begin
-    ASSERT(w >= 0);
-    ASSERT(h >= 0);
-    if img = nil then
-      DrawTile(nil, x, y, w, h, flip)
-    else
-    begin
-      offx := 0;
-      offy := 0;
-      nw := w div img.cols;
-      nh := h div img.lines;
-      for j := 0 to img.lines - 1 do
-      begin
-        for i := 0 to img.cols - 1 do
-        begin
-          n := img.GetTile(i, j);
-          ASSERT(n <> nil);
-          DrawTile(n, x + offx, y + offy, nw, nh, flip);
-          offx := offx + nw;
-        end;
-        offx := 0;
-        offy := offy + nh;
-      end
-    end
-  end;
-*)
-
-  procedure r_Draw_Texture (img: TGLTexture; x, y, w, h: Integer; flip: Boolean);
+  procedure r_Draw_Texture (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
     var i, j, offx, offy: Integer; n: TGLAtlasNode;
   begin
     ASSERT(w >= 0);
     ASSERT(h >= 0);
     if img = nil then
-      DrawTile(nil, x, y, w, h, flip)
+      DrawTile(nil, x, y, w, h, flip, NTR, NTB, NTG, NTA, blend)
     else
     begin
       glPushMatrix;
@@ -149,7 +125,7 @@ implementation
         begin
           n := img.GetTile(i, j);
           ASSERT(n <> nil);
-          DrawTile(n, x + offx, y + offy, n.width, n.height, flip);
+          DrawTile(n, x + offx, y + offy, n.width, n.height, flip, r, g, b, a, blend);
           offx := offx + n.width;
         end;
         offx := 0;
@@ -159,41 +135,41 @@ implementation
     end
   end;
 
-  procedure r_Draw_TextureRepeat (img: TGLTexture; x, y, w, h: Integer; flip: Boolean);
+  procedure r_Draw_TextureRepeat (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
     var i, j: Integer;
   begin
     ASSERT(w >= 0);
     ASSERT(h >= 0);
     if img = nil then
-      r_Draw_Texture(nil, x, y, w, h, flip)
+      r_Draw_Texture(nil, x, y, w, h, flip, NTR, NTG, NTB, NTB, blend)
     else
       for j := 0 to h div img.height - 1 do
         for i := 0 to w div img.width - 1 do
-          r_Draw_Texture(img, x + i * img.width, y + j * img.height, img.width, img.height, flip);
+          r_Draw_Texture(img, x + i * img.width, y + j * img.height, img.width, img.height, flip, r, g, b, a, blend);
   end;
 
-  procedure r_Draw_MultiTextureRepeat (m: TGLMultiTexture; const a: TAnimState; x, y, w, h: Integer; flip: Boolean);
+  procedure r_Draw_MultiTextureRepeat (m: TGLMultiTexture; const anim: TAnimState; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
     var img: TGLTexture; cur, total, i: Integer;
   begin
-    ASSERT(a.IsValid());
+    ASSERT(anim.IsValid());
     if m = nil then
-      r_Draw_TextureRepeat(nil, x, y, w, h, flip)
+      r_Draw_TextureRepeat(nil, x, y, w, h, flip, NTR, NTG, NTB, NTB, blend)
     else
     begin
       if m.BackAnim then
       begin
         total := m.count * 2 - 1;
-        cur := a.CurrentFrame mod total;
+        cur := anim.CurrentFrame mod total;
         if cur < m.count then i := cur else i := total - cur - 1;
       end
       else
-        i := a.CurrentFrame mod m.count;
+        i := anim.CurrentFrame mod m.count;
       img := m.GetTexture(i);
-      r_Draw_TextureRepeat(img, x, y, w, h, flip)
+      r_Draw_TextureRepeat(img, x, y, w, h, flip, r, g, b, a, blend);
     end
   end;
 
-  procedure r_Draw_MultiTextureRepeatRotate (img: TGLMultiTexture; const anim: TAnimState; x, y, w, h: Integer; flip: Boolean; rx, ry, a: Integer);
+  procedure r_Draw_MultiTextureRepeatRotate (m: TGLMultiTexture; const anim: TAnimState; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; rx, ry, angle: Integer; blend: Boolean);
     var i, j: Integer;
   begin
     ASSERT(w >= 0);
@@ -202,13 +178,13 @@ implementation
     begin
       glPushMatrix;
       glTranslatef(x + rx, y + ry, 0);
-      glRotatef(a, 0, 0, 1);
+      glRotatef(angle, 0, 0, 1);
       glTranslatef(-(x + rx), -(y + ry), 0);
-      r_Draw_MultiTextureRepeat(img, anim, x, y, w, h, flip);
+      r_Draw_MultiTextureRepeat(m, anim, x, y, w, h, flip, r, g, b, a, blend);
       glPopMatrix;
     end
     else
-      r_Draw_MultiTextureRepeat(img, anim, x, y, w, h, flip);
+      r_Draw_MultiTextureRepeat(m, anim, x, y, w, h, flip, r, g, b, a, blend);
   end;
 
   procedure r_Draw_Filter (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
index 0588f0da35ed92c1b2bbda5f26b9b1fe85dce29f..fda70fed811fde5d7096b62b620067ae4672c5ab 100644 (file)
@@ -486,13 +486,12 @@ implementation
 
       if (RenTextures[Texture].spec = 0) or (t <> nil) then
       begin
-        // TODO set alpha and blending type
         if t = nil then
-          r_Draw_TextureRepeat(nil, p.x, p.y, p.width, p.height, false)
+          r_Draw_TextureRepeat(nil, p.x, p.y, p.width, p.height, false, 255, 255, 255, 255 - p.alpha, p.blending)
         else if p.TextureIDs[p.FCurTexture].AnTex.IsValid() then
-          r_Draw_MultiTextureRepeat(t, p.TextureIDs[p.FCurTexture].AnTex, p.x, p.y, p.width, p.height, false)
+          r_Draw_MultiTextureRepeat(t, p.TextureIDs[p.FCurTexture].AnTex, p.x, p.y, p.width, p.height, false, 255, 255, 255, 255 - p.alpha, p.blending)
         else
-          r_Draw_TextureRepeat(t.GetTexture(0), p.x, p.y, p.width, p.height, false)
+          r_Draw_TextureRepeat(t.GetTexture(0), p.x, p.y, p.width, p.height, false, 255, 255, 255, 255 - p.alpha, p.blending)
       end;
 
       if t = nil then
@@ -536,7 +535,7 @@ implementation
           if g_Collide(it.obj.x, it.obj.y, t.width, t.height, x, y, w, h) then
           begin
             it.obj.Lerp(gLerpFactor, fX, fY);
-            r_Draw_MultiTextureRepeat(t, Items[it.ItemType].anim, fX, fY, t.width, t.height, false);
+            r_Draw_MultiTextureRepeat(t, Items[it.ItemType].anim, fX, fY, t.width, t.height, false, 255, 255, 255, 255, false);
             // if g_debug_frames then // TODO draw collision frame
           end;
         end;
@@ -583,7 +582,7 @@ implementation
     if VileFire <> nil then
       if (mon.MonsterType = MONSTER_VILE) and (mon.MonsterState = MONSTATE_SHOOT) then
         if mon.VileFireAnim.IsValid() and GetPos(mon.MonsterTargetUID, @o) then
-          r_Draw_MultiTextureRepeat(VileFire, mon.VileFireAnim, o.x + o.rect.x + (o.rect.width div 2) - VILEFIRE_DX, o.y + o.rect.y + o.rect.height - VILEFIRE_DY, VileFire.width, VileFire.height, False);
+          r_Draw_MultiTextureRepeat(VileFire, mon.VileFireAnim, o.x + o.rect.x + (o.rect.width div 2) - VILEFIRE_DX, o.y + o.rect.y + o.rect.height - VILEFIRE_DY, VileFire.width, VileFire.height, False, 255, 255, 255, 255, false);
   end;
 
   procedure r_Map_DrawMonster (constref mon: TMonster);
@@ -596,7 +595,7 @@ implementation
     mon.obj.Lerp(gLerpFactor, fX, fY);
 
     if r_Map_GetMonsterTexture(m, a, d, t, dx, dy, flip) then
-      r_Draw_MultiTextureRepeat(t, mon.DirAnim[a, d], fX + dx, fY + dy, t.width, t.height, flip);
+      r_Draw_MultiTextureRepeat(t, mon.DirAnim[a, d], fX + dx, fY + dy, t.width, t.height, flip, 255, 255, 255, 255, false);
 
 {
     if g_debug_frames
@@ -636,7 +635,7 @@ implementation
   end;
 
   procedure r_Map_DrawPlayerModel (pm: TPlayerModel; x, y: Integer);
-    var a, pos, act, xx, yy: Integer; d: TDirection; flip: Boolean; t: TGLMultiTexture; tex: TGLTexture;
+    var a, pos, act, xx, yy: Integer; d: TDirection; flip: Boolean; t: TGLMultiTexture; tex: TGLTexture; c: TRGB;
   begin
     a := pm.CurrentAnimation;
     d := pm.Direction;
@@ -663,18 +662,21 @@ implementation
           y + yy,
           tex.width,
           tex.height,
-          d = TDirection.D_LEFT
+          d = TDirection.D_LEFT,
+          255, 255, 255, 255, false
         );
       end;
     end;
     if r_Map_GetPlayerModelTex(pm.id, a, d, flip) then
     begin
       t := Models[pm.id].anim[d, a].base;
-      r_Draw_MultiTextureRepeat(t, pm.AnimState, x, y, t.width, t.height, flip);
-      // TODO colorize mask
+      r_Draw_MultiTextureRepeat(t, pm.AnimState, x, y, t.width, t.height, flip, 255, 255, 255, 255, false);
       t := Models[pm.id].anim[d, a].mask;
       if t <> nil then
-        r_Draw_MultiTextureRepeat(t, pm.AnimState, x, y, t.width, t.height, flip);
+      begin
+        c := pm.Color;
+        r_Draw_MultiTextureRepeat(t, pm.AnimState, x, y, t.width, t.height, flip, c.r, c.g, c.b, 255, false);
+      end;
     end;
   end;
 
@@ -842,8 +844,7 @@ implementation
           begin
             fx := nlerp(gfxlist[i].oldX, gfxlist[i].x, gLerpFactor);
             fy := nlerp(gfxlist[i].oldY, gfxlist[i].y, gLerpFactor);
-            // TODO set GFXAnim[typ].alpha
-            r_Draw_MultiTextureRepeat(tex, gfxlist[i].anim, fx, fy, tex.width, tex.height, false);
+            r_Draw_MultiTextureRepeat(tex, gfxlist[i].anim, fx, fy, tex.width, tex.height, false, 255, 255, 255, 255 - GFXAnim[typ].alpha, false);
           end;
         end;
       end;
@@ -874,7 +875,7 @@ implementation
             pY := Shots[i].Obj.Rect.Height div 2;
             // TODO fix this hack
             if Shots[i].Animation.IsValid() then anim := @Shots[i].Animation else anim := @StubShotAnim;
-            r_Draw_MultiTextureRepeatRotate(tex, anim^, fX, fY, tex.width, tex.height, false, pX, pY, a);
+            r_Draw_MultiTextureRepeatRotate(tex, anim^, fX, fY, tex.width, tex.height, false, 255, 255, 255, 255, pX, pY, a, false);
           end;
         end;
       end;
@@ -892,7 +893,7 @@ implementation
     hh := h;
 
     if SkyTexture <> nil then
-      r_Draw_Texture(SkyTexture, x, y, w, h, false);
+      r_Draw_Texture(SkyTexture, x, y, w, h, false, 255, 255, 255, 255, false);
 
     plist.Clear;
     iter := mapGrid.ForEachInAABB(xx, yy, ww, hh, GridDrawableMask);