DEADSOFTWARE

gl: fix invalid color cache
[d2df-sdl.git] / src / game / renders / opengl / r_draw.pas
index cd0c58fb3e5c2aace4d792c3e52d4ba1fae8ed88..c839936087a0754aa00405d235b32c67087422a3 100644 (file)
@@ -41,6 +41,9 @@ interface
   procedure r_Draw_SetRect (l, t, r, b: Integer);
   procedure r_Draw_GetRect (out l, t, r, b: Integer);
 
+  procedure r_Draw_EnableTexture2D (enable: Boolean);
+  procedure r_Draw_SetColor (r, g, b, a: Byte);
+
 implementation
 
   uses
@@ -63,6 +66,30 @@ implementation
     sl, st, sr, sb: Integer;
     ScreenWidth, ScreenHeight: Integer;
 
+    enableTexture2D: Boolean;
+    curR, curG, curB, curA: Byte;
+
+  procedure r_Draw_EnableTexture2D (enable: Boolean);
+  begin
+    if enable <> enableTexture2D then
+    begin
+      if enable then glEnable(GL_TEXTURE_2D) else glDisable(GL_TEXTURE_2D);
+      enableTexture2D := enable;
+    end;
+  end;
+
+  procedure r_Draw_SetColor (r, g, b, a: Byte);
+  begin
+    if (r <> curR) or (g <> curG) or (b <> curB) or (curA <> a) then
+    begin
+      glColor4ub(r, g, b, a);
+      curR := r;
+      curG := g;
+      curB := b;
+      curA := a;
+    end;
+  end;
+
   procedure r_Draw_Setup (w, h: Integer);
   begin
     ASSERT(w >= 0);
@@ -76,7 +103,8 @@ implementation
     glOrtho(0, w, h, 0, 0, 1);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity;
-//    glTranslatef(0.5, 0.5, 0);
+    glEnable(GL_SCISSOR_TEST);
+    r_Draw_SetRect(0, 0, w - 1, h - 1);
   end;
 
   procedure DrawQuad (x, y, w, h: Integer);
@@ -94,9 +122,9 @@ implementation
   begin
     if tile = nil then
     begin
-      glColor4ub(rr, gg, bb, aa);
+      r_Draw_SetColor(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);
+      r_Draw_EnableTexture2D(false);
       glEnable(GL_BLEND);
       DrawQuad(x, y, w, h);
     end
@@ -109,10 +137,10 @@ implementation
       ay := (tile.t) / nw;
       by := (tile.b + 1) / nh;
       l := x; t := y; r := x + w; b := y + h;
-      glBindTexture(GL_TEXTURE_2D, tile.id);
-      glColor4ub(rr, gg, bb, aa);
+      r_Textures_GL_Bind(tile.id);
+      r_Draw_SetColor(rr, gg, bb, aa);
+      r_Draw_EnableTexture2D(true);
       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);
       glBegin(GL_QUADS);
         glTexCoord2f(ax, ay); glVertex2i(r, t);
@@ -120,13 +148,32 @@ implementation
         glTexCoord2f(bx, by); glVertex2i(l, b);
         glTexCoord2f(ax, by); glVertex2i(r, b);
       glEnd();
-      glDisable(GL_TEXTURE_2D);
-      glBindTexture(GL_TEXTURE_2D, 0);
     end
   end;
 
+  procedure DrawHWTexture (gltex: GLint; nw, nh, x, y, w, h: Integer; flip: Boolean; rr, gg, bb, aa: Byte; blend: Boolean);
+    var ax, bx, ay, by: GLfloat; l, t, r, b: Integer;
+  begin
+    ax := IfThen(flip, 0, w) / nw;
+    bx := IfThen(flip, w, 0) / nh;
+    ay := 0 / nw;
+    by := h / nh;
+    l := x; t := y; r := x + w; b := y + h;
+    r_Textures_GL_Bind(gltex);
+    r_Draw_SetColor(rr, gg, bb, aa);
+    r_Draw_EnableTexture2D(true);
+    if blend then glBlendFunc(GL_SRC_ALPHA, GL_ONE) else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    glEnable(GL_BLEND);
+    glBegin(GL_QUADS);
+      glTexCoord2f(ax, ay); glVertex2i(r, t);
+      glTexCoord2f(bx, ay); glVertex2i(l, t);
+      glTexCoord2f(bx, by); glVertex2i(l, b);
+      glTexCoord2f(ax, by); glVertex2i(r, b);
+    glEnd();
+  end;
+
   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;
+    var i, j, first, last, step: Integer; n: TGLAtlasNode;
   begin
     ASSERT(w >= 0);
     ASSERT(h >= 0);
@@ -134,27 +181,44 @@ implementation
       DrawTile(nil, x, y, w, h, flip, NTR, NTB, NTG, NTA, blend)
     else
     begin
-      offx := 0;
-      offy := 0;
+      if flip then first := img.cols - 1 else first := 0;
+      if flip then last  := -1           else last  := img.cols;
+      if flip then step  := -1           else step  := +1;
+      glPushMatrix;
+      glTranslatef(x, y, 0);
+      glScalef(w / img.width, h / img.height, 1);
       for j := 0 to img.lines - 1 do
       begin
-        for i := 0 to img.cols - 1 do
-        begin
+        i := first;
+        repeat
           n := img.GetTile(i, j);
           ASSERT(n <> nil);
-          glPushMatrix;
-          glTranslatef(x + offx, y + offy, 0);
-          glScalef(w / img.width, h / img.height, 1);
           DrawTile(n, 0, 0, n.width, n.height, flip, r, g, b, a, blend);
-          glPopMatrix;
-          offx := offx + n.width;
-        end;
-        offx := 0;
-        offy := offy + n.height;
+          glTranslatef(n.width, 0, 0);
+          i := i + step;
+        until i = last;
+        glTranslatef(-img.width, n.height, 0);
       end;
+      glPopMatrix;
     end
   end;
 
+  function r_Draw_IsHWRepeatable (img: TGLTexture): Boolean;
+    var n: TGLAtlasNode; a: TGLAtlas;
+  begin
+    ASSERT(img <> nil);
+    result := false;
+    if (img.cols = 1) and (img.lines = 1) then
+    begin
+      n := img.GetTile(0, 0);
+      if (n.width = img.width) and (n.height = img.height) then
+      begin
+        a := n.base;
+        result := (a.GetWidth() = img.width) and (a.GetHeight() = img.height)
+      end;
+    end;
+  end;
+
   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
@@ -162,6 +226,8 @@ implementation
     ASSERT(h >= 0);
     if img = nil then
       r_Draw_Texture(nil, x, y, w, h, flip, NTR, NTG, NTB, NTB, blend)
+    else if r_Draw_IsHWRepeatable(img) then
+      DrawHWTexture(img.GetTile(0, 0).base.id, img.width, img.height, x, y, w, h, flip, r, g, b, a, blend)
     else
       for j := 0 to (h - 1) div img.height do
         for i := 0 to (w - 1) div img.width do
@@ -224,8 +290,8 @@ implementation
     ASSERT(b >= t);
     glEnable(GL_BLEND);
     glBlendFunc(GL_ZERO, GL_SRC_COLOR);
-    glDisable(GL_TEXTURE_2D);
-    glColor4ub(rr, gg, bb, aa);
+    r_Draw_EnableTexture2D(false);
+    r_Draw_SetColor(rr, gg, bb, aa);
     glBegin(GL_QUADS);
       glVertex2i(l, t);
       glVertex2i(r, t);
@@ -240,8 +306,8 @@ implementation
     ASSERT(b >= t);
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-    glDisable(GL_TEXTURE_2D);
-    glColor4ub(rr, gg, bb, aa);
+    r_Draw_EnableTexture2D(false);
+    r_Draw_SetColor(rr, gg, bb, aa);
     glBegin(GL_LINE_LOOP);
 {
       glVertex2i(l, t);
@@ -262,8 +328,8 @@ implementation
     ASSERT(b >= t);
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-    glDisable(GL_TEXTURE_2D);
-    glColor4ub(rr, gg, bb, aa);
+    r_Draw_EnableTexture2D(false);
+    r_Draw_SetColor(rr, gg, bb, aa);
     glBegin(GL_QUADS);
 {
       glVertex2i(l, t);
@@ -271,10 +337,16 @@ implementation
       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);
+}
+      glVertex2f(l + 0, t + 0);
+      glVertex2f(r + 0.75, t + 0);
+      glVertex2f(r + 0.75, b + 0.75);
+      glVertex2f(l + 0, b + 0.75);
     glEnd;
   end;
 
@@ -284,8 +356,8 @@ implementation
     ASSERT(b >= t);
     glEnable(GL_BLEND);
     glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
-    glDisable(GL_TEXTURE_2D);
-    glColor4ub(rr, gg, bb, aa);
+    r_Draw_EnableTexture2D(false);
+    r_Draw_SetColor(rr, gg, bb, aa);
     glBegin(GL_QUADS);
       glVertex2i(l, t);
       glVertex2i(r, t);