mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-23 17:43:08 -05:00
Combine OpenGLApi/Direct3D9Api
This commit is contained in:
parent
0a29a21d07
commit
8782d254ac
37 changed files with 1392 additions and 1414 deletions
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "AxisLinesRenderer.h"
|
||||
#include "GraphicsAPI.h"
|
||||
#include "Graphics.h"
|
||||
#include "Game.h"
|
||||
#include "GraphicsCommon.h"
|
||||
#include "SelectionBox.h"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
17
src/Chat.c
17
src/Chat.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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>
|
721
src/D3D9Api.c
721
src/D3D9Api.c
|
@ -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
|
|
@ -1,5 +1,5 @@
|
|||
#include "Drawer2D.h"
|
||||
#include "GraphicsAPI.h"
|
||||
#include "Graphics.h"
|
||||
#include "Funcs.h"
|
||||
#include "Platform.h"
|
||||
#include "ExtMath.h"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
1315
src/Graphics.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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;
|
|
@ -1,5 +1,5 @@
|
|||
#include "GraphicsCommon.h"
|
||||
#include "GraphicsAPI.h"
|
||||
#include "Graphics.h"
|
||||
#include "Platform.h"
|
||||
#include "Block.h"
|
||||
#include "Event.h"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
48
src/Input.c
48
src/Input.c
|
@ -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,
|
||||
|
|
12
src/Input.h
12
src/Input.h
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "ModelCache.h"
|
||||
#include "GraphicsAPI.h"
|
||||
#include "Graphics.h"
|
||||
#include "Game.h"
|
||||
#include "Event.h"
|
||||
#include "ExtMath.h"
|
||||
|
|
616
src/OpenGLApi.c
616
src/OpenGLApi.c
|
@ -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
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "Widgets.h"
|
||||
#include "GraphicsAPI.h"
|
||||
#include "Graphics.h"
|
||||
#include "Drawer2D.h"
|
||||
#include "GraphicsCommon.h"
|
||||
#include "ExtMath.h"
|
||||
|
|
Loading…
Add table
Reference in a new issue