X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Frenders%2Fopengl%2Fr_draw.pas;h=940b6728d2cc9827204912fcff593d848a6b0afd;hb=7ea33f434a86160ce9223f5946b5e3407026c76f;hp=b8b90210de603771695a9b76e8f2b1328207f9e6;hpb=90cf86c8e9339852b3c1831c446e242dea4d1074;p=d2df-sdl.git diff --git a/src/game/renders/opengl/r_draw.pas b/src/game/renders/opengl/r_draw.pas index b8b9021..940b672 100644 --- a/src/game/renders/opengl/r_draw.pas +++ b/src/game/renders/opengl/r_draw.pas @@ -30,12 +30,19 @@ 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); + + procedure r_Draw_EnableTexture2D (enable: Boolean); + implementation uses @@ -45,8 +52,7 @@ implementation GL, GLEXT, {$ENDIF} SysUtils, Classes, Math, - e_log, utils, - g_game // gScreenWidth, gScreenHeight + e_log, utils ; const @@ -55,15 +61,49 @@ implementation NTB = $00; NTA = $FF; - procedure SetupMatrix; + var + sl, st, sr, sb: Integer; + ScreenWidth, ScreenHeight: Integer; + + enableTexture2D: Boolean; + curR, curG, curB, curA: Byte; + + procedure r_Draw_EnableTexture2D (enable: Boolean); begin - glScissor(0, 0, gScreenWidth, gScreenHeight); - glViewport(0, 0, gScreenWidth, gScreenHeight); + 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); + 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; + glEnable(GL_SCISSOR_TEST); + r_Draw_SetRect(0, 0, w - 1, h - 1); end; procedure DrawQuad (x, y, w, h: Integer); @@ -81,9 +121,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 @@ -96,10 +136,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); @@ -107,13 +147,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); @@ -121,27 +180,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 @@ -149,6 +225,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 @@ -211,8 +289,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); @@ -221,19 +299,53 @@ 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); + r_Draw_EnableTexture2D(false); + r_Draw_SetColor(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); 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); 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); +} + 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; @@ -243,8 +355,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); @@ -282,4 +394,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.