X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fengine%2Fe_graphics.pas;h=6362cd11437986e6eba5c5da168560e11145f06c;hb=d7d166dc3cd287276202e862746208892c4cc89f;hp=1830c406172a53331dc69aba7d67c1f66c6a4460;hpb=d9d4734e5a1e0a53e1e11a16aa6e103b12b585e9;p=d2df-sdl.git diff --git a/src/engine/e_graphics.pas b/src/engine/e_graphics.pas index 1830c40..6362cd1 100644 --- a/src/engine/e_graphics.pas +++ b/src/engine/e_graphics.pas @@ -22,8 +22,8 @@ uses SysUtils, Classes, Math, e_log, e_texture, SDL2, GL, GLExt, MAPDEF, ImagingTypes, Imaging, ImagingUtility; type - TMirrorType=(M_NONE, M_HORIZONTAL, M_VERTICAL); - TBlending=(B_NONE, B_BLEND, B_FILTER, B_INVERT); + TMirrorType=(None, Horizontal, Vertical); + TBlending=(None, Blend, Filter, Invert); TPoint2i = record X, Y: Integer; @@ -60,24 +60,27 @@ procedure e_SetViewPort(X, Y, Width, Height: Word); procedure e_ResizeWindow(Width, Height: Integer); procedure e_Draw(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean; - Blending: Boolean; Mirror: TMirrorType = M_NONE); + Blending: Boolean; Mirror: TMirrorType = TMirrorType.None); procedure e_DrawAdv(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean; - Blending: Boolean; Angle: Single; RC: PDFPoint; Mirror: TMirrorType = M_NONE); + Blending: Boolean; Angle: Single; RC: PDFPoint; Mirror: TMirrorType = TMirrorType.None); procedure e_DrawSize(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean; - Blending: Boolean; Width, Height: Word; Mirror: TMirrorType = M_NONE); + Blending: Boolean; Width, Height: Word; Mirror: TMirrorType = TMirrorType.None); procedure e_DrawSizeMirror(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean; - Blending: Boolean; Width, Height: Word; Mirror: TMirrorType = M_NONE); + Blending: Boolean; Width, Height: Word; Mirror: TMirrorType = TMirrorType.None); procedure e_DrawFill(ID: DWORD; X, Y: Integer; XCount, YCount: Word; Alpha: Integer; - AlphaChannel: Boolean; Blending: Boolean); + AlphaChannel: Boolean; Blending: Boolean; ambientBlendMode: Boolean=false); -procedure e_DrawFillX (id: DWORD; x, y, wdt, hgt: Integer; alpha: Integer; alphachannel: Boolean; blending: Boolean; scale: Single); +procedure e_DrawFillX (id: DWORD; x, y, wdt, hgt: Integer; alpha: Integer; alphachannel: Boolean; + blending: Boolean; scale: Single; ambientBlendMode: Boolean=false); + +procedure e_AmbientQuad (x, y, w, h: Integer; r, g, b, a: Byte); procedure e_DrawPoint(Size: Byte; X, Y: Integer; Red, Green, Blue: Byte); procedure e_DrawLine(Width: Byte; X1, Y1, X2, Y2: Integer; Red, Green, Blue: Byte; Alpha: Byte = 0); procedure e_DrawQuad(X1, Y1, X2, Y2: Integer; Red, Green, Blue: Byte; Alpha: Byte = 0); procedure e_DrawFillQuad(X1, Y1, X2, Y2: Integer; Red, Green, Blue, Alpha: Byte; - Blending: TBlending = B_NONE); + Blending: TBlending = TBlending.None); procedure e_DarkenQuad (x0, y0, x1, y1: Integer; a: Integer); procedure e_DarkenQuadWH (x, y, w, h: Integer; a: Integer); @@ -141,6 +144,7 @@ var e_Colors: TRGB; e_NoGraphics: Boolean = False; e_FastScreenshots: Boolean = true; // it's REALLY SLOW with `false` + g_dbg_scale: Single = 1.0; implementation @@ -282,7 +286,7 @@ var begin Result := False; - e_WriteLog('Loading texture from '+FileName, MSG_NOTIFY); + e_WriteLog('Loading texture from '+FileName, TMsgType.Notify); find_id := FindTexture(); @@ -465,15 +469,21 @@ begin e_SetViewPort(0, 0, Width, Height); end; -procedure drawTxQuad (x0, y0, w, h: Integer; u, v: single; Mirror: TMirrorType); +procedure drawTxQuad (x0, y0, w, h, tw, th: Integer; u, v: single; Mirror: TMirrorType); var x1, y1, tmp: Integer; begin if (w < 1) or (h < 1) then exit; x1 := x0+w; y1 := y0+h; - if Mirror = M_HORIZONTAL then begin tmp := x1; x1 := x0; x0 := tmp; end - else if Mirror = M_VERTICAL then begin tmp := y1; y1 := y0; y0 := tmp; end; + if Mirror = TMirrorType.Horizontal then begin tmp := x1; x1 := x0; x0 := tmp; end + else if Mirror = TMirrorType.Vertical then begin tmp := y1; y1 := y0; y0 := tmp; end; + //HACK: make texture one pixel shorter, so it won't wrap + if (g_dbg_scale <> 1.0) then + begin + u := u*tw/(tw+1); + v := v*th/(th+1); + end; glTexCoord2f(0, v); glVertex2i(x0, y0); glTexCoord2f(0, 0); glVertex2i(x0, y1); glTexCoord2f(u, 0); glVertex2i(x1, y1); @@ -481,7 +491,7 @@ begin end; procedure e_Draw(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean; - Blending: Boolean; Mirror: TMirrorType = M_NONE); + Blending: Boolean; Mirror: TMirrorType = TMirrorType.None); begin if e_NoGraphics then Exit; glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255); @@ -504,7 +514,7 @@ begin glBindTexture(GL_TEXTURE_2D, e_Textures[ID].tx.id); glBegin(GL_QUADS); - drawTxQuad(X, Y, e_Textures[id].tx.width, e_Textures[id].tx.height, e_Textures[ID].tx.u, e_Textures[ID].tx.v, Mirror); + drawTxQuad(X, Y, e_Textures[id].tx.width, e_Textures[id].tx.height, e_Textures[id].tx.width, e_Textures[id].tx.height, e_Textures[ID].tx.u, e_Textures[ID].tx.v, Mirror); //u := e_Textures[ID].tx.u; //v := e_Textures[ID].tx.v; @@ -541,7 +551,7 @@ begin end; procedure e_DrawSize(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean; - Blending: Boolean; Width, Height: Word; Mirror: TMirrorType = M_NONE); + Blending: Boolean; Width, Height: Word; Mirror: TMirrorType = TMirrorType.None); var u, v: Single; begin @@ -579,7 +589,7 @@ begin end; procedure e_DrawSizeMirror(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean; - Blending: Boolean; Width, Height: Word; Mirror: TMirrorType = M_NONE); + Blending: Boolean; Width, Height: Word; Mirror: TMirrorType = TMirrorType.None); begin if e_NoGraphics then Exit; glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255); @@ -601,46 +611,42 @@ begin glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, e_Textures[ID].tx.id); glBegin(GL_QUADS); - drawTxQuad(X, Y, Width, Height, e_Textures[ID].tx.u, e_Textures[ID].tx.v, Mirror); + drawTxQuad(X, Y, Width, Height, e_Textures[id].tx.width, e_Textures[id].tx.height, e_Textures[ID].tx.u, e_Textures[ID].tx.v, Mirror); glEnd(); glDisable(GL_BLEND); end; procedure e_DrawFill(ID: DWORD; X, Y: Integer; XCount, YCount: Word; Alpha: Integer; - AlphaChannel: Boolean; Blending: Boolean); + AlphaChannel: Boolean; Blending: Boolean; ambientBlendMode: Boolean=false); var X2, Y2, dx, w, h: Integer; u, v: Single; begin if e_NoGraphics then Exit; glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255); + ambientBlendMode := false; - if (Alpha > 0) or (AlphaChannel) or (Blending) then - glEnable(GL_BLEND) + if (Alpha > 0) or AlphaChannel or Blending then + begin + glEnable(GL_BLEND); + end else - glDisable(GL_BLEND); - - if (AlphaChannel) or (Alpha > 0) then - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - if Alpha > 0 then - glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255-Alpha); - - if Blending then - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - - if XCount = 0 then - XCount := 1; + begin + if not ambientBlendMode then glDisable(GL_BLEND); + end; + if AlphaChannel or (Alpha > 0) then glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if (Alpha > 0) then glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255-Alpha); + if Blending then glBlendFunc(GL_SRC_ALPHA, GL_ONE); - if YCount = 0 then - YCount := 1; + if (XCount = 0) then XCount := 1; + if (YCount = 0) then YCount := 1; glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, e_Textures[ID].tx.id); - X2 := X + e_Textures[ID].tx.width * XCount; - Y2 := Y + e_Textures[ID].tx.height * YCount; + X2 := X+e_Textures[ID].tx.width*XCount; + Y2 := Y+e_Textures[ID].tx.height*YCount; //k8: this SHOULD work... i hope if (e_Textures[ID].tx.width = e_Textures[ID].tx.glwidth) and (e_Textures[ID].tx.height = e_Textures[ID].tx.glheight) then @@ -707,7 +713,8 @@ begin end; -procedure e_DrawFillX (id: DWORD; x, y, wdt, hgt: Integer; alpha: Integer; alphachannel: Boolean; blending: Boolean; scale: Single); +procedure e_DrawFillX (id: DWORD; x, y, wdt, hgt: Integer; alpha: Integer; alphachannel: Boolean; + blending: Boolean; scale: Single; ambientBlendMode: Boolean=false); var x2, y2: Integer; { @@ -742,26 +749,28 @@ var begin if e_NoGraphics then exit; + ambientBlendMode := false; if (wdt < 1) or (hgt < 1) then exit; if (wdt mod e_Textures[ID].tx.width = 0) and (hgt mod e_Textures[ID].tx.height = 0) then begin - e_DrawFill(id, x, y, wdt div e_Textures[ID].tx.width, hgt div e_Textures[ID].tx.height, alpha, alphachannel, blending); + e_DrawFill(id, x, y, wdt div e_Textures[ID].tx.width, hgt div e_Textures[ID].tx.height, alpha, alphachannel, blending, ambientBlendMode); exit; end; glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255); if (Alpha > 0) or AlphaChannel or Blending then - glEnable(GL_BLEND) + begin + glEnable(GL_BLEND); + end else - glDisable(GL_BLEND); - + begin + if not ambientBlendMode then glDisable(GL_BLEND); + end; if AlphaChannel or (Alpha > 0) then glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - if (Alpha > 0) then glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255-Alpha); - if Blending then glBlendFunc(GL_SRC_ALPHA, GL_ONE); glEnable(GL_TEXTURE_2D); @@ -826,8 +835,39 @@ begin end; +procedure e_AmbientQuad (x, y, w, h: Integer; r, g, b, a: Byte); +begin + if e_NoGraphics then exit; + if (w < 1) or (h < 1) then exit; + if (a <> 255) or ((r or g or b) <> 0) then + begin + glEnable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + glColor4ub(r, g, b, a); + if ((r or g or b) <> 0) then + begin + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBegin(GL_QUADS); + glVertex2i(x, y); + glVertex2i(x+w, y); + glVertex2i(x+w, y+h); + glVertex2i(x, y+h); + glEnd(); + end; + glBlendFunc(GL_ZERO, GL_SRC_ALPHA); + glBegin(GL_QUADS); + glVertex2i(x, y); + glVertex2i(x+w, y); + glVertex2i(x+w, y+h); + glVertex2i(x, y+h); + glEnd(); + glDisable(GL_BLEND); + end; +end; + + procedure e_DrawAdv(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean; - Blending: Boolean; Angle: Single; RC: PDFPoint; Mirror: TMirrorType = M_NONE); + Blending: Boolean; Angle: Single; RC: PDFPoint; Mirror: TMirrorType = TMirrorType.None); begin if e_NoGraphics then Exit; @@ -859,7 +899,7 @@ begin glBindTexture(GL_TEXTURE_2D, e_Textures[id].tx.id); glBegin(GL_QUADS); //0-1 1-1 //00 10 - drawTxQuad(X, Y, e_Textures[id].tx.width, e_Textures[id].tx.height, e_Textures[ID].tx.u, e_Textures[ID].tx.v, Mirror); + drawTxQuad(X, Y, e_Textures[id].tx.width, e_Textures[id].tx.height, e_Textures[id].tx.width, e_Textures[id].tx.height, e_Textures[ID].tx.u, e_Textures[ID].tx.v, Mirror); glEnd(); if Angle <> 0 then @@ -969,21 +1009,21 @@ begin end; procedure e_DrawFillQuad(X1, Y1, X2, Y2: Integer; Red, Green, Blue, Alpha: Byte; - Blending: TBlending = B_NONE); + Blending: TBlending = TBlending.None); begin if e_NoGraphics then Exit; - if (Alpha > 0) or (Blending <> B_NONE) then + if (Alpha > 0) or (Blending <> TBlending.None) then glEnable(GL_BLEND) else glDisable(GL_BLEND); - if Blending = B_BLEND then + if Blending = TBlending.Blend then glBlendFunc(GL_SRC_ALPHA, GL_ONE) else - if Blending = B_FILTER then + if Blending = TBlending.Filter then glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR) else - if Blending = B_INVERT then + if Blending = TBlending.Invert then glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO) else if Alpha > 0 then @@ -1192,7 +1232,7 @@ function e_CharFont_Create(sp: ShortInt=0): DWORD; var i, id: DWORD; begin - e_WriteLog('Creating CharFont...', MSG_NOTIFY); + e_WriteLog('Creating CharFont...', TMsgType.Notify); id := DWORD(-1); @@ -1515,7 +1555,7 @@ var i, id: DWORD; begin if e_NoGraphics then Exit; - e_WriteLog('Creating texture font...', MSG_NOTIFY); + e_WriteLog('Creating texture font...', TMsgType.Notify); id := DWORD(-1);