|
|
@@ -228,6 +228,7 @@ namespace bgfx
|
|
|
ARB_multisample,
|
|
|
ARB_sampler_objects,
|
|
|
ARB_seamless_cube_map,
|
|
|
+ ARB_shader_texture_lod,
|
|
|
ARB_texture_compression_rgtc,
|
|
|
ARB_texture_float,
|
|
|
ARB_texture_multisample,
|
|
|
@@ -248,6 +249,7 @@ namespace bgfx
|
|
|
EXT_framebuffer_blit,
|
|
|
EXT_framebuffer_sRGB,
|
|
|
EXT_occlusion_query_boolean,
|
|
|
+ EXT_shadow_samplers,
|
|
|
EXT_texture_array,
|
|
|
EXT_texture_compression_dxt1,
|
|
|
EXT_texture_compression_latc,
|
|
|
@@ -314,6 +316,7 @@ namespace bgfx
|
|
|
{ "GL_ARB_multisample", false, true },
|
|
|
{ "GL_ARB_sampler_objects", BGFX_CONFIG_RENDERER_OPENGL >= 33, true },
|
|
|
{ "GL_ARB_seamless_cube_map", BGFX_CONFIG_RENDERER_OPENGL >= 32, true },
|
|
|
+ { "GL_ARB_shader_texture_lod", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
|
|
|
{ "GL_ARB_texture_compression_rgtc", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
|
|
|
{ "GL_ARB_texture_float", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
|
|
|
{ "GL_ARB_texture_multisample", BGFX_CONFIG_RENDERER_OPENGL >= 32, true },
|
|
|
@@ -334,6 +337,7 @@ namespace bgfx
|
|
|
{ "GL_EXT_framebuffer_blit", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
|
|
|
{ "GL_EXT_framebuffer_sRGB", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
|
|
|
{ "GL_EXT_occlusion_query_boolean", false, true },
|
|
|
+ { "GL_EXT_shadow_samplers", false, true },
|
|
|
{ "GL_EXT_texture_array", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
|
|
|
{ "GL_EXT_texture_compression_dxt1", false, true },
|
|
|
{ "GL_EXT_texture_compression_latc", false, true },
|
|
|
@@ -377,6 +381,46 @@ namespace bgfx
|
|
|
{ "GL_OES_vertex_type_10_10_10_2", false, true },
|
|
|
};
|
|
|
|
|
|
+ static const char* s_ARB_shader_texture_lod[] =
|
|
|
+ {
|
|
|
+ "texture2DLod",
|
|
|
+ "texture2DProjLod",
|
|
|
+ "texture3DLod",
|
|
|
+ "texture3DProjLod",
|
|
|
+ "textureCubeLod",
|
|
|
+ "shadow2DLod",
|
|
|
+ "shadow2DProjLod",
|
|
|
+ NULL
|
|
|
+ // "texture1DLod",
|
|
|
+ // "texture1DProjLod",
|
|
|
+ // "shadow1DLod",
|
|
|
+ // "shadow1DProjLod",
|
|
|
+ };
|
|
|
+
|
|
|
+ static const char* s_EXT_shadow_samplers[] =
|
|
|
+ {
|
|
|
+ "shadow2D",
|
|
|
+ "shadow2DProj",
|
|
|
+ NULL
|
|
|
+ };
|
|
|
+
|
|
|
+ static const char* s_OES_standard_derivatives[] =
|
|
|
+ {
|
|
|
+ "dFdx",
|
|
|
+ "dFdy",
|
|
|
+ "fwidth",
|
|
|
+ NULL
|
|
|
+ };
|
|
|
+
|
|
|
+ static const char* s_OES_texture_3D[] =
|
|
|
+ {
|
|
|
+ "texture3D",
|
|
|
+ "texture3DProj",
|
|
|
+ "texture3DLod",
|
|
|
+ "texture3DProjLod",
|
|
|
+ NULL
|
|
|
+ };
|
|
|
+
|
|
|
#if BGFX_CONFIG_RENDERER_OPENGLES3
|
|
|
# define s_vertexAttribDivisor glVertexAttribDivisor
|
|
|
# define s_drawArraysInstanced glDrawArraysInstanced
|
|
|
@@ -1786,33 +1830,6 @@ namespace bgfx
|
|
|
bx::write(_writer, _str, (int32_t)strlen(_str) );
|
|
|
}
|
|
|
|
|
|
- const char* findMatch(const char* _str, const char* _word)
|
|
|
- {
|
|
|
- size_t len = strlen(_word);
|
|
|
- const char* ptr = strstr(_str, _word);
|
|
|
- for (; NULL != ptr; ptr = strstr(ptr + len, _word) )
|
|
|
- {
|
|
|
- if (ptr != _str)
|
|
|
- {
|
|
|
- char ch = *(ptr - 1);
|
|
|
- if (isalnum(ch) || '_' == ch)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- char ch = ptr[len];
|
|
|
- if (isalnum(ch) || '_' == ch)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- return ptr;
|
|
|
- }
|
|
|
-
|
|
|
- return ptr;
|
|
|
- }
|
|
|
-
|
|
|
void strins(char* _str, const char* _insert)
|
|
|
{
|
|
|
size_t len = strlen(_insert);
|
|
|
@@ -1838,111 +1855,146 @@ namespace bgfx
|
|
|
|
|
|
if (0 != m_id)
|
|
|
{
|
|
|
-#if BGFX_CONFIG_RENDERER_OPENGLES2
|
|
|
- bool usesDerivatives = s_extension[Extension::OES_standard_derivatives].m_supported &&
|
|
|
- ( findMatch(code, "dFdx")
|
|
|
- || findMatch(code, "dFdy")
|
|
|
- || findMatch(code, "fwidth")
|
|
|
- );
|
|
|
+ if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES2) )
|
|
|
+ {
|
|
|
+ bool usesDerivatives = s_extension[Extension::OES_standard_derivatives].m_supported
|
|
|
+ && bx::findIdentifierMatch(code, s_OES_standard_derivatives)
|
|
|
+ ;
|
|
|
|
|
|
- bool usesFragDepth = !!findMatch(code, "gl_FragDepth");
|
|
|
+ bool usesFragDepth = !!bx::findIdentifierMatch(code, "gl_FragDepth");
|
|
|
|
|
|
- bool usesTexture3D = s_extension[Extension::OES_texture_3D].m_supported &&
|
|
|
- ( findMatch(code, "texture3D")
|
|
|
- || findMatch(code, "texture3DProj")
|
|
|
- || findMatch(code, "texture3DLod")
|
|
|
- || findMatch(code, "texture3DProjLod")
|
|
|
- );
|
|
|
+ bool usesShadowSamplers = s_extension[Extension::EXT_shadow_samplers].m_supported
|
|
|
+ && bx::findIdentifierMatch(code, s_EXT_shadow_samplers)
|
|
|
+ ;
|
|
|
|
|
|
- if (usesDerivatives
|
|
|
- || usesFragDepth
|
|
|
- || usesTexture3D)
|
|
|
- {
|
|
|
- int32_t codeLen = (int32_t)strlen(code);
|
|
|
- int32_t tempLen = codeLen + 1024;
|
|
|
- char* temp = (char*)alloca(tempLen);
|
|
|
- bx::StaticMemoryBlockWriter writer(temp, tempLen);
|
|
|
+ bool usesTexture3D = s_extension[Extension::OES_texture_3D].m_supported
|
|
|
+ && bx::findIdentifierMatch(code, s_OES_texture_3D)
|
|
|
+ ;
|
|
|
|
|
|
- if (usesDerivatives)
|
|
|
+ if (usesDerivatives
|
|
|
+ || usesFragDepth
|
|
|
+ || usesShadowSamplers
|
|
|
+ || usesTexture3D)
|
|
|
{
|
|
|
- writeString(&writer, "#extension GL_OES_standard_derivatives : enable\n");
|
|
|
- }
|
|
|
+ int32_t codeLen = (int32_t)strlen(code);
|
|
|
+ int32_t tempLen = codeLen + 1024;
|
|
|
+ char* temp = (char*)alloca(tempLen);
|
|
|
+ bx::StaticMemoryBlockWriter writer(temp, tempLen);
|
|
|
|
|
|
- bool insertFragDepth = false;
|
|
|
- if (usesFragDepth)
|
|
|
- {
|
|
|
- if (s_extension[Extension::EXT_frag_depth].m_supported)
|
|
|
+ if (usesDerivatives)
|
|
|
{
|
|
|
- writeString(&writer
|
|
|
- , "#extension GL_EXT_frag_depth : enable\n"
|
|
|
- "#define gl_FragDepth gl_FragDepthEXT\n"
|
|
|
- );
|
|
|
-
|
|
|
- char str[128];
|
|
|
- bx::snprintf(str, BX_COUNTOF(str), "%s float gl_FragDepthEXT;\n"
|
|
|
- , s_extension[Extension::OES_fragment_precision_high].m_supported ? "highp" : "mediump"
|
|
|
- );
|
|
|
- writeString(&writer, str);
|
|
|
+ writeString(&writer, "#extension GL_OES_standard_derivatives : enable\n");
|
|
|
}
|
|
|
- else
|
|
|
+
|
|
|
+ bool insertFragDepth = false;
|
|
|
+ if (usesFragDepth)
|
|
|
{
|
|
|
- insertFragDepth = true;
|
|
|
+ if (s_extension[Extension::EXT_frag_depth].m_supported)
|
|
|
+ {
|
|
|
+ writeString(&writer
|
|
|
+ , "#extension GL_EXT_frag_depth : enable\n"
|
|
|
+ "#define gl_FragDepth gl_FragDepthEXT\n"
|
|
|
+ );
|
|
|
+
|
|
|
+ char str[128];
|
|
|
+ bx::snprintf(str, BX_COUNTOF(str), "%s float gl_FragDepthEXT;\n"
|
|
|
+ , s_extension[Extension::OES_fragment_precision_high].m_supported ? "highp" : "mediump"
|
|
|
+ );
|
|
|
+ writeString(&writer, str);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ insertFragDepth = true;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if (usesTexture3D)
|
|
|
- {
|
|
|
- writeString(&writer, "#extension GL_OES_texture_3D : enable\n");
|
|
|
- }
|
|
|
+ if (usesShadowSamplers)
|
|
|
+ {
|
|
|
+ writeString(&writer, "#extension GL_EXT_shadow_samplers : enable\n");
|
|
|
+ }
|
|
|
|
|
|
- bx::write(&writer, code, codeLen);
|
|
|
- bx::write(&writer, '\0');
|
|
|
+ if (usesTexture3D)
|
|
|
+ {
|
|
|
+ writeString(&writer, "#extension GL_OES_texture_3D : enable\n");
|
|
|
+ }
|
|
|
|
|
|
- code = temp;
|
|
|
+ bx::write(&writer, code, codeLen);
|
|
|
+ bx::write(&writer, '\0');
|
|
|
|
|
|
- if (insertFragDepth)
|
|
|
- {
|
|
|
- char* entry = strstr(temp, "void main ()");
|
|
|
- if (NULL != entry)
|
|
|
+ code = temp;
|
|
|
+
|
|
|
+ if (insertFragDepth)
|
|
|
{
|
|
|
- char* brace = strstr(entry, "{");
|
|
|
- if (NULL != brace)
|
|
|
+ char* entry = strstr(temp, "void main ()");
|
|
|
+ if (NULL != entry)
|
|
|
{
|
|
|
- const char* end = bx::strmb(brace, '{', '}');
|
|
|
- if (NULL != end)
|
|
|
+ char* brace = strstr(entry, "{");
|
|
|
+ if (NULL != brace)
|
|
|
{
|
|
|
- strins(brace+1, "\n float gl_FragDepth = 0.0;\n");
|
|
|
+ const char* end = bx::strmb(brace, '{', '}');
|
|
|
+ if (NULL != end)
|
|
|
+ {
|
|
|
+ strins(brace+1, "\n float gl_FragDepth = 0.0;\n");
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-#elif BGFX_CONFIG_RENDERER_OPENGL >= 31
|
|
|
- int32_t codeLen = (int32_t)strlen(code);
|
|
|
- int32_t tempLen = codeLen + 1024;
|
|
|
- char* temp = (char*)alloca(tempLen);
|
|
|
- bx::StaticMemoryBlockWriter writer(temp, tempLen);
|
|
|
-
|
|
|
- writeString(&writer, "#version 140\n");
|
|
|
- if (_type == GL_FRAGMENT_SHADER)
|
|
|
+ else if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL == 21) )
|
|
|
{
|
|
|
- writeString(&writer, "#define varying in\n");
|
|
|
- writeString(&writer, "#define texture2D texture\n");
|
|
|
- writeString(&writer, "#define texture3D texture\n");
|
|
|
- writeString(&writer, "#define textureCube texture\n");
|
|
|
- writeString(&writer, "out vec4 bgfx_FragColor;\n");
|
|
|
- writeString(&writer, "#define gl_FragColor bgfx_FragColor\n");
|
|
|
+ bool usesTextureLod = s_extension[Extension::ARB_shader_texture_lod].m_supported
|
|
|
+ && bx::findIdentifierMatch(code, s_ARB_shader_texture_lod)
|
|
|
+ ;
|
|
|
+
|
|
|
+ if (usesTextureLod)
|
|
|
+ {
|
|
|
+ int32_t codeLen = (int32_t)strlen(code);
|
|
|
+ int32_t tempLen = codeLen + 1024;
|
|
|
+ char* temp = (char*)alloca(tempLen);
|
|
|
+ bx::StaticMemoryBlockWriter writer(temp, tempLen);
|
|
|
+
|
|
|
+ writeString(&writer, "#version 120\n");
|
|
|
+ if (_type == GL_FRAGMENT_SHADER)
|
|
|
+ {
|
|
|
+ writeString(&writer, "#extension GL_ARB_shader_texture_lod : enable\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ bx::write(&writer, code, codeLen);
|
|
|
+ bx::write(&writer, '\0');
|
|
|
+ code = temp;
|
|
|
+ }
|
|
|
}
|
|
|
- else
|
|
|
+ else if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL >= 31) )
|
|
|
{
|
|
|
- writeString(&writer, "#define attribute in\n");
|
|
|
- writeString(&writer, "#define varying out\n");
|
|
|
- }
|
|
|
+ int32_t codeLen = (int32_t)strlen(code);
|
|
|
+ int32_t tempLen = codeLen + 1024;
|
|
|
+ char* temp = (char*)alloca(tempLen);
|
|
|
+ bx::StaticMemoryBlockWriter writer(temp, tempLen);
|
|
|
|
|
|
- bx::write(&writer, code, codeLen);
|
|
|
- bx::write(&writer, '\0');
|
|
|
- code = temp;
|
|
|
-#endif // BGFX_CONFIG_RENDERER_OPENGLES2
|
|
|
+ writeString(&writer, "#version 140\n");
|
|
|
+ if (_type == GL_FRAGMENT_SHADER)
|
|
|
+ {
|
|
|
+ writeString(&writer, "#define varying in\n");
|
|
|
+ writeString(&writer, "#define texture2D texture\n");
|
|
|
+ writeString(&writer, "#define texture2DLod textureLod\n");
|
|
|
+ writeString(&writer, "#define texture3D texture\n");
|
|
|
+ writeString(&writer, "#define texture3DLod textureLod\n");
|
|
|
+ writeString(&writer, "#define textureCube texture\n");
|
|
|
+ writeString(&writer, "#define textureCubeLod textureLod\n");
|
|
|
+ writeString(&writer, "out vec4 bgfx_FragColor;\n");
|
|
|
+ writeString(&writer, "#define gl_FragColor bgfx_FragColor\n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ writeString(&writer, "#define attribute in\n");
|
|
|
+ writeString(&writer, "#define varying out\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ bx::write(&writer, code, codeLen);
|
|
|
+ bx::write(&writer, '\0');
|
|
|
+ code = temp;
|
|
|
+ }
|
|
|
|
|
|
GL_CHECK(glShaderSource(m_id, 1, (const GLchar**)&code, NULL) );
|
|
|
GL_CHECK(glCompileShader(m_id) );
|