X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fengine%2Fe_graphics.pas;h=96513d90755f8abcbe1e5237a36767dd8c45316f;hb=6e52b3dc2eb459c745e571dfef5afb5c2ccd546f;hp=e4eb35a89ed96385e90571c40c9d4d8d6959f5bc;hpb=b72e164f0fb64e3301ae8ca217449daf6a9d301d;p=d2df-editor.git diff --git a/src/engine/e_graphics.pas b/src/engine/e_graphics.pas index e4eb35a..96513d9 100644 --- a/src/engine/e_graphics.pas +++ b/src/engine/e_graphics.pas @@ -1,9 +1,25 @@ +(* 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 . + *) +{$INCLUDE ../shared/a_modes.inc} unit e_graphics; interface uses - windows, SysUtils, Math, e_log, e_textures, dglOpenGL; + SysUtils, Classes, Math, e_log, e_textures, GL, GLExt, MAPDEF, + ImagingTypes, Imaging, ImagingUtility; type TMirrorType=(M_NONE, M_HORIZONTAL, M_VERTICAL); @@ -13,11 +29,16 @@ type X, Y: Integer; end; + TPoint = MAPDEF.TPoint; // TODO: create an utiltypes.pas or something + // for other types like rect as well + TPoint2f = record X, Y: Double; end; - TRect = windows.TRect; + TRectE = record + Left, Top, Right, Bottom: Integer; + end; TRectWH = record X, Y: Integer; @@ -30,14 +51,14 @@ type PPoint = ^TPoint; PPoint2f = ^TPoint2f; - PRect = ^TRect; + PRect = ^TRectE; PRectWH = ^TRectWH; //------------------------------------------------------------------ // ïðîòîòèïû ôóíêöèé //------------------------------------------------------------------ -procedure e_InitGL(VSync: Boolean); +procedure e_InitGL(); procedure e_SetViewPort(X, Y, Width, Height: Word); procedure e_ResizeWindow(Width, Height: Integer); @@ -57,22 +78,16 @@ procedure e_DrawQuad(X1, Y1, X2, Y2: Integer; Red, Green, Blue: Byte; Alpha: Byt procedure e_DrawFillQuad(X1, Y1, X2, Y2: Integer; Red, Green, Blue, Alpha: Byte; Blending: TBlending = B_NONE); +function e_CreateTextureImg (var img: TImageData; var ID: DWORD): Boolean; function e_CreateTexture(FileName: string; var ID: DWORD): Boolean; function e_CreateTextureEx(FileName: string; var ID: DWORD; fX, fY, fWidth, fHeight: Word): Boolean; -function e_CreateTextureMem(pData: Pointer; var ID: DWORD): Boolean; -function e_CreateTextureMemEx(pData: Pointer; var ID: DWORD; fX, fY, fWidth, fHeight: Word): Boolean; +function e_CreateTextureMem(pData: Pointer; dataSize: LongInt; var ID: DWORD): Boolean; +function e_CreateTextureMemEx(pData: Pointer; dataSize: LongInt; var ID: DWORD; fX, fY, fWidth, fHeight: Word): Boolean; procedure e_GetTextureSize(ID: DWORD; Width, Height: PWord); function e_GetTextureSize2(ID: DWORD): TRectWH; procedure e_DeleteTexture(ID: DWORD); procedure e_RemoveAllTextures(); -// SimpleFont -function e_SimpleFontCreate(FontName: PChar; Size: Byte; Weight: Word; DC: HDC): DWORD; -procedure e_SimpleFontFree(Font: DWORD); -procedure e_SimpleFontPrint(X, Y: SmallInt; Text: PChar; Font: Integer; Red, Green, Blue: Byte); -procedure e_SimpleFontPrintEx(X, Y: SmallInt; Text: PChar; Font: DWORD; Red, Green, Blue, - sRed, sGreen, sBlue, sWidth: Byte); - // CharFont function e_CharFont_Create(sp: ShortInt=0): DWORD; procedure e_CharFont_AddChar(FontID: DWORD; Texture: Integer; c: Char; w: Byte); @@ -88,7 +103,7 @@ procedure e_CharFont_Remove(FontID: DWORD); procedure e_CharFont_RemoveAll(); // TextureFont -procedure e_TextureFontBuild(Texture: DWORD; var FontID: DWORD; XCount, YCount: Word; +procedure e_TextureFontBuild(Tex: DWORD; var FontID: DWORD; XCount, YCount: Word; Space: ShortInt=0); procedure e_TextureFontKill(FontID: DWORD); procedure e_TextureFontPrint(X, Y: GLint; Text: string; FontID: DWORD); @@ -98,38 +113,46 @@ procedure e_TextureFontPrintFmt(X, Y: GLint; Text: string; FontID: DWORD; Shadow procedure e_TextureFontGetSize(ID: DWORD; var CharWidth, CharHeight: Byte); procedure e_RemoveAllTextureFont(); +function e_TextureFontCharWidth (ch: Char; FontID: DWORD): Integer; +procedure e_TextureFontPrintCharEx (X, Y: Integer; Ch: Char; FontID: DWORD; Shadow: Boolean = False); + procedure e_ReleaseEngine(); procedure e_BeginRender(); -procedure e_Clear(Mask: TGLbitfield; Red, Green, Blue: Single); +procedure e_Clear(Mask: TGLbitfield; Red, Green, Blue: Single); overload; +procedure e_Clear(); overload; procedure e_EndRender(); -function e_GetGamma(DC: HDC): Byte; -procedure e_SetGamma(Gamma: Byte; DC: HDC); - -procedure e_MakeScreenshot(FileName: string; Width, Height: Word); - function _RGB(Red, Green, Blue: Byte): TRGB; function _Point(X, Y: Integer): TPoint2i; function _Rect(X, Y: Integer; Width, Height: Word): TRectWH; +function _TRect(L, T, R, B: LongInt): TRectE; +//function e_getTextGLId (ID: DWORD): GLuint; var e_Colors: TRGB; + e_NoGraphics: Boolean = False; + e_FastScreenshots: Boolean = true; // it's REALLY SLOW with `false` + implementation +uses + paszlib, crc, utils; + + type TTexture = record - ID: DWORD; - Width: Word; - Height: Word; + tx: GLTexture; end; TTextureFont = record - TextureID: DWORD; - Base: GLuint; - CharWidth: Byte; - CharHeight: Byte; + Texture: DWORD; + TextureID: DWORD; + Base: Uint32; + CharWidth: Byte; + CharHeight: Byte; + XC, YC, SPC: Word; end; TCharFont = record @@ -143,25 +166,35 @@ type Live: Boolean; end; + TSavedTexture = record + TexID: DWORD; + OldID: DWORD; + Pixels: Pointer; + end; + var e_Textures: array of TTexture = nil; e_TextureFonts: array of TTextureFont = nil; e_CharFonts: array of TCharFont; + //e_SavedTextures: array of TSavedTexture; + +//function e_getTextGLId (ID: DWORD): GLuint; begin result := e_Textures[ID].tx.id; end; //------------------------------------------------------------------ // Èíèöèàëèçèðóåò OpenGL //------------------------------------------------------------------ -procedure e_InitGL(VSync: Boolean); +procedure e_InitGL(); begin - if VSync then - wglSwapIntervalEXT(1) - else - wglSwapIntervalEXT(0); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); + if e_NoGraphics then + begin + e_DummyTextures := True; + Exit; + end; e_Colors.R := 255; e_Colors.G := 255; e_Colors.B := 255; + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); glClearColor(0, 0, 0, 0); end; @@ -170,6 +203,7 @@ var mat: Array [0..15] of GLDouble; begin + if e_NoGraphics then Exit; glLoadIdentity(); glScissor(X, Y, Width, Height); glViewport(X, Y, Width, Height); @@ -200,7 +234,7 @@ begin glLoadMatrixd(@mat[0]); glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + glLoadIdentity(); end; //------------------------------------------------------------------ @@ -212,7 +246,7 @@ var begin if e_Textures <> nil then for i := 0 to High(e_Textures) do - if e_Textures[i].Width = 0 then + if e_Textures[i].tx.Width = 0 then begin Result := i; Exit; @@ -236,6 +270,7 @@ end; function e_CreateTexture(FileName: String; var ID: DWORD): Boolean; var find_id: DWORD; + fmt: Word; begin Result := False; @@ -243,8 +278,8 @@ begin find_id := FindTexture(); - if not LoadTexture(FileName, e_Textures[find_id].ID, e_Textures[find_id].Width, - e_Textures[find_id].Height) then Exit; + if not LoadTexture(FileName, e_Textures[find_id].tx, e_Textures[find_id].tx.Width, + e_Textures[find_id].tx.Height, @fmt) then Exit; ID := find_id; @@ -254,81 +289,92 @@ end; function e_CreateTextureEx(FileName: String; var ID: DWORD; fX, fY, fWidth, fHeight: Word): Boolean; var find_id: DWORD; + fmt: Word; begin Result := False; find_id := FindTexture(); - if not LoadTextureEx(FileName, e_Textures[find_id].ID, fX, fY, fWidth, fHeight) then Exit; - - e_Textures[find_id].Width := fWidth; - e_Textures[find_id].Height := fHeight; + if not LoadTextureEx(FileName, e_Textures[find_id].tx, fX, fY, fWidth, fHeight, @fmt) then exit; ID := find_id; Result := True; end; -function e_CreateTextureMem(pData: Pointer; var ID: DWORD): Boolean; +function e_CreateTextureMem(pData: Pointer; dataSize: LongInt; var ID: DWORD): Boolean; var find_id: DWORD; + fmt: Word; begin Result := False; find_id := FindTexture; - if not LoadTextureMem(pData, e_Textures[find_id].ID, e_Textures[find_id].Width, - e_Textures[find_id].Height) then Exit; + if not LoadTextureMem(pData, dataSize, e_Textures[find_id].tx, e_Textures[find_id].tx.Width, e_Textures[find_id].tx.Height, @fmt) then exit; id := find_id; Result := True; end; -function e_CreateTextureMemEx(pData: Pointer; var ID: DWORD; fX, fY, fWidth, fHeight: Word): Boolean; +function e_CreateTextureMemEx(pData: Pointer; dataSize: LongInt; var ID: DWORD; fX, fY, fWidth, fHeight: Word): Boolean; var find_id: DWORD; + fmt: Word; begin Result := False; find_id := FindTexture(); - if not LoadTextureMemEx(pData, e_Textures[find_id].ID, fX, fY, fWidth, fHeight) then Exit; - - e_Textures[find_id].Width := fWidth; - e_Textures[find_id].Height := fHeight; + if not LoadTextureMemEx(pData, dataSize, e_Textures[find_id].tx, fX, fY, fWidth, fHeight, @fmt) then exit; ID := find_id; Result := True; end; +function e_CreateTextureImg (var img: TImageData; var ID: DWORD): Boolean; +var + find_id: DWORD; + fmt, tw, th: Word; +begin + result := false; + find_id := FindTexture(); + if not LoadTextureImg(img, e_Textures[find_id].tx, tw, th, @fmt) then exit; + ID := find_id; + result := True; +end; + procedure e_GetTextureSize(ID: DWORD; Width, Height: PWord); begin - if Width <> nil then Width^ := e_Textures[ID].Width; - if Height <> nil then Height^ := e_Textures[ID].Height; + if Width <> nil then Width^ := e_Textures[ID].tx.Width; + if Height <> nil then Height^ := e_Textures[ID].tx.Height; end; function e_GetTextureSize2(ID: DWORD): TRectWH; var - data: Pointer; + data: PChar; x, y: Integer; w, h: Word; a: Boolean; lastline: Integer; begin - w := e_Textures[ID].Width; - h := e_Textures[ID].Height; - data := GetMemory(w*h*4); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, e_Textures[ID].ID); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + w := e_Textures[ID].tx.Width; + h := e_Textures[ID].tx.Height; Result.Y := 0; Result.X := 0; Result.Width := w; Result.Height := h; + if e_NoGraphics then Exit; + + data := GetMemory(w*h*4); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, e_Textures[ID].tx.id); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + for y := h-1 downto 0 do begin lastline := y; @@ -336,7 +382,7 @@ begin for x := 1 to w-4 do begin - a := Byte(Pointer(Integer(data)+y*w*4+x*4+3)^) <> 0; + a := Byte((data+y*w*4+x*4+3)^) <> 0; if a then Break; end; @@ -354,7 +400,7 @@ begin for x := 1 to w-4 do begin - a := Byte(Pointer(Integer(data)+y*w*4+x*4+3)^) <> 0; + a := Byte((data+y*w*4+x*4+3)^) <> 0; if a then Break; end; @@ -372,7 +418,7 @@ begin for y := 1 to h-4 do begin - a := Byte(Pointer(Integer(data)+y*w*4+x*4+3)^) <> 0; + a := Byte((data+y*w*4+x*4+3)^) <> 0; if a then Break; end; @@ -390,7 +436,7 @@ begin for y := 1 to h-4 do begin - a := Byte(Pointer(Integer(data)+y*w*4+x*4+3)^) <> 0; + a := Byte((data+y*w*4+x*4+3)^) <> 0; if a then Break; end; @@ -411,11 +457,27 @@ begin e_SetViewPort(0, 0, Width, Height); end; +procedure drawTxQuad (x0, y0, w, h: 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; + glTexCoord2f(0, v); glVertex2i(x0, y0); + glTexCoord2f(0, 0); glVertex2i(x0, y1); + glTexCoord2f(u, 0); glVertex2i(x1, y1); + glTexCoord2f(u, v); glVertex2i(x1, y0); +end; + procedure e_Draw(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean; Blending: Boolean; Mirror: TMirrorType = M_NONE); -begin +begin + if e_NoGraphics then Exit; glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255); - + if (Alpha > 0) or (AlphaChannel) or (Blending) then glEnable(GL_BLEND) else @@ -431,32 +493,39 @@ begin glBlendFunc(GL_SRC_ALPHA, GL_ONE); glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, e_Textures[ID].ID); + 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); + + //u := e_Textures[ID].tx.u; + //v := e_Textures[ID].tx.v; + + { if Mirror = M_NONE then begin - glTexCoord2i(1, 0); glVertex2i(X + e_Textures[id].Width, Y); - glTexCoord2i(0, 0); glVertex2i(X, Y); - glTexCoord2i(0, -1); glVertex2i(X, Y + e_Textures[id].Height); - glTexCoord2i(1, -1); glVertex2i(X + e_Textures[id].Width, Y + e_Textures[id].Height); + glTexCoord2f(u, 0); glVertex2i(X + e_Textures[id].tx.Width, Y); + glTexCoord2f(0, 0); glVertex2i(X, Y); + glTexCoord2f(0, -v); glVertex2i(X, Y + e_Textures[id].tx.Height); + glTexCoord2f(u, -v); glVertex2i(X + e_Textures[id].tx.Width, Y + e_Textures[id].tx.Height); end else if Mirror = M_HORIZONTAL then begin - glTexCoord2i(1, 0); glVertex2i(X, Y); - glTexCoord2i(0, 0); glVertex2i(X + e_Textures[id].Width, Y); - glTexCoord2i(0, -1); glVertex2i(X + e_Textures[id].Width, Y + e_Textures[id].Height); - glTexCoord2i(1, -1); glVertex2i(X, Y + e_Textures[id].Height); + glTexCoord2f(u, 0); glVertex2i(X, Y); + glTexCoord2f(0, 0); glVertex2i(X + e_Textures[id].tx.Width, Y); + glTexCoord2f(0, -v); glVertex2i(X + e_Textures[id].tx.Width, Y + e_Textures[id].tx.Height); + glTexCoord2f(u, -v); glVertex2i(X, Y + e_Textures[id].tx.Height); end else if Mirror = M_VERTICAL then begin - glTexCoord2i(1, -1); glVertex2i(X + e_Textures[id].Width, Y); - glTexCoord2i(0, -1); glVertex2i(X, Y); - glTexCoord2i(0, 0); glVertex2i(X, Y + e_Textures[id].Height); - glTexCoord2i(1, 0); glVertex2i(X + e_Textures[id].Width, Y + e_Textures[id].Height); + glTexCoord2f(u, -v); glVertex2i(X + e_Textures[id].tx.Width, Y); + glTexCoord2f(0, -v); glVertex2i(X, Y); + glTexCoord2f(0, 0); glVertex2i(X, Y + e_Textures[id].tx.Height); + glTexCoord2f(u, 0); glVertex2i(X + e_Textures[id].tx.Width, Y + e_Textures[id].tx.Height); end; + } glEnd(); @@ -465,7 +534,10 @@ end; procedure e_DrawSize(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean; Blending: Boolean; Width, Height: Word; Mirror: TMirrorType = M_NONE); +var + u, v: Single; begin + if e_NoGraphics then Exit; glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255); if (Alpha > 0) or (AlphaChannel) or (Blending) then @@ -483,13 +555,16 @@ begin glBlendFunc(GL_SRC_ALPHA, GL_ONE); glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, e_Textures[ID].ID); + glBindTexture(GL_TEXTURE_2D, e_Textures[ID].tx.id); + + u := e_Textures[ID].tx.u; + v := e_Textures[ID].tx.v; glBegin(GL_QUADS); - glTexCoord2i(0, 1); glVertex2i(X, Y); - glTexCoord2i(1, 1); glVertex2i(X + Width, Y); - glTexCoord2i(1, 0); glVertex2i(X + Width, Y + Height); - glTexCoord2i(0, 0); glVertex2i(X, Y + Height); + glTexCoord2f(0, v); glVertex2i(X, Y); + glTexCoord2f(u, v); glVertex2i(X + Width, Y); + glTexCoord2f(u, 0); glVertex2i(X + Width, Y + Height); + glTexCoord2f(0, 0); glVertex2i(X, Y + Height); glEnd(); glDisable(GL_BLEND); @@ -498,6 +573,7 @@ end; procedure e_DrawSizeMirror(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean; Blending: Boolean; Width, Height: Word; Mirror: TMirrorType = M_NONE); begin + if e_NoGraphics then Exit; glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255); if (Alpha > 0) or (AlphaChannel) or (Blending) then @@ -515,33 +591,9 @@ begin glBlendFunc(GL_SRC_ALPHA, GL_ONE); glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, e_Textures[ID].ID); + glBindTexture(GL_TEXTURE_2D, e_Textures[ID].tx.id); glBegin(GL_QUADS); - - if Mirror = M_NONE then - begin - glTexCoord2i(1, 0); glVertex2i(X + Width, Y); - glTexCoord2i(0, 0); glVertex2i(X, Y); - glTexCoord2i(0, -1); glVertex2i(X, Y + Height); - glTexCoord2i(1, -1); glVertex2i(X + Width, Y + Height); - end - else - if Mirror = M_HORIZONTAL then - begin - glTexCoord2i(1, 0); glVertex2i(X, Y); - glTexCoord2i(0, 0); glVertex2i(X + Width, Y); - glTexCoord2i(0, -1); glVertex2i(X + Width, Y + Height); - glTexCoord2i(1, -1); glVertex2i(X, Y + Height); - end - else - if Mirror = M_VERTICAL then - begin - glTexCoord2i(1, -1); glVertex2i(X + Width, Y); - glTexCoord2i(0, -1); glVertex2i(X, Y); - glTexCoord2i(0, 0); glVertex2i(X, Y + Height); - glTexCoord2i(1, 0); glVertex2i(X + Width, Y + Height); - end; - + drawTxQuad(X, Y, Width, Height, e_Textures[ID].tx.u, e_Textures[ID].tx.v, Mirror); glEnd(); glDisable(GL_BLEND); @@ -550,9 +602,10 @@ end; procedure e_DrawFill(ID: DWORD; X, Y: Integer; XCount, YCount: Word; Alpha: Integer; AlphaChannel: Boolean; Blending: Boolean); var - X2, Y2: Integer; - + 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); if (Alpha > 0) or (AlphaChannel) or (Blending) then @@ -576,31 +629,64 @@ begin YCount := 1; glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, e_Textures[ID].ID); + glBindTexture(GL_TEXTURE_2D, e_Textures[ID].tx.id); - X2 := X + e_Textures[ID].Width * XCount; - Y2 := Y + e_Textures[ID].Height * YCount; - - glBegin(GL_QUADS); - glTexCoord2i(0, YCount); glVertex2i(X, Y); - glTexCoord2i(XCount, YCount); glVertex2i(X2, Y); - glTexCoord2i(XCount, 0); glVertex2i(X2, Y2); - glTexCoord2i(0, 0); glVertex2i(X, Y2); - glEnd(); + 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 + begin + glBegin(GL_QUADS); + glTexCoord2i(0, YCount); glVertex2i(X, Y); + glTexCoord2i(XCount, YCount); glVertex2i(X2, Y); + glTexCoord2i(XCount, 0); glVertex2i(X2, Y2); + glTexCoord2i(0, 0); glVertex2i(X, Y2); + glEnd(); + end + else + begin + glBegin(GL_QUADS); + // hard day's night + u := e_Textures[ID].tx.u; + v := e_Textures[ID].tx.v; + w := e_Textures[ID].tx.width; + h := e_Textures[ID].tx.height; + while YCount > 0 do + begin + dx := XCount; + x2 := X; + while dx > 0 do + begin + glTexCoord2f(0, v); glVertex2i(X, Y); + glTexCoord2f(u, v); glVertex2i(X+w, Y); + glTexCoord2f(u, 0); glVertex2i(X+w, Y+h); + glTexCoord2f(0, 0); glVertex2i(X, Y+h); + Inc(X, w); + Dec(dx); + end; + X := x2; + Inc(Y, h); + Dec(YCount); + end; + glEnd(); + end; glDisable(GL_BLEND); end; procedure e_DrawAdv(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean; Blending: Boolean; Angle: Single; RC: PPoint; Mirror: TMirrorType = M_NONE); -begin +begin + if e_NoGraphics then Exit; + glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255); if (Alpha > 0) or (AlphaChannel) or (Blending) then glEnable(GL_BLEND) else glDisable(GL_BLEND); - + if (AlphaChannel) or (Alpha > 0) then glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -619,33 +705,10 @@ begin end; glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, e_Textures[id].ID); + glBindTexture(GL_TEXTURE_2D, e_Textures[id].tx.id); glBegin(GL_QUADS); //0-1 1-1 //00 10 - if Mirror = M_NONE then - begin - glTexCoord2i(1, 0); glVertex2i(X + e_Textures[id].Width, Y); - glTexCoord2i(0, 0); glVertex2i(X, Y); - glTexCoord2i(0, -1); glVertex2i(X, Y + e_Textures[id].Height); - glTexCoord2i(1, -1); glVertex2i(X + e_Textures[id].Width, Y + e_Textures[id].Height); - end - else - if Mirror = M_HORIZONTAL then - begin - glTexCoord2i(1, 0); glVertex2i(X, Y); - glTexCoord2i(0, 0); glVertex2i(X + e_Textures[id].Width, Y); - glTexCoord2i(0, -1); glVertex2i(X + e_Textures[id].Width, Y + e_Textures[id].Height); - glTexCoord2i(1, -1); glVertex2i(X, Y + e_Textures[id].Height); - end - else - if Mirror = M_VERTICAL then - begin - glTexCoord2i(1, -1); glVertex2i(X + e_Textures[id].Width, Y); - glTexCoord2i(0, -1); glVertex2i(X, Y); - glTexCoord2i(0, 0); glVertex2i(X, Y + e_Textures[id].Height); - glTexCoord2i(1, 0); glVertex2i(X + e_Textures[id].Width, Y + e_Textures[id].Height); - end; - + drawTxQuad(X, Y, 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 @@ -656,10 +719,11 @@ end; procedure e_DrawPoint(Size: Byte; X, Y: Integer; Red, Green, Blue: Byte); begin + if e_NoGraphics then Exit; glDisable(GL_TEXTURE_2D); glColor3ub(Red, Green, Blue); glPointSize(Size); - + if (Size = 2) or (Size = 4) then X := X + 1; @@ -670,45 +734,9 @@ begin glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255); end; -procedure e_LineCorrection(var X1, Y1, X2, Y2: Integer); -begin - // Make lines only top-left/bottom-right and top-right/bottom-left - if Y2 < Y1 then - begin - X1 := X1 xor X2; - X2 := X1 xor X2; - X1 := X1 xor X2; - - Y1 := Y1 xor Y2; - Y2 := Y1 xor Y2; - Y1 := Y1 xor Y2; - end; - - // Pixel-perfect hack - if X1 < X2 then - Inc(X2) - else - Inc(X1); - Inc(Y2); -end; - procedure e_DrawQuad(X1, Y1, X2, Y2: Integer; Red, Green, Blue: Byte; Alpha: Byte = 0); -var - nX1, nY1, nX2, nY2: Integer; begin - // Only top-left/bottom-right quad - if X1 > X2 then - begin - X1 := X1 xor X2; - X2 := X1 xor X2; - X1 := X1 xor X2; - end; - if Y1 > Y2 then - begin - Y1 := Y1 xor Y2; - Y2 := Y1 xor Y2; - Y1 := Y1 xor Y2; - end; + if e_NoGraphics then Exit; if Alpha > 0 then begin @@ -721,30 +749,11 @@ begin glColor4ub(Red, Green, Blue, 255-Alpha); glLineWidth(1); - glBegin(GL_LINES); - nX1 := X1; nY1 := Y1; - nX2 := X2; nY2 := Y1; - e_LineCorrection(nX1, nY1, nX2, nY2); // Pixel-perfect lines - glVertex2i(nX1, nY1); - glVertex2i(nX2, nY2); - - nX1 := X2; nY1 := Y1; - nX2 := X2; nY2 := Y2; - e_LineCorrection(nX1, nY1, nX2, nY2); - glVertex2i(nX1, nY1); - glVertex2i(nX2, nY2); - - nX1 := X2; nY1 := Y2; - nX2 := X1; nY2 := Y2; - e_LineCorrection(nX1, nY1, nX2, nY2); - glVertex2i(nX1, nY1); - glVertex2i(nX2, nY2); - - nX1 := X1; nY1 := Y2; - nX2 := X1; nY2 := Y1; - e_LineCorrection(nX1, nY1, nX2, nY2); - glVertex2i(nX1, nY1); - glVertex2i(nX2, nY2); + glBegin(GL_LINE_LOOP); + glVertex2f(X1 + 0.5, Y1 + 0.5); + glVertex2f(X2 + 0.5, Y1 + 0.5); + glVertex2f(X2 + 0.5, Y2 + 0.5); + glVertex2f(X1 + 0.5, Y2 + 0.5); glEnd(); glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255); @@ -755,6 +764,7 @@ end; procedure e_DrawFillQuad(X1, Y1, X2, Y2: Integer; Red, Green, Blue, Alpha: Byte; Blending: TBlending = B_NONE); begin + if e_NoGraphics then Exit; if (Alpha > 0) or (Blending <> B_NONE) then glEnable(GL_BLEND) else @@ -792,9 +802,10 @@ end; procedure e_DrawLine(Width: Byte; X1, Y1, X2, Y2: Integer; Red, Green, Blue: Byte; Alpha: Byte = 0); begin + if e_NoGraphics then Exit; // Pixel-perfect lines - if Width = 1 then - e_LineCorrection(X1, Y1, X2, Y2); + //if Width = 1 then + // e_LineCorrection(X1, Y1, X2, Y2); if Alpha > 0 then begin @@ -822,10 +833,11 @@ end; //------------------------------------------------------------------ procedure e_DeleteTexture(ID: DWORD); begin - glDeleteTextures(1, @e_Textures[ID].ID); - e_Textures[ID].ID := 0; - e_Textures[ID].Width := 0; - e_Textures[ID].Height := 0; + if not e_NoGraphics then + glDeleteTextures(1, @e_Textures[ID].tx.id); + e_Textures[ID].tx.id := 0; + e_Textures[ID].tx.Width := 0; + e_Textures[ID].tx.Height := 0; end; //------------------------------------------------------------------ @@ -838,7 +850,7 @@ begin if e_Textures = nil then Exit; for i := 0 to High(e_Textures) do - if e_Textures[i].Width <> 0 then e_DeleteTexture(i); + if e_Textures[i].tx.Width <> 0 then e_DeleteTexture(i); e_Textures := nil; end; @@ -853,196 +865,29 @@ end; procedure e_BeginRender(); begin + if e_NoGraphics then Exit; glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.0); end; -procedure e_Clear(Mask: TGLbitfield; Red, Green, Blue: Single); -begin - glClearColor(Red, Green, Blue, 0); - glClear(Mask); -end; - -procedure e_EndRender(); -begin - glPopMatrix(); -end; - -procedure e_MakeScreenshot(FileName: String; Width, Height: Word); -type - aRGB = Array [0..1] of TRGB; - PaRGB = ^aRGB; - - TByteArray = Array [0..1] of Byte; - PByteArray = ^TByteArray; - -var - FILEHEADER: BITMAPFILEHEADER; - INFOHEADER: BITMAPINFOHEADER; - pixels: PByteArray; - tmp: Byte; - i: Integer; - F: File of Byte; - -begin - if (Width mod 4) > 0 then - Width := Width + 4 - (Width mod 4); - - GetMem(pixels, Width*Height*3); - glReadPixels(0, 0, Width, Height, GL_RGB, GL_UNSIGNED_BYTE, pixels); - - {$R-} - for i := 0 to Width * Height - 1 do - with PaRGB(pixels)[i] do - begin - tmp := R; - R := B; - B := tmp; - end; - {$R+} - - with FILEHEADER do - begin - bfType := $4D42; // "BM" - bfSize := Width*Height*3 + SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER); - bfReserved1 := 0; - bfReserved2 := 0; - bfOffBits := SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER); - end; - - with INFOHEADER do - begin - biSize := SizeOf(BITMAPINFOHEADER); - biWidth := Width; - biHeight := Height; - biPlanes := 1; - biBitCount := 24; - biCompression := 0; - biSizeImage := Width*Height*3; - biXPelsPerMeter := 0; - biYPelsPerMeter := 0; - biClrUsed := 0; - biClrImportant := 0; - end; - - AssignFile(F, FileName); - Rewrite(F); - - BlockWrite(F, FILEHEADER, SizeOf(FILEHEADER)); - BlockWrite(F, INFOHEADER, SizeOf(INFOHEADER)); - BlockWrite(F, pixels[0], Width*Height*3); - - CloseFile(F); - - FreeMem(pixels); -end; - -function e_GetGamma(DC: HDC): Byte; -var - ramp: array [0..256*3-1] of Word; - rgb: array [0..2] of Double; - sum: double; - count: integer; - min: integer; - max: integer; - A, B: double; - i, j: integer; -begin - rgb[0] := 1.0; - rgb[1] := 1.0; - rgb[2] := 1.0; - - GetDeviceGammaRamp(DC, ramp); - - for i := 0 to 2 do - begin - sum := 0; - count := 0; - min := 256 * i; - max := min + 256; - - for j := min to max - 1 do - if ramp[j] > 0 then - begin - B := (j mod 256)/256; - A := ramp[j]/65536; - sum := sum + ln(A)/ln(B); - inc(count); - end; - rgb[i] := sum / count; - end; - - Result := 100 - Trunc(((rgb[0] + rgb[1] + rgb[2])/3 - 0.23) * 100/(2.7 - 0.23)); -end; - -procedure e_SetGamma(Gamma: Byte; DC: HDC); -var - ramp: array [0..256*3-1] of Word; - i: integer; - r: double; - g: double; -begin - g := (100 - Gamma)*(2.7 - 0.23)/100 + 0.23; - - for i := 0 to 255 do - begin - r := Exp(g * ln(i/256))*65536; - if r < 0 then r := 0 - else if r > 65535 then r := 65535; - ramp[i] := trunc(r); - ramp[i + 256] := trunc(r); - ramp[i + 512] := trunc(r); - end; - - SetDeviceGammaRamp(DC, ramp); -end; - -function e_SimpleFontCreate(FontName: PChar; Size: Byte; Weight: Word; DC: HDC): DWORD; -var - font: HFONT; -begin - Result := glGenLists(96); // Generate enough display lists to hold - font := CreateFont(-Size, // height of font - 0, // average character width - 0, // angle of escapement - 0, // base-line orientation angle - Weight, // font weight - 0, // italic - 0, // underline - 0, // strikeout - RUSSIAN_CHARSET, // character set - OUT_TT_PRECIS, // output precision - CLIP_DEFAULT_PRECIS, // clipping precision - ANTIALIASED_QUALITY, // output quality - FF_DONTCARE or DEFAULT_PITCH, // pitch and family - FontName); // font - SelectObject(DC, font); // Sets the new font as the current font in the device context - wglUseFontBitmaps(DC, 32, 224, Result); // Creates a set display lists containing the bitmap fonts -end; - -procedure e_SimpleFontFree(Font: DWORD); +procedure e_Clear(Mask: TGLbitfield; Red, Green, Blue: Single); overload; begin - glDeleteLists(Font, 223); // Delete the font display lists, returning used memory + if e_NoGraphics then Exit; + glClearColor(Red, Green, Blue, 0); + glClear(Mask); end; -procedure e_SimpleFontPrint(X, Y: SmallInt; Text: PChar; Font: Integer; Red, Green, Blue: Byte); +procedure e_Clear(); overload; begin - glPopAttrib(); // Rendering bug workaround - - glColor3ub(Red, Green, Blue); - glDisable(GL_TEXTURE_2D); // Turn off textures, don't want our text textured - glRasterPos2i(X, Y); // Position the Text - glPushAttrib(GL_LIST_BIT); // Save's the current base list - glListBase(DWORD(Font-32)); // Set the base list to our character list - glCallLists(Length(Text), GL_UNSIGNED_BYTE, Text); // Display the text - glPopAttrib(); // Restore the old base list + if e_NoGraphics then Exit; + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); end; -procedure e_SimpleFontPrintEx(X, Y: SmallInt; Text: PChar; Font: DWORD; Red, Green, Blue, - sRed, sGreen, sBlue, sWidth: Byte); +procedure e_EndRender(); begin - e_SimpleFontPrint(X, Y, Text, Font, Red, Green, Blue); - e_SimpleFontPrint(X+sWidth, Y+sWidth, Text, Font, sRed, sGreen, sBlue); + if e_NoGraphics then Exit; + glPopMatrix(); end; function e_CharFont_Create(sp: ShortInt=0): DWORD; @@ -1096,6 +941,7 @@ procedure e_CharFont_Print(FontID: DWORD; X, Y: Integer; Text: string); var a: Integer; begin + if e_NoGraphics then Exit; if Text = '' then Exit; if e_CharFonts = nil then Exit; if Integer(FontID) > High(e_CharFonts) then Exit; @@ -1118,6 +964,7 @@ var a: Integer; c: TRGB; begin + if e_NoGraphics then Exit; if Text = '' then Exit; if e_CharFonts = nil then Exit; if Integer(FontID) > High(e_CharFonts) then Exit; @@ -1152,6 +999,7 @@ var tc, c: TRGB; w, h: Word; begin + if e_NoGraphics then Exit; if Text = '' then Exit; if e_CharFonts = nil then Exit; if Integer(FontID) > High(e_CharFonts) then Exit; @@ -1356,18 +1204,19 @@ begin if e_CharFonts = nil then Exit; for a := 0 to High(e_CharFonts) do - e_CharFont_Remove(a); + e_CharFont_Remove(a); e_CharFonts := nil; end; -procedure e_TextureFontBuild(Texture: DWORD; var FontID: DWORD; XCount, YCount: Word; +procedure e_TextureFontBuild(Tex: DWORD; var FontID: DWORD; XCount, YCount: Word; Space: ShortInt=0); var loop1 : GLuint; cx, cy : real; i, id: DWORD; begin + if e_NoGraphics then Exit; e_WriteLog('Creating texture font...', MSG_NOTIFY); id := DWORD(-1); @@ -1389,33 +1238,37 @@ begin with e_TextureFonts[id] do begin Base := glGenLists(XCount*YCount); - TextureID := e_Textures[Texture].ID; - CharWidth := (e_Textures[Texture].Width div XCount)+Space; - CharHeight := e_Textures[Texture].Height div YCount; + TextureID := e_Textures[Tex].tx.id; + CharWidth := (e_Textures[Tex].tx.Width div XCount)+Space; + CharHeight := e_Textures[Tex].tx.Height div YCount; + XC := XCount; + YC := YCount; + Texture := Tex; + SPC := Space; end; - - glBindTexture(GL_TEXTURE_2D, e_Textures[Texture].ID); + + glBindTexture(GL_TEXTURE_2D, e_Textures[Tex].tx.id); for loop1 := 0 to XCount*YCount-1 do begin cx := (loop1 mod XCount)/XCount; - cy := (loop1 div YCount)/YCount; + cy := (loop1 div YCount)/YCount; - glNewList(e_TextureFonts[id].Base+loop1, GL_COMPILE); - glBegin(GL_QUADS); + glNewList(e_TextureFonts[id].Base+loop1, GL_COMPILE); + glBegin(GL_QUADS); glTexCoord2f(cx, 1.0-cy-1/YCount); - glVertex2d(0, e_Textures[Texture].Height div YCount); + glVertex2d(0, e_Textures[Tex].tx.Height div YCount); - glTexCoord2f(cx+1/XCount, 1.0-cy-1/YCount); - glVertex2i(e_Textures[Texture].Width div XCount, e_Textures[Texture].Height div YCount); + glTexCoord2f(cx+1/XCount, 1.0-cy-1/YCount); + glVertex2i(e_Textures[Tex].tx.Width div XCount, e_Textures[Tex].tx.Height div YCount); - glTexCoord2f(cx+1/XCount, 1.0-cy); - glVertex2i(e_Textures[Texture].Width div XCount, 0); + glTexCoord2f(cx+1/XCount, 1.0-cy); + glVertex2i(e_Textures[Tex].tx.Width div XCount, 0); - glTexCoord2f(cx, 1.0-cy); + glTexCoord2f(cx, 1.0-cy); glVertex2i(0, 0); glEnd(); - glTranslated((e_Textures[Texture].Width div XCount)+Space, 0, 0); - glEndList(); + glTranslated((e_Textures[Tex].tx.Width div XCount)+Space, 0, 0); + glEndList(); end; FontID := id; @@ -1423,12 +1276,14 @@ end; procedure e_TextureFontKill(FontID: DWORD); begin - glDeleteLists(e_TextureFonts[FontID].Base, 256); + if e_NoGraphics then Exit; + glDeleteLists(e_TextureFonts[FontID].Base, 256); e_TextureFonts[FontID].Base := 0; end; procedure e_TextureFontPrint(X, Y: GLint; Text: string; FontID: DWORD); begin + if e_NoGraphics then Exit; if Integer(FontID) > High(e_TextureFonts) then Exit; if Text = '' then Exit; @@ -1452,6 +1307,7 @@ end; // god forgive me for this, but i cannot figure out how to do it without lists procedure e_TextureFontPrintChar(X, Y: Integer; Ch: Char; FontID: DWORD; Shadow: Boolean = False); begin + if e_NoGraphics then Exit; glPushMatrix; if Shadow then @@ -1470,12 +1326,31 @@ begin glPopMatrix; end; +procedure e_TextureFontPrintCharEx (X, Y: Integer; Ch: Char; FontID: DWORD; Shadow: Boolean = False); +begin + glBindTexture(GL_TEXTURE_2D, e_TextureFonts[FontID].TextureID); + glEnable(GL_TEXTURE_2D); + //glListBase(DWORD(Integer(e_TextureFonts[FontID].Base)-32)); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + e_TextureFontPrintChar(X, Y, Ch, FontID, Shadow); + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); +end; + +function e_TextureFontCharWidth (ch: Char; FontID: DWORD): Integer; +begin + result := e_TextureFonts[FontID].CharWidth; +end; + procedure e_TextureFontPrintFmt(X, Y: Integer; Text: string; FontID: DWORD; Shadow: Boolean = False); var a, TX, TY, len: Integer; tc, c: TRGB; w: Word; begin + if e_NoGraphics then Exit; if Text = '' then Exit; if e_TextureFonts = nil then Exit; if Integer(FontID) > High(e_TextureFonts) then Exit; @@ -1565,6 +1440,7 @@ end; procedure e_TextureFontPrintEx(X, Y: GLint; Text: string; FontID: DWORD; Red, Green, Blue: Byte; Scale: Single; Shadow: Boolean = False); begin + if e_NoGraphics then Exit; if Text = '' then Exit; glPushMatrix; @@ -1598,6 +1474,9 @@ end; procedure e_TextureFontGetSize(ID: DWORD; var CharWidth, CharHeight: Byte); begin + CharWidth := 16; + CharHeight := 16; + if e_NoGraphics then Exit; if Integer(ID) > High(e_TextureFonts) then Exit; CharWidth := e_TextureFonts[ID].CharWidth; @@ -1608,6 +1487,7 @@ procedure e_RemoveAllTextureFont(); var i: integer; begin + if e_NoGraphics then Exit; if e_TextureFonts = nil then Exit; for i := 0 to High(e_TextureFonts) do @@ -1641,6 +1521,12 @@ begin Result.Height := Height; end; +function _TRect(L, T, R, B: LongInt): TRectE; +begin + Result.Top := T; + Result.Left := L; + Result.Right := R; + Result.Bottom := B; +end; end. -