diff --git a/data/shaders/instanced_grass.vert b/data/shaders/instanced_grass.vert index 803fa7f92..b65a08d1f 100644 --- a/data/shaders/instanced_grass.vert +++ b/data/shaders/instanced_grass.vert @@ -9,6 +9,10 @@ layout(location = 3) in vec2 Texcoord; layout(location = 7) in vec3 Origin; layout(location = 8) in vec3 Orientation; layout(location = 9) in vec3 Scale; +#ifdef GL_ARB_bindless_texture +layout(location = 10) in sampler2D Handle; +#endif + #else in vec3 Position; in vec3 Normal; @@ -22,6 +26,9 @@ in vec3 Scale; out vec3 nor; out vec2 uv; +#ifdef GL_ARB_bindless_texture +flat out sampler2D handle; +#endif mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); @@ -33,4 +40,7 @@ void main() gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(Position, 1.); nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz; uv = Texcoord; +#ifdef GL_ARB_bindless_texture + handle = Handle; +#endif } diff --git a/data/shaders/instanced_grass_pass2.frag b/data/shaders/instanced_grass_pass2.frag new file mode 100644 index 000000000..f3134047d --- /dev/null +++ b/data/shaders/instanced_grass_pass2.frag @@ -0,0 +1,45 @@ +#ifdef GL_ARB_bindless_texture +layout(bindless_sampler) uniform sampler2D dtex; +#else +uniform sampler2D Albedo; +uniform sampler2D dtex; +#endif + +uniform vec3 SunDir; + +#ifdef GL_ARB_bindless_texture +flat in sampler2D handle; +#endif +in vec3 nor; +in vec2 uv; +out vec4 FragColor; + +vec3 getLightFactor(float specMapValue); + +void main(void) +{ + vec2 texc = gl_FragCoord.xy / screen; + float z = texture(dtex, texc).x; + + vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0f; + xpos = InverseProjectionMatrix * xpos; + xpos /= xpos.w; + vec3 eyedir = normalize(xpos.xyz); + + // Inspired from http://http.developer.nvidia.com/GPUGems3/gpugems3_ch16.html + float fEdotL = max(0., dot(SunDir, eyedir)); + float fPowEdotL = pow(fEdotL, 4.); + + float fLdotNBack = max(0., - dot(nor, SunDir) * 0.6 + 0.4); + float scattering = mix(fPowEdotL, fLdotNBack, .5); + +#ifdef GL_ARB_bindless_texture + vec4 color = texture(handle, uv); + color.xyz = pow(color.xyz, vec3(2.2)); +#else + vec4 color = texture(Albedo, uv); +#endif + if (color.a < 0.5) discard; + vec3 LightFactor = (scattering * 0.3) + getLightFactor(1.); + FragColor = vec4(color.xyz * LightFactor, 1.); +} diff --git a/data/shaders/instanced_normalmap.frag b/data/shaders/instanced_normalmap.frag new file mode 100644 index 000000000..4b4ecadcd --- /dev/null +++ b/data/shaders/instanced_normalmap.frag @@ -0,0 +1,35 @@ +#ifndef GL_ARB_bindless_texture +uniform sampler2D normalMap; +uniform sampler2D DiffuseForAlpha; +#endif + +#ifdef GL_ARB_bindless_texture +flat in sampler2D handle; +flat in sampler2D secondhandle; +#endif +in vec3 tangent; +in vec3 bitangent; +in vec2 uv; +out vec3 EncodedNormal; + +vec2 EncodeNormal(vec3 n); + +void main() +{ + // normal in Tangent Space +#ifdef GL_ARB_bindless_texture + vec3 TS_normal = 2.0 * texture(secondhandle, uv).rgb - 1.0; + float alpha = texture(handle, uv).a; +#else + vec3 TS_normal = 2.0 * texture(normalMap, uv).rgb - 1.0; + float alpha = texture(DiffuseForAlpha, uv).a; +#endif + // Because of interpolation, we need to renormalize + vec3 Frag_tangent = normalize(tangent); + vec3 Frag_normal = normalize(cross(Frag_tangent, bitangent)); + vec3 Frag_bitangent = cross(Frag_normal, Frag_tangent); + + vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent - TS_normal.z * Frag_normal; + EncodedNormal.xy = 0.5 * EncodeNormal(normalize(FragmentNormal)) + 0.5; + EncodedNormal.z = exp2(10. * (1. - alpha) + 1.); +} diff --git a/data/shaders/instanced_object_pass.vert b/data/shaders/instanced_object_pass.vert index f83c7f7b5..eb8a9e018 100644 --- a/data/shaders/instanced_object_pass.vert +++ b/data/shaders/instanced_object_pass.vert @@ -9,6 +9,11 @@ layout(location = 6) in vec3 Bitangent; layout(location = 7) in vec3 Origin; layout(location = 8) in vec3 Orientation; layout(location = 9) in vec3 Scale; +#ifdef GL_ARB_bindless_texture +layout(location = 10) in sampler2D Handle; +layout(location = 11) in sampler2D SecondHandle; +#endif + #else in vec3 Position; in vec3 Normal; @@ -27,6 +32,10 @@ out vec3 tangent; out vec3 bitangent; out vec2 uv; out vec4 color; +#ifdef GL_ARB_bindless_texture +flat out sampler2D handle; +flat out sampler2D secondhandle; +#endif mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); @@ -41,4 +50,8 @@ void main(void) bitangent = (TransposeInverseModelView * vec4(Bitangent, 1.)).xyz; uv = Texcoord; color = Color.zyxw; +#ifdef GL_ARB_bindless_texture + handle = Handle; + secondhandle = SecondHandle; +#endif } diff --git a/data/shaders/instanced_object_pass1.frag b/data/shaders/instanced_object_pass1.frag new file mode 100644 index 000000000..fc04aa63f --- /dev/null +++ b/data/shaders/instanced_object_pass1.frag @@ -0,0 +1,23 @@ +#ifndef GL_ARB_bindless_texture +uniform sampler2D tex; +#endif + +#ifdef GL_ARB_bindless_texture +flat in sampler2D handle; +#endif +in vec3 nor; +in vec2 uv; +out vec3 EncodedNormal; + +vec2 EncodeNormal(vec3 n); + +void main(void) +{ +#ifdef GL_ARB_bindless_texture + vec4 col = texture(handle, uv); +#else + vec4 col = texture(tex, uv); +#endif + EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5; + EncodedNormal.z = exp2(10. * (1. - col.a) + 1.); +} diff --git a/data/shaders/instanced_object_pass2.frag b/data/shaders/instanced_object_pass2.frag new file mode 100644 index 000000000..6cb4296a8 --- /dev/null +++ b/data/shaders/instanced_object_pass2.frag @@ -0,0 +1,24 @@ +#ifndef GL_ARB_bindless_texture +uniform sampler2D Albedo; +#endif + +#ifdef GL_ARB_bindless_texture +flat in sampler2D handle; +#endif +in vec2 uv; +in vec4 color; +out vec4 FragColor; + +vec3 getLightFactor(float specMapValue); + +void main(void) +{ +#ifdef GL_ARB_bindless_texture + vec4 col = pow(texture(handle, uv), vec4(2.2)); +#else + vec4 col = texture(Albedo, uv); +#endif + col.xyz *= pow(color.xyz, vec3(2.2)); + vec3 LightFactor = getLightFactor(1.); + FragColor = vec4(col.xyz * LightFactor, 1.); +} diff --git a/data/shaders/instanced_objectref_pass1.frag b/data/shaders/instanced_objectref_pass1.frag new file mode 100644 index 000000000..c24fcddf7 --- /dev/null +++ b/data/shaders/instanced_objectref_pass1.frag @@ -0,0 +1,25 @@ +#ifndef GL_ARB_bindless_texture +uniform sampler2D tex; +#endif + +#ifdef GL_ARB_bindless_texture +flat in sampler2D handle; +#endif +in vec3 nor; +in vec2 uv; +out vec3 EncodedNormal; + +vec2 EncodeNormal(vec3 n); + +void main() { +#ifdef GL_ARB_bindless_texture + vec4 col = texture(handle, uv); +#else + vec4 col = texture(tex, uv); +#endif + if (col.a < 0.5) + discard; + EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5; + EncodedNormal.z = 1.; +} + diff --git a/data/shaders/instanced_objectref_pass2.frag b/data/shaders/instanced_objectref_pass2.frag new file mode 100644 index 000000000..27d1bd03d --- /dev/null +++ b/data/shaders/instanced_objectref_pass2.frag @@ -0,0 +1,26 @@ +#ifndef GL_ARB_bindless_texture +uniform sampler2D Albedo; +#endif + +#ifdef GL_ARB_bindless_texture +flat in sampler2D handle; +#endif +in vec2 uv; +in vec4 color; +out vec4 FragColor; + +vec3 getLightFactor(float specMapValue); + +void main(void) +{ +#ifdef GL_ARB_bindless_texture + vec4 col = texture(handle, uv); + col.xyz = pow(col.xyz, vec3(2.2)); +#else + vec4 col = texture(Albedo, uv); +#endif + col.xyz *= pow(color.xyz, vec3(2.2)); + if (col.a * color.a < 0.5) discard; + vec3 LightFactor = getLightFactor(1.); + FragColor = vec4(col.xyz * LightFactor, 1.); +} diff --git a/data/shaders/instanced_shadow.geom b/data/shaders/instanced_shadow.geom new file mode 100644 index 000000000..1ecc55a46 --- /dev/null +++ b/data/shaders/instanced_shadow.geom @@ -0,0 +1,28 @@ +layout(triangles) in; +layout(triangle_strip, max_vertices=3) out; + +#ifdef GL_ARB_bindless_texture +flat in sampler2D hdle[3]; +#endif +in vec2 tc[3]; +in int layerId[3]; + +out vec2 uv; +#ifdef GL_ARB_bindless_texture +out flat sampler2D handle; +#endif + +void main(void) +{ + gl_Layer = layerId[0]; +#ifdef GL_ARB_bindless_texture + handle = hdle[0]; +#endif + for(int i=0; i<3; i++) + { + uv = tc[i]; + gl_Position = gl_in[i].gl_Position; + EmitVertex(); + } + EndPrimitive(); +} diff --git a/data/shaders/instanced_shadowref.frag b/data/shaders/instanced_shadowref.frag new file mode 100644 index 000000000..7ed4ab3ae --- /dev/null +++ b/data/shaders/instanced_shadowref.frag @@ -0,0 +1,21 @@ +#ifndef GL_ARB_bindless_texture +uniform sampler2D tex; +#endif + +#ifdef GL_ARB_bindless_texture +flat in sampler2D handle; +#endif +in vec2 uv; +in vec4 color; +out vec4 FragColor; + +void main(void) +{ +#ifdef GL_ARB_bindless_texture + vec4 col = texture(handle, uv); +#else + vec4 col = texture(tex, uv); +#endif + if (col.a < 0.5) discard; + FragColor = vec4(1.); +} diff --git a/data/shaders/instanciedgrassshadow.vert b/data/shaders/instanciedgrassshadow.vert index d27f2e808..1a88fbf6a 100644 --- a/data/shaders/instanciedgrassshadow.vert +++ b/data/shaders/instanciedgrassshadow.vert @@ -7,6 +7,10 @@ layout(location = 3) in vec2 Texcoord; layout(location = 7) in vec3 Origin; layout(location = 8) in vec3 Orientation; layout(location = 9) in vec3 Scale; +#ifdef GL_ARB_bindless_texture +layout(location = 10) in sampler2D Handle; +#endif + #else in vec3 Position; in vec4 Color; @@ -19,9 +23,15 @@ in vec3 Scale; #ifdef VSLayer out vec2 uv; +#ifdef GL_ARB_bindless_texture +flat out sampler2D handle; +#endif #else out vec2 tc; out int layerId; +#ifdef GL_ARB_bindless_texture +flat out sampler2D hdle; +#endif #endif mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); @@ -34,9 +44,15 @@ void main(void) gl_Layer = gl_InstanceID & 3; gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position + windDir * Color.r, 1.); uv = Texcoord; +#ifdef GL_ARB_bindless_texture + handle = Handle; +#endif #else layerId = gl_InstanceID & 3; gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position + windDir * Color.r, 1.); tc = Texcoord; +#ifdef GL_ARB_bindless_texture + hdle = Handle; +#endif #endif } \ No newline at end of file diff --git a/data/shaders/instanciedshadow.vert b/data/shaders/instanciedshadow.vert index a9f5fc34d..0bfc9426b 100644 --- a/data/shaders/instanciedshadow.vert +++ b/data/shaders/instanciedshadow.vert @@ -5,6 +5,10 @@ layout(location = 3) in vec2 Texcoord; layout(location = 7) in vec3 Origin; layout(location = 8) in vec3 Orientation; layout(location = 9) in vec3 Scale; +#ifdef GL_ARB_bindless_texture +layout(location = 10) in sampler2D Handle; +#endif + #else in vec3 Position; in vec2 Texcoord; @@ -16,9 +20,15 @@ in vec3 Scale; #ifdef VSLayer out vec2 uv; +#ifdef GL_ARB_bindless_texture +flat out sampler2D handle; +#endif #else out vec2 tc; out int layerId; +#ifdef GL_ARB_bindless_texture +flat out sampler2D hdle; +#endif #endif mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); @@ -31,9 +41,15 @@ void main(void) gl_Layer = gl_InstanceID & 3; gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.); uv = Texcoord; +#ifdef GL_ARB_bindless_texture + handle = Handle; +#endif #else layerId = gl_InstanceID & 3; gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.); tc = Texcoord; +#ifdef GL_ARB_bindless_texture + hdle = Handle; +#endif #endif } \ No newline at end of file diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 3baa27d22..219e2f558 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -745,6 +745,12 @@ void VAOManager::regenerateInstancedVAO() glEnableVertexAttribArray(9); glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float))); glVertexAttribDivisor(9, 1); + glEnableVertexAttribArray(10); + glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float))); + glVertexAttribDivisor(10, 1); + glEnableVertexAttribArray(11); + glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned))); + glVertexAttribDivisor(11, 1); InstanceVAO[std::pair(tp, (InstanceType) j)] = vao; GLuint shadow_vao = createVAO(vbo[tp], ibo[tp], tp); @@ -759,6 +765,12 @@ void VAOManager::regenerateInstancedVAO() glEnableVertexAttribArray(9); glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float))); glVertexAttribDivisor(9, 4); + glEnableVertexAttribArray(10); + glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float))); + glVertexAttribDivisor(10, 4); + glEnableVertexAttribArray(11); + glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)+2 * sizeof(unsigned))); + glVertexAttribDivisor(11, 1); ShadowInstanceVAO[std::pair(tp, (InstanceType)j)] = shadow_vao; glBindVertexArray(0); } diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index c775bcebe..6d45bbba5 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -166,6 +166,7 @@ struct InstanceData float Z; } Scale; uint64_t Texture; + uint64_t SecondTexture; }; class VAOManager : public Singleton diff --git a/src/graphics/render_geometry.cpp b/src/graphics/render_geometry.cpp index 1b3d01acb..20e6e4620 100644 --- a/src/graphics/render_geometry.cpp +++ b/src/graphics/render_geometry.cpp @@ -201,7 +201,6 @@ void renderInstancedMeshes1stPass(const std::vector &TexUnits, std::vec glUseProgram(Shader::getInstance()->Program); for (unsigned i = 0; i < meshes->size(); i++) { - std::vector Handles; std::vector Textures; GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i))); #ifdef DEBUG @@ -210,28 +209,17 @@ void renderInstancedMeshes1stPass(const std::vector &TexUnits, std::vec #endif if (!irr_driver->hasARB_base_instance()) glBindVertexArray(mesh.vao); - for (unsigned j = 0; j < TexUnits.size(); j++) + if (!UserConfigParams::m_bindless_textures) { - if (!mesh.textures[TexUnits[j].m_id]) - mesh.textures[j] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); - compressTexture(mesh.textures[TexUnits[j].m_id], TexUnits[j].m_premul_alpha); - if (UserConfigParams::m_bindless_textures) + for (unsigned j = 0; j < TexUnits.size(); j++) { -#ifdef Bindless_Texture_Support - if (!mesh.TextureHandles[TexUnits[j].m_id]) - mesh.TextureHandles[TexUnits[j].m_id] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[TexUnits[j].m_id]), Shader::getInstance()->SamplersId[j]); - if (!glIsTextureHandleResidentARB(mesh.TextureHandles[TexUnits[j].m_id])) - glMakeTextureHandleResidentARB(mesh.TextureHandles[TexUnits[j].m_id]); -#endif - Handles.push_back(mesh.TextureHandles[TexUnits[j].m_id]); - } - else + if (!mesh.textures[TexUnits[j].m_id]) + mesh.textures[j] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); + compressTexture(mesh.textures[TexUnits[j].m_id], TexUnits[j].m_premul_alpha); Textures.push_back(getTextureGLuint(mesh.textures[TexUnits[j].m_id])); - } - if (UserConfigParams::m_bindless_textures) - Shader::getInstance()->SetTextureHandles(Handles); - else + } Shader::getInstance()->SetTextureUnits(Textures); + } instanced_custom_unroll_args::template exec(Shader::getInstance(), meshes->at(i)); } } @@ -363,16 +351,6 @@ void renderMeshes2ndPass(const std::vector &TexUnits, std::vectorgetLightViz()) - { - GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ALPHA }; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } - else - { - GLint swizzleMask[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - }*/ } if (mesh.VAOType != VertexType) @@ -402,40 +380,25 @@ void renderInstancedMeshes2ndPass(const std::vector &TexUnits, std::vec if (!irr_driver->hasARB_base_instance()) glBindVertexArray(mesh.vao); - std::vector Textures(Prefilled_tex); - std::vector Handles(Prefilled_Handles); - - for (unsigned j = 0; j < TexUnits.size(); j++) - { - if (!mesh.textures[TexUnits[j].m_id]) - mesh.textures[TexUnits[j].m_id] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); - compressTexture(mesh.textures[TexUnits[j].m_id], TexUnits[j].m_premul_alpha); -#ifdef Bindless_Texture_Support - if (!mesh.TextureHandles[TexUnits[j].m_id]) - mesh.TextureHandles[TexUnits[j].m_id] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[TexUnits[j].m_id]), Shader::getInstance()->SamplersId[Handles.size()]); - if (!glIsTextureHandleResidentARB(mesh.TextureHandles[TexUnits[j].m_id])) - glMakeTextureHandleResidentARB(mesh.TextureHandles[TexUnits[j].m_id]); -#endif - if (UserConfigParams::m_bindless_textures) - Handles.push_back(mesh.TextureHandles[TexUnits[j].m_id]); - else - Textures.push_back(getTextureGLuint(mesh.textures[TexUnits[j].m_id])); -/* if (irr_driver->getLightViz()) - { - GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ALPHA }; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } - else - { - GLint swizzleMask[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - }*/ - } - if (UserConfigParams::m_bindless_textures) + { + std::vector Handles(Prefilled_Handles); + for (unsigned i = 0; i < TexUnits.size(); i++) + Handles.push_back(0); Shader::getInstance()->SetTextureHandles(Handles); + } else - Shader::getInstance()->SetTextureUnits(Textures); + { + std::vector Textures(Prefilled_tex); + for (unsigned j = 0; j < TexUnits.size(); j++) + { + if (!mesh.textures[TexUnits[j].m_id]) + mesh.textures[TexUnits[j].m_id] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); + compressTexture(mesh.textures[TexUnits[j].m_id], TexUnits[j].m_premul_alpha); + Textures.push_back(getTextureGLuint(mesh.textures[TexUnits[j].m_id])); + Shader::getInstance()->SetTextureUnits(Textures); + } + } instanced_custom_unroll_args::template exec(Shader::getInstance(), meshes->at(i)); } @@ -841,26 +804,15 @@ void renderInstancedShadow(const std::vector TextureUnits, const std::ve GLMesh *mesh = STK::tuple_get<0>(t->at(i)); if (!irr_driver->hasARB_base_instance()) glBindVertexArray(mesh->vao_shadow_pass); - for (unsigned j = 0; j < TextureUnits.size(); j++) + if (!UserConfigParams::m_bindless_textures) { - compressTexture(mesh->textures[TextureUnits[j]], true); - if (UserConfigParams::m_bindless_textures) + for (unsigned j = 0; j < TextureUnits.size(); j++) { -#ifdef Bindless_Texture_Support - if (!mesh->TextureHandles[TextureUnits[j]]) - mesh->TextureHandles[TextureUnits[j]] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh->textures[TextureUnits[j]]), T::getInstance()->SamplersId[j]); - if (!glIsTextureHandleResidentARB(mesh->TextureHandles[TextureUnits[j]])) - glMakeTextureHandleResidentARB(mesh->TextureHandles[TextureUnits[j]]); -#endif - Handles.push_back(mesh->TextureHandles[TextureUnits[j]]); - } - else + compressTexture(mesh->textures[TextureUnits[j]], true); Textures.push_back(getTextureGLuint(mesh->textures[TextureUnits[j]])); + T::getInstance()->SetTextureUnits(Textures); + } } - if (UserConfigParams::m_bindless_textures) - T::getInstance()->SetTextureHandles(Handles); - else - T::getInstance()->SetTextureUnits(Textures); instanced_shadow_custom_unroll_args::template exec(T::getInstance(), t->at(i)); } } diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index dc357c07f..968642db9 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -818,7 +818,7 @@ namespace MeshShader GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass1.frag").c_str()); + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_object_pass1.frag").c_str()); AssignUniforms(); AssignSamplerNames(Program, 0, "tex"); @@ -833,7 +833,7 @@ namespace MeshShader GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass1.frag").c_str()); + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_objectref_pass1.frag").c_str()); AssignUniforms(); AssignSamplerNames(Program, 0, "tex"); @@ -848,7 +848,7 @@ namespace MeshShader GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_grass.vert").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass1.frag").c_str()); + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_objectref_pass1.frag").c_str()); AssignUniforms("windDir"); AssignSamplerNames(Program, 0, "tex"); @@ -863,7 +863,7 @@ namespace MeshShader GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/normalmap.frag").c_str()); + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_normalmap.frag").c_str()); AssignUniforms(); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); @@ -893,7 +893,7 @@ namespace MeshShader GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass2.frag").c_str()); + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_object_pass2.frag").c_str()); AssignUniforms(); AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo"); @@ -909,7 +909,7 @@ namespace MeshShader GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass2.frag").c_str()); + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_objectref_pass2.frag").c_str()); AssignUniforms(); AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo"); @@ -975,7 +975,7 @@ namespace MeshShader GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_grass.vert").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/grass_pass2.frag").c_str()); + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_grass_pass2.frag").c_str()); AssignUniforms("windDir", "SunDir"); AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "dtex", 4, "Albedo"); @@ -1158,7 +1158,7 @@ namespace MeshShader Program = LoadProgram( GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(), - GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), + GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/instanced_shadow.geom").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str()); } GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); @@ -1200,15 +1200,15 @@ namespace MeshShader Program = LoadProgram( GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_shadowref.frag").c_str()); } else { Program = LoadProgram( GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(), - GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); + GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/instanced_shadow.geom").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_shadowref.frag").c_str()); } AssignSamplerNames(Program, 0, "tex"); @@ -1251,15 +1251,15 @@ namespace MeshShader Program = LoadProgram( GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedgrassshadow.vert").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_shadowref.frag").c_str()); } else { Program = LoadProgram( GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedgrassshadow.vert").c_str(), - GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); + GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/instanced_shadow.geom").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_shadowref.frag").c_str()); } AssignSamplerNames(Program, 0, "tex"); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 33ae728f9..ce4481cb9 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -439,10 +439,12 @@ public: void SetTextureHandles(const std::vector &args) { + assert(args.size() == TextureLocation.size() && "Wrong Handle count"); for (unsigned i = 0; i < args.size(); i++) { #ifdef Bindless_Texture_Support - glUniformHandleui64ARB(TextureLocation[i], args[i]); + if (args[i]) + glUniformHandleui64ARB(TextureLocation[i], args[i]); #endif } } diff --git a/src/graphics/stkinstancedscenenode.cpp b/src/graphics/stkinstancedscenenode.cpp index f12e27be7..ff0c7384a 100644 --- a/src/graphics/stkinstancedscenenode.cpp +++ b/src/graphics/stkinstancedscenenode.cpp @@ -57,6 +57,7 @@ void STKInstancedSceneNode::createGLMeshes() mesh.vaoBaseVertex = p.first; mesh.vaoOffset = p.second; mesh.VAOType = mb->getVertexType(); + instanceData.push_back(std::vector()); } else fillLocalBuffer(mesh, mb); @@ -66,9 +67,7 @@ void STKInstancedSceneNode::createGLMeshes() void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh) { - if (irr_driver->hasARB_base_instance()) - mesh.vaoBaseInstance = VAOManager::getInstance()->appendInstance(InstanceTypeDefault, instanceData); - else + if (!irr_driver->hasARB_base_instance()) { mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride)); glGenBuffers(1, &instances_vbo); @@ -115,6 +114,7 @@ void STKInstancedSceneNode::setFirstTimeMaterial() GLMesh &mesh = GLmeshes[i]; MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType()); initinstancedvaostate(mesh); + mesh.vaoBaseInstance = VAOManager::getInstance()->appendInstance(InstanceTypeDefault, instanceData[i]); MeshSolidMaterial[MatType].push_back(&mesh); } isMaterialInitialized = true; @@ -122,32 +122,53 @@ void STKInstancedSceneNode::setFirstTimeMaterial() void STKInstancedSceneNode::addInstance(const core::vector3df &origin, const core::vector3df &orientation, const core::vector3df &scale) { - InstanceData instance = { + for (unsigned i = 0; i < GLmeshes.size(); i++) + { + GLMesh &mesh = GLmeshes[i]; +#ifdef Bindless_Texture_Support + if (UserConfigParams::m_bindless_textures) { - origin.X, - origin.Y, - origin.Z - }, - { - orientation.X, - orientation.Y, - orientation.Z - }, - { - scale.X, - scale.Y, - scale.Z - }, - 0 - }; - instanceData.push_back(instance); + for (unsigned j = 0; j < 2; j++) + { + if (!mesh.textures[j]) + mesh.textures[j] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); + compressTexture(mesh.textures[j], true); + + if (!mesh.TextureHandles[j]) + mesh.TextureHandles[j] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[j]), MeshShader::InstancedNormalMapShader::getInstance()->SamplersId[j]); + if (!glIsTextureHandleResidentARB(mesh.TextureHandles[j])) + glMakeTextureHandleResidentARB(mesh.TextureHandles[j]); + } + } +#endif + InstanceData instance = { + { + origin.X, + origin.Y, + origin.Z + }, + { + orientation.X, + orientation.Y, + orientation.Z + }, + { + scale.X, + scale.Y, + scale.Z + }, + mesh.TextureHandles[0], + mesh.TextureHandles[1] + }; + instanceData[i].push_back(instance); + } } core::matrix4 STKInstancedSceneNode::getInstanceTransform(int id) { core::matrix4 mat; - const InstanceData &instance = instanceData[id]; + const InstanceData &instance = instanceData[0][id]; mat.setTranslation(core::vector3df( instance.Origin.X, instance.Origin.Y, @@ -174,17 +195,16 @@ void STKInstancedSceneNode::render() setFirstTimeMaterial(); - for(unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++) { GLMesh *mesh = MeshSolidMaterial[MAT_DEFAULT][i]; - ListInstancedMatDefault::getInstance()->push_back(STK::make_tuple(mesh, instanceData.size())); + ListInstancedMatDefault::getInstance()->push_back(STK::make_tuple(mesh, instanceData[0].size())); } for(unsigned i = 0; i < MeshSolidMaterial[MAT_ALPHA_REF].size(); i++) { GLMesh *mesh = MeshSolidMaterial[MAT_ALPHA_REF][i]; - ListInstancedMatAlphaRef::getInstance()->push_back(STK::make_tuple(mesh, instanceData.size())); + ListInstancedMatAlphaRef::getInstance()->push_back(STK::make_tuple(mesh, instanceData[0].size())); } windDir = getWind(); @@ -192,12 +212,12 @@ void STKInstancedSceneNode::render() for(unsigned i = 0; i < MeshSolidMaterial[MAT_GRASS].size(); i++) { GLMesh *mesh = MeshSolidMaterial[MAT_GRASS][i]; - ListInstancedMatGrass::getInstance()->push_back(STK::make_tuple(mesh, instanceData.size(), windDir, cb->getPosition())); + ListInstancedMatGrass::getInstance()->push_back(STK::make_tuple(mesh, instanceData[0].size(), windDir, cb->getPosition())); } for(unsigned i = 0; i < MeshSolidMaterial[MAT_NORMAL_MAP].size(); i++) { GLMesh *mesh = MeshSolidMaterial[MAT_NORMAL_MAP][i]; - ListInstancedMatNormalMap::getInstance()->push_back(STK::make_tuple(mesh, instanceData.size())); + ListInstancedMatNormalMap::getInstance()->push_back(STK::make_tuple(mesh, instanceData[0].size())); } } diff --git a/src/graphics/stkinstancedscenenode.hpp b/src/graphics/stkinstancedscenenode.hpp index 35a38d8b1..c6787a02f 100644 --- a/src/graphics/stkinstancedscenenode.hpp +++ b/src/graphics/stkinstancedscenenode.hpp @@ -22,7 +22,7 @@ protected: int m_ref_count; std::vector MeshSolidMaterial[MAT_COUNT]; std::vector GLmeshes; - std::vector instanceData; + std::vector > instanceData; core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView; GLuint instances_vbo; void createGLMeshes();