Combine OpenGLApi/Direct3D9Api

This commit is contained in:
UnknownShadow200 2018-10-10 20:01:44 +11:00
parent 0a29a21d07
commit 8782d254ac
37 changed files with 1392 additions and 1414 deletions

View file

@ -47,7 +47,7 @@ namespace OpenTK {
public static readonly Vector3 UnitZ = new Vector3(0, 0, 1);
public static readonly Vector3 Zero = new Vector3(0, 0, 0);
public static readonly Vector3 One = new Vector3(1, 1, 1);
public static readonly Vector3 One = new Vector3(1, 1, 1);
public static Vector3 Lerp(Vector3 a, Vector3 b, float blend) {
a.X = blend * (b.X - a.X) + a.X;

View file

@ -4,7 +4,7 @@
#include "Platform.h"
#include "Event.h"
#include "Funcs.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Chat.h"
#include "World.h"
#include "Options.h"

View file

@ -1,5 +1,5 @@
#include "AxisLinesRenderer.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Game.h"
#include "GraphicsCommon.h"
#include "SelectionBox.h"

View file

@ -5,7 +5,7 @@
#include "Lighting.h"
#include "Platform.h"
#include "MapRenderer.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "ErrorHandler.h"
#include "Drawer.h"
#include "ExtMath.h"

View file

@ -2,7 +2,7 @@
#include "ExtMath.h"
#include "Game.h"
#include "Window.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Funcs.h"
#include "Gui.h"
#include "Entity.h"

View file

@ -9,13 +9,16 @@
#include "Inventory.h"
#include "Entity.h"
#include "Window.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "GraphicsCommon.h"
#include "Funcs.h"
#include "Block.h"
#include "EnvRenderer.h"
#include "GameStructs.h"
/*########################################################################################################################*
*-------------------------------------------------------Chat logging------------------------------------------------------*
*#########################################################################################################################*/
#define CHAT_LOGTIMES_DEF_ELEMS 256
TimeMS Chat_DefaultLogTimes[CHAT_LOGTIMES_DEF_ELEMS];
TimeMS* Chat_LogTimes = Chat_DefaultLogTimes;
@ -36,12 +39,6 @@ static void Chat_AppendLogTime(void) {
Chat_LogTimes[Chat_LogTimesCount++] = now;
}
static void ChatLine_Make(struct ChatLine* line, const String* text) {
String dst = String_ClearedArray(line->Buffer);
String_AppendString(&dst, text);
line->Received = DateTime_CurrentUTC_MS();
}
char Chat_LogNameBuffer[STRING_SIZE];
String Chat_LogName = String_FromArray(Chat_LogNameBuffer);
char Chat_LogPathBuffer[FILENAME_SIZE];
@ -141,6 +138,12 @@ static void Chat_AppendLog(const String* text) {
Chat_LogError2(res, "writing to", &Chat_LogPath);
}
static void ChatLine_Make(struct ChatLine* line, const String* text) {
String dst = String_ClearedArray(line->Buffer);
String_AppendString(&dst, text);
line->Received = DateTime_CurrentUTC_MS();
}
void Chat_LogError(ReturnCode result, const char* place) {
Chat_Add4("&cError %h when %c", &result, place, NULL, NULL);
}

View file

@ -4,7 +4,7 @@
#include "ExtMath.h"
#include "Funcs.h"
#include "Game.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Entity.h"
#include "MapRenderer.h"
#include "Platform.h"

View file

@ -241,7 +241,7 @@
<ClInclude Include="Funcs.h" />
<ClInclude Include="Game.h" />
<ClInclude Include="ExtMath.h" />
<ClInclude Include="GraphicsAPI.h" />
<ClInclude Include="Graphics.h" />
<ClInclude Include="GraphicsCommon.h" />
<ClInclude Include="Platform.h" />
<ClInclude Include="String.h" />
@ -262,7 +262,6 @@
<ClCompile Include="Builder.c" />
<ClCompile Include="Chat.c" />
<ClCompile Include="ChunkUpdater.c" />
<ClCompile Include="D3D9Api.c" />
<ClCompile Include="Bitmap.c" />
<ClCompile Include="DisplayDevice.c" />
<ClCompile Include="Drawer.c" />
@ -273,6 +272,7 @@
<ClCompile Include="ExtMath.c" />
<ClCompile Include="Formats.c" />
<ClCompile Include="Game.c" />
<ClCompile Include="Graphics.c" />
<ClCompile Include="Gui.c" />
<ClCompile Include="HeldBlockRenderer.c" />
<ClCompile Include="InputHandler.c" />
@ -290,7 +290,6 @@
<ClCompile Include="Entity.c" />
<ClCompile Include="MapRenderer.c" />
<ClCompile Include="ModelCache.c" />
<ClCompile Include="OpenGLApi.c" />
<ClCompile Include="Options.c" />
<ClCompile Include="PackedCol.c" />
<ClCompile Include="GraphicsCommon.c" />

View file

@ -141,9 +141,6 @@
<ClInclude Include="ExtMath.h">
<Filter>Header Files\Math</Filter>
</ClInclude>
<ClInclude Include="GraphicsAPI.h">
<Filter>Header Files\Graphics</Filter>
</ClInclude>
<ClInclude Include="GraphicsCommon.h">
<Filter>Header Files\Graphics</Filter>
</ClInclude>
@ -315,6 +312,9 @@
<ClInclude Include="BlockPhysics.h">
<Filter>Header Files\Blocks</Filter>
</ClInclude>
<ClInclude Include="Graphics.h">
<Filter>Header Files\Graphics</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="String.c">
@ -338,9 +338,6 @@
<ClCompile Include="World.c">
<Filter>Source Files\Map</Filter>
</ClCompile>
<ClCompile Include="D3D9Api.c">
<Filter>Source Files\Graphics</Filter>
</ClCompile>
<ClCompile Include="PackedCol.c">
<Filter>Source Files\2D\Utils</Filter>
</ClCompile>
@ -395,9 +392,6 @@
<ClCompile Include="Deflate.c">
<Filter>Source Files\IO</Filter>
</ClCompile>
<ClCompile Include="OpenGLApi.c">
<Filter>Source Files\Graphics</Filter>
</ClCompile>
<ClCompile Include="Formats.c">
<Filter>Source Files\Map</Filter>
</ClCompile>
@ -578,5 +572,8 @@
<ClCompile Include="_ftcache.c">
<Filter>Source Files\Freetype</Filter>
</ClCompile>
<ClCompile Include="Graphics.c">
<Filter>Source Files\Graphics</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -1,721 +0,0 @@
#include "GraphicsAPI.h"
#ifdef CC_BUILD_D3D9
#include "ErrorHandler.h"
#include "Platform.h"
#include "Window.h"
#include "GraphicsCommon.h"
#include "Funcs.h"
#include "Game.h"
#include "ExtMath.h"
#include "Bitmap.h"
#include "Event.h"
//#define D3D_DISABLE_9EX causes compile errors
#ifdef CC_BUILD_WIN
#define WIN32_LEAN_AND_MEAN
#define NOSERVICE
#define NOMCX
#define NOIME
#endif
#include <d3d9.h>
#include <d3d9caps.h>
#include <d3d9types.h>
int Gfx_strideSizes[2] = GFX_STRIDE_SIZES;
D3DFORMAT d3d9_depthFormats[6] = { D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D16, D3DFMT_D15S1 };
D3DFORMAT d3d9_viewFormats[4] = { D3DFMT_X8R8G8B8, D3DFMT_R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 };
D3DBLEND d3d9_blendFuncs[6] = { D3DBLEND_ZERO, D3DBLEND_ONE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA, D3DBLEND_DESTALPHA, D3DBLEND_INVDESTALPHA };
D3DCMPFUNC d3d9_compareFuncs[8] = { D3DCMP_ALWAYS, D3DCMP_NOTEQUAL, D3DCMP_NEVER, D3DCMP_LESS, D3DCMP_LESSEQUAL, D3DCMP_EQUAL, D3DCMP_GREATEREQUAL, D3DCMP_GREATER };
D3DFOGMODE d3d9_modes[3] = { D3DFOG_LINEAR, D3DFOG_EXP, D3DFOG_EXP2 };
DWORD d3d9_formatMappings[2] = { D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2 };
bool d3d9_vsync;
IDirect3D9* d3d;
IDirect3DDevice9* device;
D3DTRANSFORMSTATETYPE curMatrix;
DWORD createFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
D3DFORMAT d3d9_viewFormat, d3d9_depthFormat;
#define D3D9_SetRenderState(state, value, name) \
ReturnCode res = IDirect3DDevice9_SetRenderState(device, state, value); if (res) ErrorHandler_Fail2(res, name);
#define D3D9_SetRenderState2(state, value, name) \
res = IDirect3DDevice9_SetRenderState(device, state, value); if (res) ErrorHandler_Fail2(res, name);
/* Forward declarations for these two functions. */
static void D3D9_SetDefaultRenderStates(void);
static void D3D9_RestoreRenderStates(void);
static void D3D9_FreeResource(GfxResourceID* resource) {
if (!resource || *resource == GFX_NULL) return;
IUnknown* unk = (IUnknown*)(*resource);
ULONG refCount = unk->lpVtbl->Release(unk);
*resource = GFX_NULL;
if (refCount <= 0) return;
uintptr_t addr = (uintptr_t)unk;
Platform_Log2("D3D9 resource has %i outstanding references! ID 0x%x", &refCount, &addr);
}
static void D3D9_LoopUntilRetrieved(void) {
struct ScheduledTask task;
task.Interval = 1.0f / 60.0f;
task.Callback = Gfx_LostContextFunction;
while (true) {
Thread_Sleep(16);
ReturnCode code = IDirect3DDevice9_TestCooperativeLevel(device);
if (code == D3DERR_DEVICENOTRESET) return;
task.Callback(&task);
}
}
static void D3D9_FindCompatibleFormat(void) {
int i, count = Array_Elems(d3d9_viewFormats);
ReturnCode res;
for (i = 0; i < count; i++) {
d3d9_viewFormat = d3d9_viewFormats[i];
res = IDirect3D9_CheckDeviceType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d9_viewFormat, d3d9_viewFormat, true);
if (!res) break;
if (i == count - 1) {
ErrorHandler_Fail("Unable to create a back buffer with sufficient precision.");
}
}
count = Array_Elems(d3d9_depthFormats);
for (i = 0; i < count; i++) {
d3d9_depthFormat = d3d9_depthFormats[i];
res = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d9_viewFormat, d3d9_viewFormat, d3d9_depthFormat);
if (!res) break;
if (i == count - 1) {
ErrorHandler_Fail("Unable to create a depth buffer with sufficient precision.");
}
}
}
static void D3D9_FillPresentArgs(int width, int height, D3DPRESENT_PARAMETERS* args) {
args->AutoDepthStencilFormat = d3d9_depthFormat;
args->BackBufferWidth = width;
args->BackBufferHeight = height;
args->BackBufferFormat = d3d9_viewFormat;
args->BackBufferCount = 1;
args->EnableAutoDepthStencil = true;
args->PresentationInterval = d3d9_vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
args->SwapEffect = D3DSWAPEFFECT_DISCARD;
args->Windowed = true;
}
static void D3D9_RecreateDevice(void) {
D3DPRESENT_PARAMETERS args = { 0 };
D3D9_FillPresentArgs(Game_Width, Game_Height, &args);
while (IDirect3DDevice9_Reset(device, &args) == D3DERR_DEVICELOST) {
D3D9_LoopUntilRetrieved();
}
D3D9_SetDefaultRenderStates();
D3D9_RestoreRenderStates();
GfxCommon_RecreateContext();
}
void Gfx_Init(void) {
Gfx_MinZNear = 0.05f;
void* winHandle = Window_GetWindowHandle();
d3d = Direct3DCreate9(D3D_SDK_VERSION);
D3D9_FindCompatibleFormat();
D3DPRESENT_PARAMETERS args = { 0 };
D3D9_FillPresentArgs(640, 480, &args);
ReturnCode res;
/* Try to create a device with as much hardware usage as possible. */
res = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, winHandle, createFlags, &args, &device);
if (res) {
createFlags = D3DCREATE_MIXED_VERTEXPROCESSING;
res = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, winHandle, createFlags, &args, &device);
}
if (res) {
createFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
res = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, winHandle, createFlags, &args, &device);
}
if (res) ErrorHandler_Fail2(res, "Creating Direct3D9 device");
D3DCAPS9 caps;
res = IDirect3DDevice9_GetDeviceCaps(device, &caps);
if (res) ErrorHandler_Fail2(res, "Getting Direct3D9 capabilities");
Gfx_MaxTexWidth = caps.MaxTextureWidth;
Gfx_MaxTexHeight = caps.MaxTextureHeight;
Gfx_CustomMipmapsLevels = true;
D3D9_SetDefaultRenderStates();
GfxCommon_Init();
}
void Gfx_Free(void) {
GfxCommon_Free();
D3D9_FreeResource(&device);
D3D9_FreeResource(&d3d);
}
static void D3D9_SetTextureData(IDirect3DTexture9* texture, Bitmap* bmp, int lvl) {
D3DLOCKED_RECT rect;
ReturnCode res = IDirect3DTexture9_LockRect(texture, lvl, &rect, NULL, 0);
if (res) ErrorHandler_Fail2(res, "D3D9_SetTextureData - Lock");
uint32_t size = Bitmap_DataSize(bmp->Width, bmp->Height);
Mem_Copy(rect.pBits, bmp->Scan0, size);
res = IDirect3DTexture9_UnlockRect(texture, lvl);
if (res) ErrorHandler_Fail2(res, "D3D9_SetTextureData - Unlock");
}
static void D3D9_SetTexturePartData(IDirect3DTexture9* texture, int x, int y, Bitmap* bmp, int lvl) {
RECT part;
part.left = x; part.right = x + bmp->Width;
part.top = y; part.bottom = y + bmp->Height;
D3DLOCKED_RECT rect;
ReturnCode res = IDirect3DTexture9_LockRect(texture, lvl, &rect, &part, 0);
if (res) ErrorHandler_Fail2(res, "D3D9_SetTexturePartData - Lock");
/* We need to copy scanline by scanline, as generally rect.stride != data.stride */
uint8_t* src = (uint8_t*)bmp->Scan0;
uint8_t* dst = (uint8_t*)rect.pBits;
int yy;
uint32_t stride = (uint32_t)(bmp->Width) * BITMAP_SIZEOF_PIXEL;
for (yy = 0; yy < bmp->Height; yy++) {
Mem_Copy(dst, src, stride);
src += stride;
dst += rect.Pitch;
}
res = IDirect3DTexture9_UnlockRect(texture, lvl);
if (res) ErrorHandler_Fail2(res, "D3D9_SetTexturePartData - Unlock");
}
static void D3D9_DoMipmaps(IDirect3DTexture9* texture, int x, int y, Bitmap* bmp, bool partial) {
uint8_t* prev = bmp->Scan0;
int lvls = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height);
int lvl, width = bmp->Width, height = bmp->Height;
for (lvl = 1; lvl <= lvls; lvl++) {
x /= 2; y /= 2;
if (width > 1) width /= 2;
if (height > 1) height /= 2;
uint8_t* cur = Mem_Alloc(width * height, BITMAP_SIZEOF_PIXEL, "mipmaps");
GfxCommon_GenMipmaps(width, height, cur, prev);
Bitmap mipmap;
Bitmap_Create(&mipmap, width, height, cur);
if (partial) {
D3D9_SetTexturePartData(texture, x, y, &mipmap, lvl);
} else {
D3D9_SetTextureData(texture, &mipmap, lvl);
}
if (prev != bmp->Scan0) Mem_Free(prev);
prev = cur;
}
if (prev != bmp->Scan0) Mem_Free(prev);
}
GfxResourceID Gfx_CreateTexture(Bitmap* bmp, bool managedPool, bool mipmaps) {
IDirect3DTexture9* tex;
ReturnCode res;
int mipmapsLevels = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height);
int levels = 1 + (mipmaps ? mipmapsLevels : 0);
if (!Math_IsPowOf2(bmp->Width) || !Math_IsPowOf2(bmp->Height)) {
ErrorHandler_Fail("Textures must have power of two dimensions");
}
if (managedPool) {
res = IDirect3DDevice9_CreateTexture(device, bmp->Width, bmp->Height, levels,
0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex, NULL);
if (res) ErrorHandler_Fail2(res, "D3D9_CreateTexture");
D3D9_SetTextureData(tex, bmp, 0);
if (mipmaps) D3D9_DoMipmaps(tex, 0, 0, bmp, false);
} else {
IDirect3DTexture9* sys;
res = IDirect3DDevice9_CreateTexture(device, bmp->Width, bmp->Height, levels,
0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &sys, NULL);
if (res) ErrorHandler_Fail2(res, "D3D9_CreateTexture - SystemMem");
D3D9_SetTextureData(sys, bmp, 0);
if (mipmaps) D3D9_DoMipmaps(sys, 0, 0, bmp, false);
res = IDirect3DDevice9_CreateTexture(device, bmp->Width, bmp->Height, levels,
0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
if (res) ErrorHandler_Fail2(res, "D3D9_CreateTexture - GPU");
res = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9*)sys, (IDirect3DBaseTexture9*)tex);
if (res) ErrorHandler_Fail2(res, "D3D9_CreateTexture - Update");
D3D9_FreeResource(&sys);
}
return tex;
}
void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, Bitmap* part, bool mipmaps) {
IDirect3DTexture9* texture = (IDirect3DTexture9*)texId;
D3D9_SetTexturePartData(texture, x, y, part, 0);
if (mipmaps) D3D9_DoMipmaps(texture, x, y, part, true);
}
void Gfx_BindTexture(GfxResourceID texId) {
ReturnCode res = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9*)texId);
if (res) ErrorHandler_Fail2(res, "D3D9_BindTexture");
}
void Gfx_DeleteTexture(GfxResourceID* texId) { D3D9_FreeResource(texId); }
void Gfx_SetTexturing(bool enabled) {
if (enabled) return;
ReturnCode res = IDirect3DDevice9_SetTexture(device, 0, NULL);
if (res) ErrorHandler_Fail2(res, "D3D9_SetTexturing");
}
void Gfx_EnableMipmaps(void) {
if (Gfx_Mipmaps) {
ReturnCode res = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
if (res) ErrorHandler_Fail2(res, "D3D9_EnableMipmaps");
}
}
void Gfx_DisableMipmaps(void) {
if (Gfx_Mipmaps) {
ReturnCode res = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
if (res) ErrorHandler_Fail2(res, "D3D9_DisableMipmaps");
}
}
bool d3d9_fogEnable = false;
bool Gfx_GetFog(void) { return d3d9_fogEnable; }
void Gfx_SetFog(bool enabled) {
if (d3d9_fogEnable == enabled) return;
d3d9_fogEnable = enabled;
if (Gfx_LostContext) return;
D3D9_SetRenderState(D3DRS_FOGENABLE, (uint32_t)enabled, "D3D9_SetFog");
}
uint32_t d3d9_fogCol = 0xFF000000; /* black */
void Gfx_SetFogCol(PackedCol col) {
if (col.Packed == d3d9_fogCol) return;
d3d9_fogCol = col.Packed;
if (Gfx_LostContext) return;
D3D9_SetRenderState(D3DRS_FOGCOLOR, col.Packed, "D3D9_SetFogColour");
}
float d3d9_fogDensity = -1.0f;
void Gfx_SetFogDensity(float value) {
if (value == d3d9_fogDensity) return;
d3d9_fogDensity = value;
if (Gfx_LostContext) return;
union IntAndFloat raw; raw.f = value;
D3D9_SetRenderState(D3DRS_FOGDENSITY, raw.u, "D3D9_SetFogDensity");
}
float d3d9_fogEnd = -1.0f;
void Gfx_SetFogEnd(float value) {
if (value == d3d9_fogEnd) return;
d3d9_fogEnd = value;
if (Gfx_LostContext) return;
union IntAndFloat raw; raw.f = value;
D3D9_SetRenderState(D3DRS_FOGEND, raw.u, "D3D9_SetFogEnd");
}
D3DFOGMODE d3d9_fogTableMode = D3DFOG_NONE;
void Gfx_SetFogMode(int fogMode) {
D3DFOGMODE mode = d3d9_modes[fogMode];
if (mode == d3d9_fogTableMode) return;
d3d9_fogTableMode = mode;
if (Gfx_LostContext) return;
D3D9_SetRenderState(D3DRS_FOGTABLEMODE, mode, "D3D9_SetFogMode");
}
void Gfx_SetFaceCulling(bool enabled) {
D3DCULL mode = enabled ? D3DCULL_CW : D3DCULL_NONE;
D3D9_SetRenderState(D3DRS_CULLMODE, mode, "D3D9_SetFaceCulling");
}
bool d3d9_alphaTest = false;
void Gfx_SetAlphaTest(bool enabled) {
if (d3d9_alphaTest == enabled) return;
d3d9_alphaTest = enabled;
D3D9_SetRenderState(D3DRS_ALPHATESTENABLE, (uint32_t)enabled, "D3D9_SetAlphaTest");
}
D3DCMPFUNC d3d9_alphaTestFunc = D3DCMP_ALWAYS;
int d3d9_alphaTestRef = 0;
void Gfx_SetAlphaTestFunc(int compareFunc, float refValue) {
d3d9_alphaTestFunc = d3d9_compareFuncs[compareFunc];
D3D9_SetRenderState(D3DRS_ALPHAFUNC, d3d9_alphaTestFunc, "D3D9_SetAlphaTest_Func");
d3d9_alphaTestRef = (int)(refValue * 255);
D3D9_SetRenderState2(D3DRS_ALPHAREF, d3d9_alphaTestRef, "D3D9_SetAlphaTest_Ref");
}
bool d3d9_alphaBlend = false;
void Gfx_SetAlphaBlending(bool enabled) {
if (d3d9_alphaBlend == enabled) return;
d3d9_alphaBlend = enabled;
D3D9_SetRenderState(D3DRS_ALPHABLENDENABLE, (uint32_t)enabled, "D3D9_SetAlphaBlending");
}
D3DBLEND d3d9_srcBlendFunc = D3DBLEND_ONE;
D3DBLEND d3d9_dstBlendFunc = D3DBLEND_ZERO;
void Gfx_SetAlphaBlendFunc(int srcBlendFunc, int dstBlendFunc) {
d3d9_srcBlendFunc = d3d9_blendFuncs[srcBlendFunc];
D3D9_SetRenderState(D3DRS_SRCBLEND, d3d9_srcBlendFunc, "D3D9_SetAlphaBlendFunc_Src");
d3d9_dstBlendFunc = d3d9_blendFuncs[dstBlendFunc];
D3D9_SetRenderState2(D3DRS_DESTBLEND, d3d9_dstBlendFunc, "D3D9_SetAlphaBlendFunc_Dst");
}
void Gfx_SetAlphaArgBlend(bool enabled) {
D3DTEXTUREOP op = enabled ? D3DTOP_MODULATE : D3DTOP_SELECTARG1;
ReturnCode res = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, op);
if (res) ErrorHandler_Fail2(res, "D3D9_SetAlphaArgBlend");
}
uint32_t d3d9_clearCol = 0xFF000000;
void Gfx_Clear(void) {
DWORD flags = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER;
ReturnCode res = IDirect3DDevice9_Clear(device, 0, NULL, flags, d3d9_clearCol, 1.0f, 0);
if (res) ErrorHandler_Fail2(res, "D3D9_Clear");
}
void Gfx_ClearCol(PackedCol col) {
d3d9_clearCol = col.Packed;
}
bool d3d9_depthTest = false;
void Gfx_SetDepthTest(bool enabled) {
d3d9_depthTest = enabled;
D3D9_SetRenderState(D3DRS_ZENABLE, (uint32_t)enabled, "D3D9_SetDepthTest");
}
D3DCMPFUNC d3d9_depthTestFunc = D3DCMP_LESSEQUAL;
void Gfx_SetDepthTestFunc(int compareFunc) {
d3d9_depthTestFunc = d3d9_compareFuncs[compareFunc];
D3D9_SetRenderState(D3DRS_ZFUNC, d3d9_alphaTestFunc, "D3D9_SetDepthTestFunc");
}
void Gfx_SetColourWriteMask(bool r, bool g, bool b, bool a) {
uint32_t channels = (r ? 1u : 0u) | (g ? 2u : 0u) | (b ? 4u : 0u) | (a ? 8u : 0u);
D3D9_SetRenderState(D3DRS_COLORWRITEENABLE, channels, "D3D9_SetColourWrite");
}
bool d3d9_depthWrite = false;
void Gfx_SetDepthWrite(bool enabled) {
d3d9_depthWrite = enabled;
D3D9_SetRenderState(D3DRS_ZWRITEENABLE, (uint32_t)enabled, "D3D9_SetDepthWrite");
}
GfxResourceID Gfx_CreateDynamicVb(int vertexFormat, int maxVertices) {
int size = maxVertices * Gfx_strideSizes[vertexFormat];
IDirect3DVertexBuffer9* vbuffer;
ReturnCode res = IDirect3DDevice9_CreateVertexBuffer(device, size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
d3d9_formatMappings[vertexFormat], D3DPOOL_DEFAULT, &vbuffer, NULL);
if (res) ErrorHandler_Fail2(res, "D3D9_CreateDynamicVb");
return vbuffer;
}
static void D3D9_SetVbData(IDirect3DVertexBuffer9* buffer, void* data, int size, const char* lockMsg, const char* unlockMsg, int lockFlags) {
void* dst = NULL;
ReturnCode res = IDirect3DVertexBuffer9_Lock(buffer, 0, size, &dst, lockFlags);
if (res) ErrorHandler_Fail2(res, lockMsg);
Mem_Copy(dst, data, size);
res = IDirect3DVertexBuffer9_Unlock(buffer);
if (res) ErrorHandler_Fail2(res, unlockMsg);
}
GfxResourceID Gfx_CreateVb(void* vertices, int vertexFormat, int count) {
int size = count * Gfx_strideSizes[vertexFormat];
IDirect3DVertexBuffer9* vbuffer;
for (;;) {
ReturnCode res = IDirect3DDevice9_CreateVertexBuffer(device, size, D3DUSAGE_WRITEONLY,
d3d9_formatMappings[vertexFormat], D3DPOOL_DEFAULT, &vbuffer, NULL);
if (!res) break;
if (res != D3DERR_OUTOFVIDEOMEMORY) ErrorHandler_Fail2(res, "D3D9_CreateVb");
Event_RaiseVoid(&GfxEvents_LowVRAMDetected);
}
D3D9_SetVbData(vbuffer, vertices, size, "D3D9_CreateVb - Lock", "D3D9_CreateVb - Unlock", 0);
return vbuffer;
}
static void D3D9_SetIbData(IDirect3DIndexBuffer9* buffer, void* data, int size) {
void* dst = NULL;
ReturnCode res = IDirect3DIndexBuffer9_Lock(buffer, 0, size, &dst, 0);
if (res) ErrorHandler_Fail2(res, "D3D9_CreateIb - Lock");
Mem_Copy(dst, data, size);
res = IDirect3DIndexBuffer9_Unlock(buffer);
if (res) ErrorHandler_Fail2(res, "D3D9_CreateIb - Unlock");
}
GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) {
int size = indicesCount * 2;
IDirect3DIndexBuffer9* ibuffer;
ReturnCode res = IDirect3DDevice9_CreateIndexBuffer(device, size, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ibuffer, NULL);
if (res) ErrorHandler_Fail2(res, "D3D9_CreateIb");
D3D9_SetIbData(ibuffer, indices, size);
return ibuffer;
}
int d3d9_batchStride;
void Gfx_BindVb(GfxResourceID vb) {
IDirect3DVertexBuffer9* vbuffer = (IDirect3DVertexBuffer9*)vb;
ReturnCode res = IDirect3DDevice9_SetStreamSource(device, 0, vbuffer, 0, d3d9_batchStride);
if (res) ErrorHandler_Fail2(res, "D3D9_BindVb");
}
void Gfx_BindIb(GfxResourceID ib) {
IDirect3DIndexBuffer9* ibuffer = (IDirect3DIndexBuffer9*)ib;
ReturnCode res = IDirect3DDevice9_SetIndices(device, ibuffer);
if (res) ErrorHandler_Fail2(res, "D3D9_BindIb");
}
void Gfx_DeleteVb(GfxResourceID* vb) { D3D9_FreeResource(vb); }
void Gfx_DeleteIb(GfxResourceID* ib) { D3D9_FreeResource(ib); }
int d3d9_batchFormat = -1;
void Gfx_SetBatchFormat(int format) {
if (format == d3d9_batchFormat) return;
d3d9_batchFormat = format;
ReturnCode res = IDirect3DDevice9_SetFVF(device, d3d9_formatMappings[format]);
if (res) ErrorHandler_Fail2(res, "D3D9_SetBatchFormat");
d3d9_batchStride = Gfx_strideSizes[format];
}
void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
int size = vCount * d3d9_batchStride;
IDirect3DVertexBuffer9* vbuffer = (IDirect3DVertexBuffer9*)vb;
D3D9_SetVbData(vbuffer, vertices, size, "D3D9_SetDynamicVbData - Lock", "D3D9_SetDynamicVbData - Unlock", D3DLOCK_DISCARD);
ReturnCode res = IDirect3DDevice9_SetStreamSource(device, 0, vbuffer, 0, d3d9_batchStride);
if (res) ErrorHandler_Fail2(res, "D3D9_SetDynamicVbData - Bind");
}
void Gfx_DrawVb_Lines(int verticesCount) {
ReturnCode res = IDirect3DDevice9_DrawPrimitive(device, D3DPT_LINELIST, 0, verticesCount >> 1);
if (res) ErrorHandler_Fail2(res, "D3D9_DrawVb_Lines");
}
void Gfx_DrawVb_IndexedTris(int verticesCount) {
ReturnCode res = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
0, 0, verticesCount, 0, verticesCount >> 1);
if (res) ErrorHandler_Fail2(res, "D3D9_DrawVb_IndexedTris");
}
void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
ReturnCode res = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
startVertex, 0, verticesCount, 0, verticesCount >> 1);
if (res) ErrorHandler_Fail2(res, "D3D9_DrawVb_IndexedTris");
}
void Gfx_DrawIndexedVb_TrisT2fC4b(int verticesCount, int startVertex) {
ReturnCode res = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
startVertex, 0, verticesCount, 0, verticesCount >> 1);
if (res) ErrorHandler_Fail2(res, "D3D9_DrawIndexedVb_TrisT2fC4b");
}
void Gfx_SetMatrixMode(int matrixType) {
if (matrixType == MATRIX_TYPE_PROJECTION) {
curMatrix = D3DTS_PROJECTION;
} else if (matrixType == MATRIX_TYPE_VIEW) {
curMatrix = D3DTS_VIEW;
} else if (matrixType == MATRIX_TYPE_TEXTURE) {
curMatrix = D3DTS_TEXTURE0;
}
}
void Gfx_LoadMatrix(struct Matrix* matrix) {
if (curMatrix == D3DTS_TEXTURE0) {
matrix->Row2.X = matrix->Row3.X; /* NOTE: this hack fixes the texture movements. */
IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
}
if (Gfx_LostContext) return;
ReturnCode res = IDirect3DDevice9_SetTransform(device, curMatrix, matrix);
if (res) ErrorHandler_Fail2(res, "D3D9_LoadMatrix");
}
void Gfx_LoadIdentityMatrix(void) {
if (curMatrix == D3DTS_TEXTURE0) {
IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
}
if (Gfx_LostContext) return;
ReturnCode res = IDirect3DDevice9_SetTransform(device, curMatrix, &Matrix_Identity);
if (res) ErrorHandler_Fail2(res, "D3D9_LoadIdentityMatrix");
}
#define d3d9_zN -10000.0f
#define d3d9_zF 10000.0f
void Gfx_CalcOrthoMatrix(float width, float height, struct Matrix* matrix) {
Matrix_OrthographicOffCenter(matrix, 0.0f, width, height, 0.0f, d3d9_zN, d3d9_zF);
matrix->Row2.Z = 1.0f / (d3d9_zN - d3d9_zF);
matrix->Row3.Z = d3d9_zN / (d3d9_zN - d3d9_zF);
}
void Gfx_CalcPerspectiveMatrix(float fov, float aspect, float zNear, float zFar, struct Matrix* matrix) {
Matrix_PerspectiveFieldOfView(matrix, fov, aspect, zNear, zFar);
}
ReturnCode Gfx_TakeScreenshot(struct Stream* output, int width, int height) {
IDirect3DSurface9* backbuffer = NULL;
IDirect3DSurface9* temp = NULL;
ReturnCode res;
res = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
if (res) goto finished;
res = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &temp, NULL);
if (res) goto finished; /* TODO: For DX 8 use IDirect3DDevice8::CreateImageSurface */
res = IDirect3DDevice9_GetRenderTargetData(device, backbuffer, temp);
if (res) goto finished;
D3DLOCKED_RECT rect;
res = IDirect3DSurface9_LockRect(temp, &rect, NULL, D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE);
if (res) goto finished;
{
Bitmap bmp; Bitmap_Create(&bmp, width, height, rect.pBits);
res = Bitmap_EncodePng(&bmp, output);
if (res) { IDirect3DSurface9_UnlockRect(temp); goto finished; }
}
res = IDirect3DSurface9_UnlockRect(temp);
if (res) goto finished;
finished:
D3D9_FreeResource(&backbuffer);
D3D9_FreeResource(&temp);
return res;
}
bool Gfx_WarnIfNecessary(void) { return false; }
void Gfx_SetVSync(bool value) {
if (d3d9_vsync == value) return;
d3d9_vsync = value;
GfxCommon_LoseContext(" (toggling VSync)");
D3D9_RecreateDevice();
}
void Gfx_BeginFrame(void) {
IDirect3DDevice9_BeginScene(device);
}
void Gfx_EndFrame(void) {
IDirect3DDevice9_EndScene(device);
ReturnCode res = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
if (!res) return;
if (res != D3DERR_DEVICELOST) ErrorHandler_Fail2(res, "D3D9_EndFrame");
/* TODO: Make sure this actually works on all graphics cards.*/
GfxCommon_LoseContext(" (Direct3D9 device lost)");
D3D9_LoopUntilRetrieved();
D3D9_RecreateDevice();
}
const char* D3D9_StrFlags(void) {
if (createFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) return "Hardware";
if (createFlags & D3DCREATE_MIXED_VERTEXPROCESSING) return "Mixed";
if (createFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) return "Software";
return "(none)";
}
const char* D3D9_StrFormat(D3DFORMAT format) {
switch (format) {
case D3DFMT_D32: return "D32";
case D3DFMT_D24X8: return "D24X8";
case D3DFMT_D24S8: return "D24S8";
case D3DFMT_D24X4S4: return "D24X4S4";
case D3DFMT_D16: return "D16";
case D3DFMT_D15S1: return "D15S1";
case D3DFMT_X8R8G8B8: return "X8R8G8B8";
case D3DFMT_R8G8B8: return "R8G8B8";
case D3DFMT_R5G6B5: return "R5G6B5";
case D3DFMT_X1R5G5B5: return "X1R5G5B5";
}
return "(unknown)";
}
float d3d9_totalMem;
void Gfx_MakeApiInfo(void) {
D3DADAPTER_IDENTIFIER9 adapter = { 0 };
IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &adapter);
d3d9_totalMem = IDirect3DDevice9_GetAvailableTextureMem(device) / (1024.0f * 1024.0f);
String_AppendConst(&Gfx_ApiInfo[0],"-- Using Direct3D9 --");
String_Format1(&Gfx_ApiInfo[1], "Adapter: %c", adapter.Description);
String_Format1(&Gfx_ApiInfo[2], "Processing mode: %c", D3D9_StrFlags());
Gfx_UpdateApiInfo();
String_Format2(&Gfx_ApiInfo[4], "Max texture size: (%i, %i)", &Gfx_MaxTexWidth, &Gfx_MaxTexHeight);
String_Format1(&Gfx_ApiInfo[5], "Depth buffer format: %c", D3D9_StrFormat(d3d9_depthFormat));
String_Format1(&Gfx_ApiInfo[6], "Back buffer format: %c", D3D9_StrFormat(d3d9_viewFormat));
}
void Gfx_UpdateApiInfo(void) {
float mem = IDirect3DDevice9_GetAvailableTextureMem(device) / (1024.0f * 1024.0f);
Gfx_ApiInfo[3].length = 0;
String_Format2(&Gfx_ApiInfo[3], "Video memory: %f2 MB total, %f2 free", &d3d9_totalMem, &mem);
}
void Gfx_OnWindowResize(void) {
GfxCommon_LoseContext(" (resizing window)");
D3D9_RecreateDevice();
}
static void D3D9_SetDefaultRenderStates(void) {
Gfx_SetFaceCulling(false);
d3d9_batchFormat = -1;
D3D9_SetRenderState(D3DRS_COLORVERTEX, false, "D3D9_ColorVertex");
D3D9_SetRenderState2(D3DRS_LIGHTING, false, "D3D9_Lighting");
D3D9_SetRenderState2(D3DRS_SPECULARENABLE, false, "D3D9_SpecularEnable");
D3D9_SetRenderState2(D3DRS_LOCALVIEWER, false, "D3D9_LocalViewer");
D3D9_SetRenderState2(D3DRS_DEBUGMONITORTOKEN, false, "D3D9_DebugMonitor");
}
static void D3D9_RestoreRenderStates(void) {
union IntAndFloat raw;
D3D9_SetRenderState(D3DRS_ALPHATESTENABLE, d3d9_alphaTest, "D3D9_AlphaTest");
D3D9_SetRenderState2(D3DRS_ALPHABLENDENABLE, d3d9_alphaBlend, "D3D9_AlphaBlend");
D3D9_SetRenderState2(D3DRS_ALPHAFUNC, d3d9_alphaTestFunc, "D3D9_AlphaTestFunc");
D3D9_SetRenderState2(D3DRS_ALPHAREF, d3d9_alphaTestRef, "D3D9_AlphaRefFunc");
D3D9_SetRenderState2(D3DRS_SRCBLEND, d3d9_srcBlendFunc, "D3D9_AlphaSrcBlend");
D3D9_SetRenderState2(D3DRS_DESTBLEND, d3d9_dstBlendFunc, "D3D9_AlphaDstBlend");
D3D9_SetRenderState2(D3DRS_FOGENABLE, d3d9_fogEnable, "D3D9_Fog");
D3D9_SetRenderState2(D3DRS_FOGCOLOR, d3d9_fogCol, "D3D9_FogColor");
raw.f = d3d9_fogDensity;
D3D9_SetRenderState2(D3DRS_FOGDENSITY, raw.u, "D3D9_FogDensity");
raw.f = d3d9_fogEnd;
D3D9_SetRenderState2(D3DRS_FOGEND, raw.u, "D3D9_FogEnd");
D3D9_SetRenderState2(D3DRS_FOGTABLEMODE, d3d9_fogTableMode, "D3D9_FogMode");
D3D9_SetRenderState2(D3DRS_ZFUNC, d3d9_depthTestFunc, "D3D9_DepthTestFunc");
D3D9_SetRenderState2(D3DRS_ZENABLE, d3d9_depthTest, "D3D9_DepthTest");
D3D9_SetRenderState2(D3DRS_ZWRITEENABLE, d3d9_depthWrite, "D3D9_DepthWrite");
}
#endif

View file

@ -1,5 +1,5 @@
#include "Drawer2D.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Funcs.h"
#include "Platform.h"
#include "ExtMath.h"

View file

@ -8,7 +8,7 @@
#include "Platform.h"
#include "Funcs.h"
#include "ModelCache.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Lighting.h"
#include "Drawer2D.h"
#include "Particle.h"

View file

@ -9,7 +9,7 @@
#include "Camera.h"
#include "Funcs.h"
#include "VertexStructs.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "GraphicsCommon.h"
#include "ModelCache.h"
#include "Physics.h"

View file

@ -2,7 +2,7 @@
#include "ExtMath.h"
#include "World.h"
#include "Funcs.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Physics.h"
#include "Block.h"
#include "Platform.h"

View file

@ -3,7 +3,7 @@
#include "World.h"
#include "Lighting.h"
#include "MapRenderer.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Camera.h"
#include "Options.h"
#include "Funcs.h"

1315
src/Graphics.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,6 @@ struct Matrix Gfx_View, Gfx_Projection;
#define GFX_MAX_INDICES (65536 / 4 * 6)
#define GFX_MAX_VERTICES 65536
#define GFX_STRIDE_SIZES { 16, 24 }
/* Callback invoked when the current context is lost, and is repeatedly invoked until the context can be retrieved. */
ScheduledTaskCallback Gfx_LostContextFunction;

View file

@ -1,5 +1,5 @@
#include "GraphicsCommon.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Platform.h"
#include "Block.h"
#include "Event.h"

View file

@ -2,7 +2,7 @@
#include "Window.h"
#include "Game.h"
#include "GraphicsCommon.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Event.h"
#include "Drawer2D.h"
#include "ExtMath.h"

View file

@ -2,7 +2,7 @@
#include "Block.h"
#include "Game.h"
#include "Inventory.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "GraphicsCommon.h"
#include "Camera.h"
#include "ModelCache.h"

View file

@ -7,6 +7,10 @@
#include "Platform.h"
#include "Chat.h"
/*########################################################################################################################*
*--------------------------------------------------------Key/Mouse--------------------------------------------------------*
*#########################################################################################################################*/
#define Key_Function_Names \
"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",\
"F11", "F12", "F13", "F14", "F15", "F16", "F17", "F18", "F19", "F20",\
@ -60,41 +64,32 @@ const char* Key_Names[Key_Count] = {
"XBUTTON1", "XBUTTON2",
};*/
bool Key_States[Key_Count];
bool Key_IsPressed(Key key) { return Key_States[key]; }
void Key_SetPressed(Key key, bool pressed) {
if (Key_States[key] != pressed || Key_KeyRepeat) {
Key_States[key] = pressed;
if (Key_Pressed[key] == pressed && !Key_KeyRepeat) return;
Key_Pressed[key] = pressed;
if (pressed) {
Event_RaiseInt(&KeyEvents_Down, key);
} else {
Event_RaiseInt(&KeyEvents_Up, key);
}
if (pressed) {
Event_RaiseInt(&KeyEvents_Down, key);
} else {
Event_RaiseInt(&KeyEvents_Up, key);
}
}
void Key_Clear(void) {
int i;
for (i = 0; i < Key_Count; i++) {
if (Key_States[i]) Key_SetPressed((Key)i, false);
if (Key_Pressed[i]) Key_SetPressed((Key)i, false);
}
}
bool MouseButton_States[MouseButton_Count];
bool Mouse_IsPressed(MouseButton btn) { return MouseButton_States[btn]; }
void Mouse_SetPressed(MouseButton btn, bool pressed) {
if (MouseButton_States[btn] != pressed) {
MouseButton_States[btn] = pressed;
if (Mouse_Pressed[btn] == pressed) return;
Mouse_Pressed[btn] = pressed;
if (pressed) {
Event_RaiseInt(&MouseEvents_Down, btn);
} else {
Event_RaiseInt(&MouseEvents_Up, btn);
}
if (pressed) {
Event_RaiseInt(&MouseEvents_Down, btn);
} else {
Event_RaiseInt(&MouseEvents_Up, btn);
}
}
@ -110,6 +105,10 @@ void Mouse_SetPosition(int x, int y) {
Event_RaiseMouseMove(&MouseEvents_Moved, deltaX, deltaY);
}
/*########################################################################################################################*
*---------------------------------------------------------Keybinds--------------------------------------------------------*
*#########################################################################################################################*/
Key KeyBind_Keys[KeyBind_Count];
uint8_t KeyBind_Defaults[KeyBind_Count] = {
Key_W, Key_S, Key_A, Key_D,
@ -136,7 +135,7 @@ const char* KeyBind_Names[KeyBind_Count] = {
Key KeyBind_Get(KeyBind binding) { return KeyBind_Keys[binding]; }
Key KeyBind_GetDefault(KeyBind binding) { return KeyBind_Defaults[binding]; }
bool KeyBind_IsPressed(KeyBind binding) { return Key_States[KeyBind_Keys[binding]]; }
bool KeyBind_IsPressed(KeyBind binding) { return Key_Pressed[KeyBind_Keys[binding]]; }
void KeyBind_Load(void) {
int i;
@ -181,6 +180,9 @@ void KeyBind_Init(void) {
}
/*########################################################################################################################*
*---------------------------------------------------------Hotkeys---------------------------------------------------------*
*#########################################################################################################################*/
uint8_t Hotkeys_LWJGL[256] = {
0, Key_Escape, Key_1, Key_2, Key_3, Key_4, Key_5, Key_6, Key_7, Key_8, Key_9, Key_0, Key_Minus, Key_Plus, Key_BackSpace, Key_Tab,
Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_BracketLeft, Key_BracketRight, Key_Enter, Key_ControlLeft, Key_A, Key_S,

View file

@ -71,12 +71,12 @@ are generated for the same key when it is held down for a period of time. Should
bool Key_KeyRepeat;
extern const char* Key_Names[Key_Count];
#define Key_IsWinPressed() (Key_IsPressed(Key_WinLeft) || Key_IsPressed(Key_WinRight))
#define Key_IsAltPressed() (Key_IsPressed(Key_AltLeft) || Key_IsPressed(Key_AltRight))
#define Key_IsControlPressed() (Key_IsPressed(Key_ControlLeft) || Key_IsPressed(Key_ControlRight))
#define Key_IsShiftPressed() (Key_IsPressed(Key_ShiftLeft) || Key_IsPressed(Key_ShiftRight))
#define Key_IsWinPressed() (Key_Pressed[Key_WinLeft] || Key_Pressed[Key_WinRight])
#define Key_IsAltPressed() (Key_Pressed[Key_AltLeft] || Key_Pressed[Key_AltRight])
#define Key_IsControlPressed() (Key_Pressed[Key_ControlLeft] || Key_Pressed[Key_ControlRight])
#define Key_IsShiftPressed() (Key_Pressed[Key_ShiftLeft] || Key_Pressed[Key_ShiftRight])
bool Key_IsPressed(Key key);
bool Key_Pressed[Key_Count];
void Key_SetPressed(Key key, bool pressed);
void Key_Clear(void);
@ -89,7 +89,7 @@ typedef enum MouseButton_ {
float Mouse_Wheel;
int Mouse_X, Mouse_Y;
bool Mouse_IsPressed(MouseButton btn);
bool Mouse_Pressed[MouseButton_Count];
void Mouse_SetPressed(MouseButton btn, bool pressed);
void Mouse_SetWheel(float wheel);
void Mouse_SetPosition(int x, int y);

View file

@ -26,7 +26,7 @@ TimeMS input_lastClick;
float input_fovIndex = -1.0f;
bool InputHandler_IsMousePressed(MouseButton button) {
if (Mouse_IsPressed(button)) return true;
if (Mouse_Pressed[button]) return true;
/* Key --> mouse mappings */
if (button == MouseButton_Left && KeyBind_IsPressed(KeyBind_MouseLeft)) return true;

View file

@ -1,7 +1,7 @@
#include "IsometricDrawer.h"
#include "Drawer.h"
#include "GraphicsCommon.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "PackedCol.h"
#include "ExtMath.h"
#include "Block.h"

View file

@ -1,7 +1,7 @@
#include "MapRenderer.h"
#include "Block.h"
#include "Game.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "EnvRenderer.h"
#include "World.h"
#include "Vectors.h"

View file

@ -6,7 +6,7 @@
#include "Platform.h"
#include "Inventory.h"
#include "Drawer2D.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Funcs.h"
#include "TerrainAtlas.h"
#include "ModelCache.h"

View file

@ -4,7 +4,7 @@
#include "Game.h"
#include "ModelCache.h"
#include "GraphicsCommon.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Entity.h"
#define UV_POS_MASK ((uint16_t)0x7FFF)

View file

@ -1,5 +1,5 @@
#include "ModelCache.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Game.h"
#include "Event.h"
#include "ExtMath.h"

View file

@ -1,616 +0,0 @@
#include "GraphicsAPI.h"
#ifndef CC_BUILD_D3D9
#include "ErrorHandler.h"
#include "Platform.h"
#include "Window.h"
#include "GraphicsCommon.h"
#include "Funcs.h"
#include "Chat.h"
#include "Game.h"
#include "ExtMath.h"
#include "Bitmap.h"
#ifdef CC_BUILD_WIN
#define WIN32_LEAN_AND_MEAN
#define NOSERVICE
#define NOMCX
#define NOIME
#include <windows.h>
#else
#define APIENETRY
#endif
#include <GL/gl.h>
/* Extensions from later than OpenGL 1.1 */
#define GL_TEXTURE_MAX_LEVEL 0x813D
#define GL_ARRAY_BUFFER 0x8892
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
#define GL_STATIC_DRAW 0x88E4
#define GL_DYNAMIC_DRAW 0x88E8
#define GL_BGRA_EXT 0x80E1
#ifdef CC_BUILD_GL11
GfxResourceID gl_activeList;
#define gl_DYNAMICLISTID 1234567891
void* gl_dynamicListData;
#else
typedef void (APIENTRY *FUNC_GLBINDBUFFER) (GLenum target, GLuint buffer);
typedef void (APIENTRY *FUNC_GLDELETEBUFFERS) (GLsizei n, const GLuint *buffers);
typedef void (APIENTRY *FUNC_GLGENBUFFERS) (GLsizei n, GLuint *buffers);
typedef void (APIENTRY *FUNC_GLBUFFERDATA) (GLenum target, const void* size, const void *data, GLenum usage);
typedef void (APIENTRY *FUNC_GLBUFFERSUBDATA) (GLenum target, const void* offset, const void* size, const void *data);
FUNC_GLBINDBUFFER glBindBuffer;
FUNC_GLDELETEBUFFERS glDeleteBuffers;
FUNC_GLGENBUFFERS glGenBuffers;
FUNC_GLBUFFERDATA glBufferData;
FUNC_GLBUFFERSUBDATA glBufferSubData;
#endif
int Gfx_strideSizes[2] = GFX_STRIDE_SIZES;
bool gl_vsync;
int gl_blend[6] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA };
int gl_compare[8] = { GL_ALWAYS, GL_NOTEQUAL, GL_NEVER, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER };
int gl_fogModes[3] = { GL_LINEAR, GL_EXP, GL_EXP2 };
int gl_matrixModes[3] = { GL_PROJECTION, GL_MODELVIEW, GL_TEXTURE };
typedef void (*GL_SetupVBFunc)(void);
typedef void (*GL_SetupVBRangeFunc)(int startVertex);
GL_SetupVBFunc gl_setupVBFunc;
GL_SetupVBRangeFunc gl_setupVBRangeFunc;
int gl_batchStride, gl_batchFormat = -1;
#ifndef CC_BUILD_GL11
static void GL_CheckVboSupport(void) {
String extensions = String_FromReadonly(glGetString(GL_EXTENSIONS));
String version = String_FromReadonly(glGetString(GL_VERSION));
String vboExt = String_FromConst("GL_ARB_vertex_buffer_object");
int major = (int)(version.buffer[0] - '0'); /* x.y. (and so forth) */
int minor = (int)(version.buffer[2] - '0');
/* Supported in core since 1.5 */
if ((major > 1) || (major == 1 && minor >= 5)) {
glBindBuffer = (FUNC_GLBINDBUFFER)GLContext_GetAddress("glBindBuffer");
glDeleteBuffers = (FUNC_GLDELETEBUFFERS)GLContext_GetAddress("glDeleteBuffers");
glGenBuffers = (FUNC_GLGENBUFFERS)GLContext_GetAddress("glGenBuffers");
glBufferData = (FUNC_GLBUFFERDATA)GLContext_GetAddress("glBufferData");
glBufferSubData = (FUNC_GLBUFFERSUBDATA)GLContext_GetAddress("glBufferSubData");
return;
} else if (String_CaselessContains(&extensions, &vboExt)) {
glBindBuffer = (FUNC_GLBINDBUFFER)GLContext_GetAddress("glBindBufferARB");
glDeleteBuffers = (FUNC_GLDELETEBUFFERS)GLContext_GetAddress("glDeleteBuffersARB");
glGenBuffers = (FUNC_GLGENBUFFERS)GLContext_GetAddress("glGenBuffersARB");
glBufferData = (FUNC_GLBUFFERDATA)GLContext_GetAddress("glBufferDataARB");
glBufferSubData = (FUNC_GLBUFFERSUBDATA)GLContext_GetAddress("glBufferSubDataARB");
} else {
ErrorHandler_Fail("Only OpenGL 1.1 supported.\r\n\r\n" \
"Compile the game with CC_BUILD_GL11, or ask on the classicube forums for it");
}
}
#endif
void Gfx_Init(void) {
Gfx_MinZNear = 0.1f;
struct GraphicsMode mode = GraphicsMode_MakeDefault();
GLContext_Init(mode);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &Gfx_MaxTexWidth);
Gfx_MaxTexHeight = Gfx_MaxTexWidth;
#ifndef CC_BUILD_GL11
Gfx_CustomMipmapsLevels = true;
GL_CheckVboSupport();
#else
Gfx_CustomMipmapsLevels = false;
#endif
GfxCommon_Init();
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
}
void Gfx_Free(void) {
GfxCommon_Free();
GLContext_Free();
}
#define gl_Toggle(cap) if (enabled) { glEnable(cap); } else { glDisable(cap); }
static void GL_DoMipmaps(GfxResourceID texId, int x, int y, Bitmap* bmp, bool partial) {
uint8_t* prev = bmp->Scan0;
int lvls = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height);
int lvl, width = bmp->Width, height = bmp->Height;
for (lvl = 1; lvl <= lvls; lvl++) {
x /= 2; y /= 2;
if (width > 1) width /= 2;
if (height > 1) height /= 2;
uint8_t* cur = Mem_Alloc(width * height, BITMAP_SIZEOF_PIXEL, "mipmaps");
GfxCommon_GenMipmaps(width, height, cur, prev);
if (partial) {
glTexSubImage2D(GL_TEXTURE_2D, lvl, x, y, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, cur);
} else {
glTexImage2D(GL_TEXTURE_2D, lvl, GL_RGBA, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, cur);
}
if (prev != bmp->Scan0) Mem_Free(prev);
prev = cur;
}
if (prev != bmp->Scan0) Mem_Free(prev);
}
GfxResourceID Gfx_CreateTexture(Bitmap* bmp, bool managedPool, bool mipmaps) {
uint32_t texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if (!Math_IsPowOf2(bmp->Width) || !Math_IsPowOf2(bmp->Height)) {
ErrorHandler_Fail("Textures must have power of two dimensions");
}
if (mipmaps) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
if (Gfx_CustomMipmapsLevels) {
int lvls = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, lvls);
}
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bmp->Width, bmp->Height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, bmp->Scan0);
if (mipmaps) GL_DoMipmaps(texId, 0, 0, bmp, false);
return texId;
}
void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, Bitmap* part, bool mipmaps) {
glBindTexture(GL_TEXTURE_2D, texId);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, part->Width, part->Height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, part->Scan0);
if (mipmaps) GL_DoMipmaps(texId, x, y, part, true);
}
void Gfx_BindTexture(GfxResourceID texId) {
glBindTexture(GL_TEXTURE_2D, texId);
}
void Gfx_DeleteTexture(GfxResourceID* texId) {
if (!texId || *texId == GFX_NULL) return;
glDeleteTextures(1, texId);
*texId = GFX_NULL;
}
void Gfx_SetTexturing(bool enabled) { gl_Toggle(GL_TEXTURE_2D); }
void Gfx_EnableMipmaps(void) { }
void Gfx_DisableMipmaps(void) { }
bool gl_fogEnable;
bool Gfx_GetFog(void) { return gl_fogEnable; }
void Gfx_SetFog(bool enabled) {
gl_fogEnable = enabled;
gl_Toggle(GL_FOG);
}
PackedCol gl_lastFogCol;
void Gfx_SetFogCol(PackedCol col) {
if (PackedCol_Equals(col, gl_lastFogCol)) return;
float colRGBA[4] = { col.R / 255.0f, col.G / 255.0f, col.B / 255.0f, col.A / 255.0f };
glFogfv(GL_FOG_COLOR, colRGBA);
gl_lastFogCol = col;
}
float gl_lastFogEnd = -1, gl_lastFogDensity = -1;
void Gfx_SetFogDensity(float value) {
if (value == gl_lastFogDensity) return;
glFogf(GL_FOG_DENSITY, value);
gl_lastFogDensity = value;
}
void Gfx_SetFogEnd(float value) {
if (value == gl_lastFogEnd) return;
glFogf(GL_FOG_END, value);
gl_lastFogEnd = value;
}
int gl_lastFogMode = -1;
void Gfx_SetFogMode(int mode) {
if (mode == gl_lastFogMode) return;
glFogi(GL_FOG_MODE, gl_fogModes[mode]);
gl_lastFogMode = mode;
}
void Gfx_SetFaceCulling(bool enabled) { gl_Toggle(GL_CULL_FACE); }
void Gfx_SetAlphaTest(bool enabled) { gl_Toggle(GL_ALPHA_TEST); }
void Gfx_SetAlphaTestFunc(int func, float value) {
glAlphaFunc(gl_compare[func], value);
}
void Gfx_SetAlphaBlending(bool enabled) { gl_Toggle(GL_BLEND); }
void Gfx_SetAlphaBlendFunc(int srcFunc, int dstFunc) {
glBlendFunc(gl_blend[srcFunc], gl_blend[dstFunc]);
}
void Gfx_SetAlphaArgBlend(bool enabled) { }
void Gfx_Clear(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
PackedCol gl_lastClearCol;
void Gfx_ClearCol(PackedCol col) {
if (PackedCol_Equals(col, gl_lastClearCol)) return;
glClearColor(col.R / 255.0f, col.G / 255.0f, col.B / 255.0f, col.A / 255.0f);
gl_lastClearCol = col;
}
void Gfx_SetColourWriteMask(bool r, bool g, bool b, bool a) {
glColorMask(r, g, b, a);
}
void Gfx_SetDepthWrite(bool enabled) {
glDepthMask(enabled);
}
void Gfx_SetDepthTest(bool enabled) { gl_Toggle(GL_DEPTH_TEST); }
void Gfx_SetDepthTestFunc(int compareFunc) {
glDepthFunc(gl_compare[compareFunc]);
}
#ifndef CC_BUILD_GL11
GfxResourceID GL_GenAndBind(GLenum target) {
GfxResourceID id;
glGenBuffers(1, &id);
glBindBuffer(target, id);
return id;
}
#endif
GfxResourceID Gfx_CreateDynamicVb(int vertexFormat, int maxVertices) {
#ifndef CC_BUILD_GL11
GfxResourceID id = GL_GenAndBind(GL_ARRAY_BUFFER);
uint32_t sizeInBytes = maxVertices * Gfx_strideSizes[vertexFormat];
glBufferData(GL_ARRAY_BUFFER, (void*)sizeInBytes, NULL, GL_DYNAMIC_DRAW);
return id;
#else
return gl_DYNAMICLISTID;
#endif
}
#define gl_MAXINDICES ICOUNT(65536)
GfxResourceID Gfx_CreateVb(void* vertices, int vertexFormat, int count) {
#ifndef CC_BUILD_GL11
GfxResourceID id = GL_GenAndBind(GL_ARRAY_BUFFER);
uint32_t sizeInBytes = count * Gfx_strideSizes[vertexFormat];
glBufferData(GL_ARRAY_BUFFER, (void*)sizeInBytes, vertices, GL_STATIC_DRAW);
return id;
#else
/* We need to setup client state properly when building the list */
int curFormat = gl_batchFormat;
Gfx_SetBatchFormat(vertexFormat);
GfxResourceID list = glGenLists(1);
glNewList(list, GL_COMPILE);
count &= ~0x01; /* Need to get rid of the 1 extra element, see comment in chunk mesh builder for why */
uint16_t indices[GFX_MAX_INDICES];
GfxCommon_MakeIndices(indices, ICOUNT(count));
int stride = vertexFormat == VERTEX_FORMAT_P3FT2FC4B ? sizeof(VertexP3fT2fC4b) : sizeof(VertexP3fC4b);
glVertexPointer(3, GL_FLOAT, stride, vertices);
glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)((uint8_t*)vertices + 12));
if (vertexFormat == VERTEX_FORMAT_P3FT2FC4B) {
glTexCoordPointer(2, GL_FLOAT, stride, (void*)((uint8_t*)vertices + 16));
}
glDrawElements(GL_TRIANGLES, ICOUNT(count), GL_UNSIGNED_SHORT, indices);
glEndList();
Gfx_SetBatchFormat(curFormat);
return list;
#endif
}
GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) {
#ifndef CC_BUILD_GL11
GfxResourceID id = GL_GenAndBind(GL_ELEMENT_ARRAY_BUFFER);
uint32_t sizeInBytes = indicesCount * 2;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (void*)sizeInBytes, indices, GL_STATIC_DRAW);
return id;
#else
return NULL;
#endif
}
void Gfx_BindVb(GfxResourceID vb) {
#ifndef CC_BUILD_GL11
glBindBuffer(GL_ARRAY_BUFFER, vb);
#else
gl_activeList = vb;
#endif
}
void Gfx_BindIb(GfxResourceID ib) {
#ifndef CC_BUILD_GL11
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib);
#else
return;
#endif
}
void Gfx_DeleteVb(GfxResourceID* vb) {
if (!vb || *vb == GFX_NULL) return;
#ifndef CC_BUILD_GL11
glDeleteBuffers(1, vb);
#else
if (*vb != gl_DYNAMICLISTID) glDeleteLists(*vb, 1);
#endif
*vb = GFX_NULL;
}
void Gfx_DeleteIb(GfxResourceID* ib) {
#ifndef CC_BUILD_GL11
if (!ib || *ib == GFX_NULL) return;
glDeleteBuffers(1, ib);
*ib = GFX_NULL;
#else
return;
#endif
}
void GL_SetupVbPos3fCol4b(void) {
glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fC4b), (void*)0);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fC4b), (void*)12);
}
void GL_SetupVbPos3fTex2fCol4b(void) {
glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)0);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fT2fC4b), (void*)12);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)16);
}
void GL_SetupVbPos3fCol4b_Range(int startVertex) {
uint32_t offset = startVertex * (uint32_t)sizeof(VertexP3fC4b);
glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fC4b), (void*)(offset));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fC4b), (void*)(offset + 12));
}
void GL_SetupVbPos3fTex2fCol4b_Range(int startVertex) {
uint32_t offset = startVertex * (uint32_t)sizeof(VertexP3fT2fC4b);
glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)(offset));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fT2fC4b), (void*)(offset + 12));
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)(offset + 16));
}
void Gfx_SetBatchFormat(int vertexFormat) {
if (vertexFormat == gl_batchFormat) return;
if (gl_batchFormat == VERTEX_FORMAT_P3FT2FC4B) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
gl_batchFormat = vertexFormat;
gl_batchStride = Gfx_strideSizes[vertexFormat];
if (vertexFormat == VERTEX_FORMAT_P3FT2FC4B) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
gl_setupVBFunc = GL_SetupVbPos3fTex2fCol4b;
gl_setupVBRangeFunc = GL_SetupVbPos3fTex2fCol4b_Range;
} else {
gl_setupVBFunc = GL_SetupVbPos3fCol4b;
gl_setupVBRangeFunc = GL_SetupVbPos3fCol4b_Range;
}
}
void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
#ifndef CC_BUILD_GL11
glBindBuffer(GL_ARRAY_BUFFER, vb);
uint32_t sizeInBytes = vCount * gl_batchStride;
glBufferSubData(GL_ARRAY_BUFFER, NULL, (void*)sizeInBytes, vertices);
#else
gl_activeList = gl_DYNAMICLISTID;
gl_dynamicListData = vertices;
#endif
}
#ifdef CC_BUILD_GL11
static void GL_V16(VertexP3fC4b v) {
glColor4ub(v.Col.R, v.Col.G, v.Col.B, v.Col.A);
glVertex3f(v.X, v.Y, v.Z);
}
static void GL_V24(VertexP3fT2fC4b v) {
glColor4ub(v.Col.R, v.Col.G, v.Col.B, v.Col.A);
glTexCoord2f(v.U, v.V);
glVertex3f(v.X, v.Y, v.Z);
}
static void GL_DrawDynamicTriangles(int verticesCount, int startVertex) {
glBegin(GL_TRIANGLES);
int i;
if (gl_batchFormat == VERTEX_FORMAT_P3FT2FC4B) {
VertexP3fT2fC4b* ptr = (VertexP3fT2fC4b*)gl_dynamicListData;
for (i = startVertex; i < startVertex + verticesCount; i += 4) {
GL_V24(ptr[i + 0]); GL_V24(ptr[i + 1]); GL_V24(ptr[i + 2]);
GL_V24(ptr[i + 2]); GL_V24(ptr[i + 3]); GL_V24(ptr[i + 0]);
}
} else {
VertexP3fC4b* ptr = (VertexP3fC4b*)gl_dynamicListData;
for (i = startVertex; i < startVertex + verticesCount; i += 4) {
GL_V16(ptr[i + 0]); GL_V16(ptr[i + 1]); GL_V16(ptr[i + 2]);
GL_V16(ptr[i + 2]); GL_V16(ptr[i + 3]); GL_V16(ptr[i + 0]);
}
}
glEnd();
}
#endif
void Gfx_DrawVb_Lines(int verticesCount) {
#ifndef CC_BUILD_GL11
gl_setupVBFunc();
glDrawArrays(GL_LINES, 0, verticesCount);
#else
glBegin(GL_LINES);
int i;
if (gl_batchFormat == VERTEX_FORMAT_P3FT2FC4B) {
VertexP3fT2fC4b* ptr = (VertexP3fT2fC4b*)gl_dynamicListData;
for (i = 0; i < verticesCount; i += 2) { GL_V24(ptr[i + 0]); GL_V24(ptr[i + 1]); }
} else {
VertexP3fC4b* ptr = (VertexP3fC4b*)gl_dynamicListData;
for (i = 0; i < verticesCount; i += 2) { GL_V16(ptr[i + 0]); GL_V16(ptr[i + 1]); }
}
glEnd();
#endif
}
void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
#ifndef CC_BUILD_GL11
gl_setupVBRangeFunc(startVertex);
glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, NULL);
#else
if (gl_activeList != gl_DYNAMICLISTID) { glCallList(gl_activeList); }
else { GL_DrawDynamicTriangles(verticesCount, startVertex); }
#endif
}
void Gfx_DrawVb_IndexedTris(int verticesCount) {
#ifndef CC_BUILD_GL11
gl_setupVBFunc();
glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, NULL);
#else
if (gl_activeList != gl_DYNAMICLISTID) { glCallList(gl_activeList); }
else { GL_DrawDynamicTriangles(verticesCount, 0); }
#endif
}
GfxResourceID gl_lastPartialList;
void Gfx_DrawIndexedVb_TrisT2fC4b(int verticesCount, int startVertex) {
#ifndef CC_BUILD_GL11
uint32_t offset = startVertex * (uint32_t)sizeof(VertexP3fT2fC4b);
glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)(offset));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fT2fC4b), (void*)(offset + 12));
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)(offset + 16));
glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, NULL);
#else
/* TODO: This renders the whole map, bad performance!! FIX FIX */
if (gl_activeList != gl_lastPartialList) {
glCallList(gl_activeList);
gl_lastPartialList = gl_activeList;
}
#endif
}
int gl_lastMatrixType;
void Gfx_SetMatrixMode(int matrixType) {
if (matrixType == gl_lastMatrixType) return;
glMatrixMode(gl_matrixModes[matrixType]);
gl_lastMatrixType = matrixType;
}
void Gfx_LoadMatrix(struct Matrix* matrix) { glLoadMatrixf((float*)matrix); }
void Gfx_LoadIdentityMatrix(void) { glLoadIdentity(); }
void Gfx_CalcOrthoMatrix(float width, float height, struct Matrix* matrix) {
Matrix_OrthographicOffCenter(matrix, 0.0f, width, height, 0.0f, -10000.0f, 10000.0f);
}
void Gfx_CalcPerspectiveMatrix(float fov, float aspect, float zNear, float zFar, struct Matrix* matrix) {
Matrix_PerspectiveFieldOfView(matrix, fov, aspect, zNear, zFar);
}
ReturnCode Gfx_TakeScreenshot(struct Stream* output, int width, int height) {
Bitmap bmp; Bitmap_Allocate(&bmp, width, height);
glReadPixels(0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, bmp.Scan0);
uint8_t tmp[PNG_MAX_DIMS * BITMAP_SIZEOF_PIXEL];
/* flip vertically around y */
int x, y;
uint32_t stride = (uint32_t)(bmp.Width) * BITMAP_SIZEOF_PIXEL;
for (y = 0; y < height / 2; y++) {
uint32_t* src = Bitmap_GetRow(&bmp, y);
uint32_t* dst = Bitmap_GetRow(&bmp, (height - 1) - y);
Mem_Copy(tmp, src, stride);
Mem_Copy(src, dst, stride);
Mem_Copy(dst, tmp, stride);
/*for (x = 0; x < bmp.Width; x++) {
uint32_t temp = dst[x]; dst[x] = src[x]; src[x] = temp;
}*/
}
ReturnCode res = Bitmap_EncodePng(&bmp, output);
Mem_Free(bmp.Scan0);
return res;
}
bool nv_mem;
void Gfx_MakeApiInfo(void) {
int depthBits = 0;
glGetIntegerv(GL_DEPTH_BITS, &depthBits);
String_AppendConst(&Gfx_ApiInfo[0],"-- Using OpenGL --");
String_Format1(&Gfx_ApiInfo[1], "Vendor: %c", glGetString(GL_VENDOR));
String_Format1(&Gfx_ApiInfo[2], "Renderer: %c", glGetString(GL_RENDERER));
String_Format1(&Gfx_ApiInfo[3], "GL version: %c", glGetString(GL_VERSION));
/* Memory usage goes here */
String_Format2(&Gfx_ApiInfo[5], "Max texture size: (%i, %i)", &Gfx_MaxTexWidth, &Gfx_MaxTexHeight);
String_Format1(&Gfx_ApiInfo[6], "Depth buffer bits: %i", &depthBits);
String extensions = String_FromReadonly(glGetString(GL_EXTENSIONS));
String memExt = String_FromConst("GL_NVX_gpu_memory_info");
nv_mem = String_CaselessContains(&extensions, &memExt);
}
void Gfx_UpdateApiInfo(void) {
if (!nv_mem) return;
int totalKb = 0, curKb = 0;
glGetIntegerv(0x9048, &totalKb);
glGetIntegerv(0x9049, &curKb);
if (totalKb <= 0 || curKb <= 0) return;
Gfx_ApiInfo[4].length = 0;
float total = totalKb / 1024.0f, cur = curKb / 1024.0f;
String_Format2(&Gfx_ApiInfo[4], "Video memory: %f2 MB total, %f2 free", &total, &cur);
}
bool Gfx_WarnIfNecessary(void) {
#ifdef CC_BUILD_GL11
Chat_AddRaw("&cYou are using the very outdated OpenGL backend.");
Chat_AddRaw("&cAs such you may experience poor performance.");
Chat_AddRaw("&cIt is likely you need to install video card drivers.");
#endif
String renderer = String_FromReadonly(glGetString(GL_RENDERER));
String intel = String_FromConst("Intel");
if (!String_ContainsString(&renderer, &intel)) return false;
Chat_AddRaw("&cIntel graphics cards are known to have issues with the OpenGL build.");
Chat_AddRaw("&cVSync may not work, and you may see disappearing clouds and map edges.");
Chat_AddRaw("&cFor Windows, try downloading the Direct3D 9 build instead.");
return true;
}
void Gfx_SetVSync(bool value) {
if (gl_vsync == value) return;
gl_vsync = value;
GLContext_SetVSync(value);
}
void Gfx_BeginFrame(void) { }
void Gfx_EndFrame(void) {
GLContext_SwapBuffers();
#ifdef CC_BUILD_GL11
gl_activeList = NULL;
#endif
}
void Gfx_OnWindowResize(void) {
glViewport(0, 0, Game_Width, Game_Height);
}
#endif

View file

@ -5,7 +5,7 @@
#include "Lighting.h"
#include "Entity.h"
#include "TerrainAtlas.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "GraphicsCommon.h"
#include "Funcs.h"
#include "Game.h"

View file

@ -1,7 +1,7 @@
#include "PickedPosRenderer.h"
#include "PackedCol.h"
#include "VertexStructs.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "GraphicsCommon.h"
#include "Game.h"
#include "Event.h"

View file

@ -6,7 +6,7 @@
#include "Platform.h"
#include "Inventory.h"
#include "Drawer2D.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Funcs.h"
#include "TerrainAtlas.h"
#include "ModelCache.h"

View file

@ -1,6 +1,6 @@
#include "SelectionBox.h"
#include "ExtMath.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "GraphicsCommon.h"
#include "Event.h"
#include "Funcs.h"

View file

@ -135,7 +135,7 @@ bool String_Append(String* str, char c) {
}
bool String_AppendBool(String* str, bool value) {
char* text = value ? "True" : "False";
const char* text = value ? "True" : "False";
return String_AppendConst(str, text);
}

View file

@ -3,7 +3,7 @@
#include "Block.h"
#include "ExtMath.h"
#include "Funcs.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Platform.h"
void Atlas2D_UpdateState(Bitmap* bmp) {

View file

@ -5,7 +5,7 @@
#include "Stream.h"
#include "Bitmap.h"
#include "World.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Event.h"
#include "Game.h"
#include "AsyncDownloader.h"

View file

@ -1,5 +1,5 @@
#include "Widgets.h"
#include "GraphicsAPI.h"
#include "Graphics.h"
#include "Drawer2D.h"
#include "GraphicsCommon.h"
#include "ExtMath.h"