Fix fog for modern OpenGL backend

This commit is contained in:
UnknownShadow200 2019-03-11 15:21:42 +11:00
parent b1a951e714
commit d20a49123d

View File

@ -276,7 +276,7 @@ static DWORD d3d9_formatMappings[2] = { D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DFVF_XYZ
static IDirect3D9* d3d;
static IDirect3DDevice9* device;
static DWORD createFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
static D3DFORMAT d3d9_viewFormat, d3d9_depthFormat;
static D3DFORMAT gfx_viewFormat, gfx_depthFormat;
#define D3D9_SetRenderState(state, value, name) \
ReturnCode res = IDirect3DDevice9_SetRenderState(device, state, value); if (res) Logger_Abort2(res, name);
@ -318,26 +318,26 @@ static void D3D9_FindCompatibleFormat(void) {
int i, count = Array_Elems(viewFormats);
for (i = 0; i < count; i++) {
d3d9_viewFormat = viewFormats[i];
res = IDirect3D9_CheckDeviceType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d9_viewFormat, d3d9_viewFormat, true);
gfx_viewFormat = viewFormats[i];
res = IDirect3D9_CheckDeviceType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, gfx_viewFormat, gfx_viewFormat, true);
if (!res) break;
}
if (i == count) Logger_Abort("Unable to create a back buffer with sufficient precision.");
count = Array_Elems(depthFormats);
for (i = 0; i < count; i++) {
d3d9_depthFormat = depthFormats[i];
res = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d9_viewFormat, d3d9_viewFormat, d3d9_depthFormat);
gfx_depthFormat = depthFormats[i];
res = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, gfx_viewFormat, gfx_viewFormat, gfx_depthFormat);
if (!res) break;
}
if (i == count) Logger_Abort("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->AutoDepthStencilFormat = gfx_depthFormat;
args->BackBufferWidth = width;
args->BackBufferHeight = height;
args->BackBufferFormat = d3d9_viewFormat;
args->BackBufferFormat = gfx_viewFormat;
args->BackBufferCount = 1;
args->EnableAutoDepthStencil = true;
args->PresentationInterval = gfx_vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
@ -542,18 +542,18 @@ void Gfx_DisableMipmaps(void) {
/*########################################################################################################################*
*-----------------------------------------------------State management----------------------------------------------------*
*#########################################################################################################################*/
static PackedColUnion d3d9_fogCol;
static float d3d9_fogDensity = -1.0f, d3d9_fogEnd = -1.0f;
static D3DFOGMODE d3d9_fogMode = D3DFOG_NONE;
static PackedColUnion gfx_fogCol;
static float gfx_fogDensity = -1.0f, gfx_fogEnd = -1.0f;
static D3DFOGMODE gfx_fogMode = D3DFOG_NONE;
static bool d3d9_alphaTesting, d3d9_alphaBlending;
static int d3d9_alphaTestRef;
static D3DCMPFUNC d3d9_alphaTestFunc = D3DCMP_ALWAYS;
static D3DBLEND d3d9_srcBlendFunc = D3DBLEND_ONE, d3d9_dstBlendFunc = D3DBLEND_ZERO;
static bool gfx_alphaTesting, gfx_alphaBlending;
static int gfx_alphaTestRef;
static D3DCMPFUNC gfx_alphaTestFunc = D3DCMP_ALWAYS;
static D3DBLEND gfx_srcBlendFunc = D3DBLEND_ONE, gfx_dstBlendFunc = D3DBLEND_ZERO;
static PackedColUnion d3d9_clearCol;
static bool d3d9_depthTesting, d3d9_depthWriting;
static D3DCMPFUNC d3d9_depthTestFunc = D3DCMP_LESSEQUAL;
static PackedColUnion gfx_clearCol;
static bool gfx_depthTesting, gfx_depthWriting;
static D3DCMPFUNC gfx_depthTestFunc = D3DCMP_LESSEQUAL;
void Gfx_SetFaceCulling(bool enabled) {
D3DCULL mode = enabled ? D3DCULL_CW : D3DCULL_NONE;
@ -569,17 +569,17 @@ void Gfx_SetFog(bool enabled) {
}
void Gfx_SetFogCol(PackedCol col) {
if (PackedCol_Equals(col, d3d9_fogCol.C)) return;
d3d9_fogCol.C = col;
if (PackedCol_Equals(col, gfx_fogCol.C)) return;
gfx_fogCol.C = col;
if (Gfx.LostContext) return;
D3D9_SetRenderState(D3DRS_FOGCOLOR, d3d9_fogCol.Raw, "D3D9_SetFogColour");
D3D9_SetRenderState(D3DRS_FOGCOLOR, gfx_fogCol.Raw, "D3D9_SetFogColour");
}
void Gfx_SetFogDensity(float value) {
union IntAndFloat raw;
if (value == d3d9_fogDensity) return;
d3d9_fogDensity = value;
if (value == gfx_fogDensity) return;
gfx_fogDensity = value;
if (Gfx.LostContext) return;
raw.f = value;
@ -588,8 +588,8 @@ void Gfx_SetFogDensity(float value) {
void Gfx_SetFogEnd(float value) {
union IntAndFloat raw;
if (value == d3d9_fogEnd) return;
d3d9_fogEnd = value;
if (value == gfx_fogEnd) return;
gfx_fogEnd = value;
if (Gfx.LostContext) return;
raw.f = value;
@ -599,39 +599,39 @@ void Gfx_SetFogEnd(float value) {
void Gfx_SetFogMode(FogFunc func) {
static D3DFOGMODE modes[3] = { D3DFOG_LINEAR, D3DFOG_EXP, D3DFOG_EXP2 };
D3DFOGMODE mode = modes[func];
if (mode == d3d9_fogMode) return;
if (mode == gfx_fogMode) return;
d3d9_fogMode = mode;
gfx_fogMode = mode;
if (Gfx.LostContext) return;
D3D9_SetRenderState(D3DRS_FOGTABLEMODE, mode, "D3D9_SetFogMode");
}
void Gfx_SetAlphaTest(bool enabled) {
if (d3d9_alphaTesting == enabled) return;
d3d9_alphaTesting = enabled;
if (gfx_alphaTesting == enabled) return;
gfx_alphaTesting = enabled;
D3D9_SetRenderState(D3DRS_ALPHATESTENABLE, enabled, "D3D9_SetAlphaTest");
}
void Gfx_SetAlphaTestFunc(CompareFunc func, float refValue) {
d3d9_alphaTestFunc = d3d9_compareFuncs[func];
D3D9_SetRenderState(D3DRS_ALPHAFUNC, d3d9_alphaTestFunc, "D3D9_SetAlphaTest_Func");
d3d9_alphaTestRef = (int)(refValue * 255);
D3D9_SetRenderState2(D3DRS_ALPHAREF, d3d9_alphaTestRef, "D3D9_SetAlphaTest_Ref");
gfx_alphaTestFunc = d3d9_compareFuncs[func];
D3D9_SetRenderState(D3DRS_ALPHAFUNC, gfx_alphaTestFunc, "D3D9_SetAlphaTest_Func");
gfx_alphaTestRef = (int)(refValue * 255);
D3D9_SetRenderState2(D3DRS_ALPHAREF, gfx_alphaTestRef, "D3D9_SetAlphaTest_Ref");
}
void Gfx_SetAlphaBlending(bool enabled) {
if (d3d9_alphaBlending == enabled) return;
d3d9_alphaBlending = enabled;
if (gfx_alphaBlending == enabled) return;
gfx_alphaBlending = enabled;
D3D9_SetRenderState(D3DRS_ALPHABLENDENABLE, enabled, "D3D9_SetAlphaBlending");
}
void Gfx_SetAlphaBlendFunc(BlendFunc srcFunc, BlendFunc dstFunc) {
static D3DBLEND funcs[6] = { D3DBLEND_ZERO, D3DBLEND_ONE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA, D3DBLEND_DESTALPHA, D3DBLEND_INVDESTALPHA };
d3d9_srcBlendFunc = funcs[srcFunc];
D3D9_SetRenderState(D3DRS_SRCBLEND, d3d9_srcBlendFunc, "D3D9_SetAlphaBlendFunc_Src");
d3d9_dstBlendFunc = funcs[dstFunc];
D3D9_SetRenderState2(D3DRS_DESTBLEND, d3d9_dstBlendFunc, "D3D9_SetAlphaBlendFunc_Dst");
gfx_srcBlendFunc = funcs[srcFunc];
D3D9_SetRenderState(D3DRS_SRCBLEND, gfx_srcBlendFunc, "D3D9_SetAlphaBlendFunc_Src");
gfx_dstBlendFunc = funcs[dstFunc];
D3D9_SetRenderState2(D3DRS_DESTBLEND, gfx_dstBlendFunc, "D3D9_SetAlphaBlendFunc_Dst");
}
void Gfx_SetAlphaArgBlend(bool enabled) {
@ -640,24 +640,24 @@ void Gfx_SetAlphaArgBlend(bool enabled) {
if (res) Logger_Abort2(res, "D3D9_SetAlphaArgBlend");
}
void Gfx_ClearCol(PackedCol col) { d3d9_clearCol.C = col; }
void Gfx_ClearCol(PackedCol col) { gfx_clearCol.C = col; }
void Gfx_SetColWriteMask(bool r, bool g, bool b, bool a) {
DWORD channels = (r ? 1u : 0u) | (g ? 2u : 0u) | (b ? 4u : 0u) | (a ? 8u : 0u);
D3D9_SetRenderState(D3DRS_COLORWRITEENABLE, channels, "D3D9_SetColourWrite");
}
void Gfx_SetDepthTest(bool enabled) {
d3d9_depthTesting = enabled;
gfx_depthTesting = enabled;
D3D9_SetRenderState(D3DRS_ZENABLE, enabled, "D3D9_SetDepthTest");
}
void Gfx_SetDepthTestFunc(CompareFunc func) {
d3d9_depthTestFunc = d3d9_compareFuncs[func];
D3D9_SetRenderState(D3DRS_ZFUNC, d3d9_alphaTestFunc, "D3D9_SetDepthTestFunc");
gfx_depthTestFunc = d3d9_compareFuncs[func];
D3D9_SetRenderState(D3DRS_ZFUNC, gfx_alphaTestFunc, "D3D9_SetDepthTestFunc");
}
void Gfx_SetDepthWrite(bool enabled) {
d3d9_depthWriting = enabled;
gfx_depthWriting = enabled;
D3D9_SetRenderState(D3DRS_ZWRITEENABLE, enabled, "D3D9_SetDepthWrite");
}
@ -673,24 +673,24 @@ static void D3D9_SetDefaultRenderStates(void) {
static void D3D9_RestoreRenderStates(void) {
union IntAndFloat raw;
D3D9_SetRenderState(D3DRS_ALPHATESTENABLE, d3d9_alphaTesting, "D3D9_AlphaTest");
D3D9_SetRenderState2(D3DRS_ALPHABLENDENABLE, d3d9_alphaBlending, "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_SetRenderState(D3DRS_ALPHATESTENABLE, gfx_alphaTesting, "D3D9_AlphaTest");
D3D9_SetRenderState2(D3DRS_ALPHABLENDENABLE, gfx_alphaBlending, "D3D9_AlphaBlend");
D3D9_SetRenderState2(D3DRS_ALPHAFUNC, gfx_alphaTestFunc, "D3D9_AlphaTestFunc");
D3D9_SetRenderState2(D3DRS_ALPHAREF, gfx_alphaTestRef, "D3D9_AlphaRefFunc");
D3D9_SetRenderState2(D3DRS_SRCBLEND, gfx_srcBlendFunc, "D3D9_AlphaSrcBlend");
D3D9_SetRenderState2(D3DRS_DESTBLEND, gfx_dstBlendFunc, "D3D9_AlphaDstBlend");
D3D9_SetRenderState2(D3DRS_FOGENABLE, gfx_fogEnabled, "D3D9_Fog");
D3D9_SetRenderState2(D3DRS_FOGCOLOR, d3d9_fogCol.Raw, "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_fogMode, "D3D9_FogMode");
D3D9_SetRenderState2(D3DRS_FOGCOLOR, gfx_fogCol.Raw, "gfx_fogColor");
raw.f = gfx_fogDensity;
D3D9_SetRenderState2(D3DRS_FOGDENSITY, raw.u, "gfx_fogDensity");
raw.f = gfx_fogEnd;
D3D9_SetRenderState2(D3DRS_FOGEND, raw.u, "gfx_fogEnd");
D3D9_SetRenderState2(D3DRS_FOGTABLEMODE, gfx_fogMode, "D3D9_FogMode");
D3D9_SetRenderState2(D3DRS_ZFUNC, d3d9_depthTestFunc, "D3D9_DepthTestFunc");
D3D9_SetRenderState2(D3DRS_ZENABLE, d3d9_depthTesting, "D3D9_DepthTest");
D3D9_SetRenderState2(D3DRS_ZWRITEENABLE, d3d9_depthWriting, "D3D9_DepthWrite");
D3D9_SetRenderState2(D3DRS_ZFUNC, gfx_depthTestFunc, "D3D9_DepthTestFunc");
D3D9_SetRenderState2(D3DRS_ZENABLE, gfx_depthTesting, "D3D9_DepthTest");
D3D9_SetRenderState2(D3DRS_ZWRITEENABLE, gfx_depthWriting, "D3D9_DepthWrite");
}
@ -896,7 +896,7 @@ void Gfx_SetVSync(bool value) {
void Gfx_BeginFrame(void) { IDirect3DDevice9_BeginScene(device); }
void Gfx_Clear(void) {
DWORD flags = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER;
ReturnCode res = IDirect3DDevice9_Clear(device, 0, NULL, flags, d3d9_clearCol.Raw, 1.0f, 0);
ReturnCode res = IDirect3DDevice9_Clear(device, 0, NULL, flags, gfx_clearCol.Raw, 1.0f, 0);
if (res) Logger_Abort2(res, "D3D9_Clear");
}
@ -937,27 +937,27 @@ static const char* D3D9_StrFormat(D3DFORMAT format) {
return "(unknown)";
}
static float d3d9_totalMem;
static float gfx_totalMem;
void Gfx_MakeApiInfo(void) {
D3DADAPTER_IDENTIFIER9 adapter = { 0 };
int pointerSize = sizeof(void*) * 8;
IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &adapter);
d3d9_totalMem = IDirect3DDevice9_GetAvailableTextureMem(device) / (1024.0f * 1024.0f);
gfx_totalMem = IDirect3DDevice9_GetAvailableTextureMem(device) / (1024.0f * 1024.0f);
String_Format1(&Gfx_ApiInfo[0], "-- Using Direct3D9 (%i bit) --", &pointerSize);
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));
String_Format1(&Gfx_ApiInfo[5], "Depth buffer format: %c", D3D9_StrFormat(gfx_depthFormat));
String_Format1(&Gfx_ApiInfo[6], "Back buffer format: %c", D3D9_StrFormat(gfx_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);
String_Format2(&Gfx_ApiInfo[3], "Video memory: %f2 MB total, %f2 free", &gfx_totalMem, &mem);
}
void Gfx_OnWindowResize(void) {
@ -988,9 +988,9 @@ void Gfx_OnWindowResize(void) {
#endif
#if defined CC_BUILD_GL11
static GfxResourceID gl_activeList;
static GfxResourceID gfx_activeList;
#define gl_DYNAMICLISTID 1234567891
static void* gl_dynamicListData;
static void* gfx_dynamicListData;
static uint16_t gl_indices[GFX_MAX_INDICES];
#elif defined CC_BUILD_GLMODERN
#define _glBindBuffer(t,b) glBindBuffer(t,b)
@ -1027,8 +1027,8 @@ static int gl_compare[8] = { GL_ALWAYS, GL_NOTEQUAL, GL_NEVER, GL_LESS, GL_LEQUA
typedef void (*GL_SetupVBFunc)(void);
typedef void (*GL_SetupVBRangeFunc)(int startVertex);
static GL_SetupVBFunc gl_setupVBFunc;
static GL_SetupVBRangeFunc gl_setupVBRangeFunc;
static GL_SetupVBFunc gfx_setupVBFunc;
static GL_SetupVBRangeFunc gfx_setupVBRangeFunc;
static void GL_CheckSupport(void);
static void GL_InitState(void);
@ -1133,7 +1133,10 @@ void Gfx_DisableMipmaps(void) { }
/*########################################################################################################################*
*-----------------------------------------------------State management----------------------------------------------------*
*#########################################################################################################################*/
static PackedCol gl_lastClearCol;
static PackedCol gfx_clearCol, gfx_fogCol;
static float gfx_fogEnd = -1, gfx_fogDensity = -1;
static int gfx_fogMode = -1;
void Gfx_SetFaceCulling(bool enabled) { gl_Toggle(GL_CULL_FACE); }
void Gfx_SetAlphaBlending(bool enabled) { gl_Toggle(GL_BLEND); }
@ -1144,9 +1147,9 @@ void Gfx_SetAlphaBlendFunc(BlendFunc srcFunc, BlendFunc dstFunc) {
void Gfx_SetAlphaArgBlend(bool enabled) { }
void Gfx_ClearCol(PackedCol col) {
if (PackedCol_Equals(col, gl_lastClearCol)) return;
if (PackedCol_Equals(col, gfx_clearCol)) return;
glClearColor(col.R / 255.0f, col.G / 255.0f, col.B / 255.0f, col.A / 255.0f);
gl_lastClearCol = col;
gfx_clearCol = col;
}
void Gfx_SetColWriteMask(bool r, bool g, bool b, bool a) {
@ -1319,6 +1322,7 @@ void Gfx_OnWindowResize(void) {
#define FTR_TEX_MATRIX (1 << 2)
#define FTR_LINEAR_FOG (1 << 3)
#define FTR_DENSIT_FOG (1 << 4)
#define FTR_HASANY_FOG (FTR_LINEAR_FOG | FTR_DENSIT_FOG)
#define UNI_MVP_MATRIX (1 << 0)
#define UNI_TEX_MATRIX (1 << 1)
@ -1359,7 +1363,7 @@ static struct GLShader {
{ FTR_DENSIT_FOG | FTR_TEXTURE_UV | FTR_TEX_MATRIX },
{ FTR_DENSIT_FOG | FTR_TEXTURE_UV | FTR_TEX_MATRIX | FTR_ALPHA_TEST },
};
static struct GLShader* gl_activeShader;
static struct GLShader* gfx_activeShader;
/* Generates source code for a GLSL vertex shader, based on shader's flags */
static void Gfx_GenVertexShader(const struct GLShader* shader, String* dst) {
@ -1373,6 +1377,7 @@ static void Gfx_GenVertexShader(const struct GLShader* shader, String* dst) {
if (uv) String_AppendConst(dst, "varying vec2 out_uv;\n");
String_AppendConst(dst, "uniform mat4 mvp;\n");
if (tm) String_AppendConst(dst, "uniform mat4 texMatrix;\n");
String_AppendConst(dst, "void main() {\n");
String_AppendConst(dst, " gl_Position = mvp * vec4(in_pos, 1.0);\n");
String_AppendConst(dst, " out_col = in_col;\n");
@ -1386,16 +1391,27 @@ static void Gfx_GenVertexShader(const struct GLShader* shader, String* dst) {
static void Gfx_GenFragmentShader(const struct GLShader* shader, String* dst) {
int uv = shader->Features & FTR_TEXTURE_UV;
int al = shader->Features & FTR_ALPHA_TEST;
int fl = shader->Features & FTR_LINEAR_FOG;
int fd = shader->Features & FTR_DENSIT_FOG;
int fm = shader->Features & FTR_HASANY_FOG;
String_AppendConst(dst, "precision highp float;\n");
String_AppendConst(dst, "varying vec4 out_col;\n");
if (uv) String_AppendConst(dst, "varying vec2 out_uv;\n");
if (uv) String_AppendConst(dst, "uniform sampler2D texImage;\n");
if (fm) String_AppendConst(dst, "uniform vec4 fogCol;\n");
if (fl) String_AppendConst(dst, "uniform float fogEnd;\n");
if (fd) String_AppendConst(dst, "uniform float fogDensity;\n");
String_AppendConst(dst, "void main() {\n");
if (uv) String_AppendConst(dst, " vec4 col = texture2D(texImage, out_uv) * out_col;");
else String_AppendConst(dst, " vec4 col = out_col;");
if (al) String_AppendConst(dst, " if (col.a < 0.5) discard;");
String_AppendConst(dst, " gl_FragColor = col;");
if (uv) String_AppendConst(dst, " vec4 col = texture2D(texImage, out_uv) * out_col;\n");
else String_AppendConst(dst, " vec4 col = out_col;\n");
if (al) String_AppendConst(dst, " if (col.a < 0.5) discard;\n");
if (fm) String_AppendConst(dst, " float depth = gl_FragCoord.z / gl_FragCoord.w;\n");
if (fl) String_AppendConst(dst, " float f = clamp((fogEnd - depth) / fogEnd, 0.0, 1.0);\n");
if (fd) String_AppendConst(dst, " float f = clamp(exp(fogDensity * depth), 0.0, 1.0);\n");
if (fm) String_AppendConst(dst, " col = f * col + (1.0 - f) * fogCol;\n");
String_AppendConst(dst, " gl_FragColor = col;\n");
String_AppendConst(dst, "}");
}
@ -1485,17 +1501,31 @@ static void Gfx_DirtyUniform(int uniform) {
/* Sends changes uniforms to the GPU for current program */
static void Gfx_ReloadUniforms(void) {
struct GLShader* s = gl_activeShader;
struct GLShader* s = gfx_activeShader;
if (s->Uniforms & UNI_MVP_MATRIX) {
glUniformMatrix4fv(s->Locations[0], 1, false, &_mvp);
s->Uniforms &= ~UNI_MVP_MATRIX;
}
if ((s->Uniforms & UNI_TEX_MATRIX) && (s->Features & FTR_TEX_MATRIX)) {
glUniformMatrix4fv(s->Locations[1], 1, false, &_tex);
s->Uniforms &= ~UNI_TEX_MATRIX;
}
if ((s->Uniforms & UNI_FOG_COL) && (s->Features & FTR_HASANY_FOG)) {
glUniform4f(s->Locations[2], gfx_fogCol.R / 255.0f, gfx_fogCol.G / 255.0f,
gfx_fogCol.B / 255.0f, gfx_fogCol.A / 255.0f);
s->Uniforms &= ~UNI_FOG_COL;
}
if ((s->Uniforms & UNI_FOG_END) && (s->Features & FTR_LINEAR_FOG)) {
glUniform1f(s->Locations[3], gfx_fogEnd);
s->Uniforms &= ~UNI_FOG_END;
}
if ((s->Uniforms & UNI_FOG_DENS) && (s->Features & FTR_DENSIT_FOG)) {
/* See https://docs.microsoft.com/en-us/previous-versions/ms537113(v%3Dvs.85) */
/* The equation for EXP mode is exp(-density * z), so just negate density here */
glUniform1f(s->Locations[4], -gfx_fogDensity);
s->Uniforms &= ~UNI_FOG_DENS;
}
}
/* Switches program to one that duplicates current fixed function state */
@ -1504,24 +1534,52 @@ static void Gfx_SwitchProgram(void) {
struct GLShader* shader;
int index = 0;
if (gfx_fogEnabled) {
index += 6; /* linear fog */
if (gfx_fogMode >= 1) index += 6; /* exp fog */
}
if (gfx_batchFormat == VERTEX_FORMAT_P3FT2FC4B) index += 2;
if (gfx_texTransform) index += 2;
if (gfx_alphaTest) index += 1;
shader = &shaders[index];
if (shader == gl_activeShader) return;
if (shader == gfx_activeShader) { Gfx_ReloadUniforms(); return; }
if (!shader->Program) Gfx_CompileProgram(shader);
gl_activeShader = shader;
gfx_activeShader = shader;
glUseProgram(shader->Program);
Gfx_ReloadUniforms();
}
void Gfx_SetFog(bool enabled) { }
void Gfx_SetFogCol(PackedCol col) { }
void Gfx_SetFogDensity(float value) { }
void Gfx_SetFogEnd(float value) { }
void Gfx_SetFogMode(FogFunc func) { }
void Gfx_SetFog(bool enabled) { gfx_fogEnabled = enabled; Gfx_SwitchProgram(); }
void Gfx_SetFogCol(PackedCol col) {
if (PackedCol_Equals(col, gfx_fogCol)) return;
gfx_fogCol = col;
Gfx_DirtyUniform(UNI_FOG_COL);
Gfx_ReloadUniforms();
}
void Gfx_SetFogDensity(float value) {
if (gfx_fogDensity == value) return;
gfx_fogDensity = value;
Gfx_DirtyUniform(UNI_FOG_DENS);
Gfx_ReloadUniforms();
}
void Gfx_SetFogEnd(float value) {
if (gfx_fogEnd == value) return;
gfx_fogEnd = value;
Gfx_DirtyUniform(UNI_FOG_END);
Gfx_ReloadUniforms();
}
void Gfx_SetFogMode(FogFunc func) {
if (gfx_fogMode == func) return;
gfx_fogMode = func;
Gfx_SwitchProgram();
}
void Gfx_SetTexturing(bool enabled) { }
void Gfx_SetAlphaTest(bool enabled) { gfx_alphaTest = enabled; Gfx_SwitchProgram(); }
@ -1589,28 +1647,28 @@ void Gfx_SetVertexFormat(VertexFormat fmt) {
if (fmt == VERTEX_FORMAT_P3FT2FC4B) {
glEnableVertexAttribArray(2);
gl_setupVBFunc = GL_SetupVbPos3fTex2fCol4b;
gl_setupVBRangeFunc = GL_SetupVbPos3fTex2fCol4b_Range;
gfx_setupVBFunc = GL_SetupVbPos3fTex2fCol4b;
gfx_setupVBRangeFunc = GL_SetupVbPos3fTex2fCol4b_Range;
} else {
glDisableVertexAttribArray(2);
gl_setupVBFunc = GL_SetupVbPos3fCol4b;
gl_setupVBRangeFunc = GL_SetupVbPos3fCol4b_Range;
gfx_setupVBFunc = GL_SetupVbPos3fCol4b;
gfx_setupVBRangeFunc = GL_SetupVbPos3fCol4b_Range;
}
Gfx_SwitchProgram();
}
void Gfx_DrawVb_Lines(int verticesCount) {
gl_setupVBFunc();
gfx_setupVBFunc();
glDrawArrays(GL_LINES, 0, verticesCount);
}
void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
gl_setupVBRangeFunc(startVertex);
gfx_setupVBRangeFunc(startVertex);
glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, NULL);
}
void Gfx_DrawVb_IndexedTris(int verticesCount) {
gl_setupVBFunc();
gfx_setupVBFunc();
glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, NULL);
}
@ -1628,10 +1686,6 @@ void Gfx_DrawIndexedVb_TrisT2fC4b(int verticesCount, int startVertex) {
*------------------------------------------------------OpenGL legacy------------------------------------------------------*
*#########################################################################################################################*/
#ifndef CC_BUILD_GLMODERN
static PackedCol gl_lastFogCol;
static float gl_lastFogEnd = -1, gl_lastFogDensity = -1;
static int gl_lastFogMode = -1;
void Gfx_SetFog(bool enabled) {
gfx_fogEnabled = enabled;
gl_Toggle(GL_FOG);
@ -1639,33 +1693,33 @@ void Gfx_SetFog(bool enabled) {
void Gfx_SetFogCol(PackedCol col) {
float rgba[4];
if (PackedCol_Equals(col, gl_lastFogCol)) return;
if (PackedCol_Equals(col, gfx_fogCol)) return;
rgba[0] = col.R / 255.0f; rgba[1] = col.G / 255.0f;
rgba[2] = col.B / 255.0f; rgba[3] = col.A / 255.0f;
glFogfv(GL_FOG_COLOR, rgba);
gl_lastFogCol = col;
gfx_fogCol = col;
}
void Gfx_SetFogDensity(float value) {
if (value == gl_lastFogDensity) return;
if (value == gfx_fogDensity) return;
glFogf(GL_FOG_DENSITY, value);
gl_lastFogDensity = value;
gfx_fogDensity = value;
}
void Gfx_SetFogEnd(float value) {
if (value == gl_lastFogEnd) return;
if (value == gfx_fogEnd) return;
glFogf(GL_FOG_END, value);
gl_lastFogEnd = value;
gfx_fogEnd = value;
}
void Gfx_SetFogMode(FogFunc func) {
static GLint modes[3] = { GL_LINEAR, GL_EXP, GL_EXP2 };
if (func == gl_lastFogMode) return;
if (func == gfx_fogMode) return;
glFogi(GL_FOG_MODE, modes[func]);
gl_lastFogMode = func;
gfx_fogMode = func;
}
void Gfx_SetTexturing(bool enabled) { gl_Toggle(GL_TEXTURE_2D); }
@ -1699,7 +1753,7 @@ static void GL_InitState(void) {
*#########################################################################################################################*/
#ifdef CC_BUILD_GL11
/* point to client side dynamic array */
#define VB_PTR ((uint8_t*)gl_dynamicListData)
#define VB_PTR ((uint8_t*)gfx_dynamicListData)
#define IB_PTR gl_indices
#else
/* no client side array, use vertex buffer object */
@ -1738,33 +1792,33 @@ void Gfx_SetVertexFormat(VertexFormat fmt) {
if (fmt == VERTEX_FORMAT_P3FT2FC4B) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
gl_setupVBFunc = GL_SetupVbPos3fTex2fCol4b;
gl_setupVBRangeFunc = GL_SetupVbPos3fTex2fCol4b_Range;
gfx_setupVBFunc = GL_SetupVbPos3fTex2fCol4b;
gfx_setupVBRangeFunc = GL_SetupVbPos3fTex2fCol4b_Range;
} else {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
gl_setupVBFunc = GL_SetupVbPos3fCol4b;
gl_setupVBRangeFunc = GL_SetupVbPos3fCol4b_Range;
gfx_setupVBFunc = GL_SetupVbPos3fCol4b;
gfx_setupVBRangeFunc = GL_SetupVbPos3fCol4b_Range;
}
}
void Gfx_DrawVb_Lines(int verticesCount) {
gl_setupVBFunc();
gfx_setupVBFunc();
glDrawArrays(GL_LINES, 0, verticesCount);
}
void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
#ifdef CC_BUILD_GL11
if (gl_activeList != gl_DYNAMICLISTID) { glCallList(gl_activeList); return; }
if (gfx_activeList != gl_DYNAMICLISTID) { glCallList(gfx_activeList); return; }
#endif
gl_setupVBRangeFunc(startVertex);
gfx_setupVBRangeFunc(startVertex);
glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR);
}
void Gfx_DrawVb_IndexedTris(int verticesCount) {
#ifdef CC_BUILD_GL11
if (gl_activeList != gl_DYNAMICLISTID) { glCallList(gl_activeList); return; }
if (gfx_activeList != gl_DYNAMICLISTID) { glCallList(gfx_activeList); return; }
#endif
gl_setupVBFunc();
gfx_setupVBFunc();
glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR);
}
@ -1814,21 +1868,21 @@ GfxResourceID Gfx_CreateVb(void* vertices, VertexFormat fmt, int count) {
/* We need to setup client state properly when building the list */
int curFormat = gfx_batchFormat;
Gfx_SetVertexFormat(fmt);
void* dyn_data = gl_dynamicListData;
gl_dynamicListData = vertices;
void* dyn_data = gfx_dynamicListData;
gfx_dynamicListData = vertices;
glNewList(list, GL_COMPILE);
gl_setupVBFunc();
gfx_setupVBFunc();
glDrawElements(GL_TRIANGLES, ICOUNT(count), GL_UNSIGNED_SHORT, gl_indices);
glEndList();
Gfx_SetVertexFormat(curFormat);
gl_dynamicListData = dyn_data;
gfx_dynamicListData = dyn_data;
return list;
}
GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) { return GFX_NULL; }
void Gfx_BindVb(GfxResourceID vb) { gl_activeList = vb; }
void Gfx_BindVb(GfxResourceID vb) { gfx_activeList = vb; }
void Gfx_BindIb(GfxResourceID ib) { }
void Gfx_DeleteIb(GfxResourceID* ib) { }
@ -1839,16 +1893,16 @@ void Gfx_DeleteVb(GfxResourceID* vb) {
}
void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
gl_activeList = gl_DYNAMICLISTID;
gl_dynamicListData = vertices;
gfx_activeList = gl_DYNAMICLISTID;
gfx_dynamicListData = vertices;
}
static GfxResourceID gl_lastPartialList;
void Gfx_DrawIndexedVb_TrisT2fC4b(int verticesCount, int startVertex) {
/* TODO: This renders the whole map, bad performance!! FIX FIX */
if (gl_activeList == gl_lastPartialList) return;
glCallList(gl_activeList);
gl_lastPartialList = gl_activeList;
if (gfx_activeList == gl_lastPartialList) return;
glCallList(gfx_activeList);
gl_lastPartialList = gfx_activeList;
}
static void GL_CheckSupport(void) {