diff --git a/CMakeLists.txt b/CMakeLists.txt index 16759b88f..0c447a46d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -368,10 +368,8 @@ install(DIRECTORY ${STK_DATA_DIR} DESTINATION ${STK_INSTALL_DATA_DIR} PATTERN ". if(STK_ASSETS_DIR AND CHECK_ASSETS) install(DIRECTORY ${STK_ASSETS_DIR} DESTINATION ${STK_INSTALL_DATA_DIR}/data PATTERN ".svn" EXCLUDE PATTERN ".git" EXCLUDE) endif() -install(FILES ${PROJECT_BINARY_DIR}/supertuxkart.desktop DESTINATION share/applications) +install(FILES ${STK_DATA_DIR}/supertuxkart.desktop DESTINATION share/applications) +install(FILES data/supertuxkart_32.png DESTINATION share/icons/hicolor/32x32 RENAME supertuxkart.png) +install(FILES data/supertuxkart_128.png DESTINATION share/icons/hicolor/128x128 RENAME supertuxkart.png) install(FILES data/supertuxkart_32.png data/supertuxkart_128.png DESTINATION share/pixmaps) install(FILES data/supertuxkart.appdata DESTINATION share/appdata) - -set(PREFIX ${CMAKE_INSTALL_PREFIX}) -configure_file(data/supertuxkart_desktop.template supertuxkart.desktop) -add_dependencies(supertuxkart supertuxkart.desktop) 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/data/supertuxkart_desktop.template b/data/supertuxkart.desktop similarity index 66% rename from data/supertuxkart_desktop.template rename to data/supertuxkart.desktop index 789b21442..034f20da6 100644 --- a/data/supertuxkart_desktop.template +++ b/data/supertuxkart.desktop @@ -1,15 +1,14 @@ [Desktop Entry] Name=SuperTuxKart -Icon=@PREFIX@/share/pixmaps/supertuxkart_128.png +Icon=supertuxkart GenericName=A kart racing game GenericName[de]=Ein Kart-Rennspiel GenericName[fr]=Un jeu de karting GenericName[gl]=Xogo de carreiras con karts GenericName[pl]=Wyścigi gokartów GenericName[ro]=Un joc de curse cu carturi -Exec=@PREFIX@/@STK_INSTALL_BINARY_DIR@/supertuxkart --no-console +Exec=supertuxkart Terminal=false StartupNotify=false Type=Application -TryExec=@PREFIX@/@STK_INSTALL_BINARY_DIR@/supertuxkart Categories=Game;ArcadeGame; diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp index 096309f15..b5423ca57 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp @@ -251,12 +251,10 @@ bool CIrrDeviceLinux::restoreResolution() if (UseXRandR && CreationParams.Fullscreen && old_mode != BadRRMode) { XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display)); - if (!res) return false; XRROutputInfo* output = XRRGetOutputInfo(display, res, output_id); - if (!output || !output->crtc || output->connection == RR_Disconnected) { XRRFreeOutputInfo(output); @@ -264,10 +262,8 @@ bool CIrrDeviceLinux::restoreResolution() } XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc); - if (!crtc) { - XRRFreeCrtcInfo(crtc); XRRFreeOutputInfo(output); return false; } @@ -288,7 +284,7 @@ bool CIrrDeviceLinux::restoreResolution() } -bool CIrrDeviceLinux::switchToFullscreen() +bool CIrrDeviceLinux::changeResolution() { if (!CreationParams.Fullscreen) return true; @@ -356,22 +352,33 @@ bool CIrrDeviceLinux::switchToFullscreen() XFree(modes); } - else #endif #ifdef _IRR_LINUX_X11_RANDR_ - if (XRRQueryExtension(display, &eventbase, &errorbase)) + while (XRRQueryExtension(display, &eventbase, &errorbase)) { - XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display)); + if (output_id == BadRROutput) + break; - if (!res || output_id == BadRROutput) - { - os::Printer::log("Could not get video output. Try to run in windowed mode.", ELL_WARNING); - CreationParams.Fullscreen = false; - return CreationParams.Fullscreen; - } + XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display)); + if (!res) + break; XRROutputInfo* output = XRRGetOutputInfo(display, res, output_id); + if (!output || !output->crtc || output->connection == RR_Disconnected) + { + XRRFreeOutputInfo(output); + XRRFreeScreenResources(res); + break; + } + XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc); + if (!crtc) + { + XRRFreeOutputInfo(output); + XRRFreeScreenResources(res); + break; + } + float refresh_rate, refresh_rate_new; core::dimension2d mode0_size = core::dimension2d(0, 0); @@ -436,26 +443,22 @@ bool CIrrDeviceLinux::switchToFullscreen() Status s = XRRSetCrtcConfig(display, res, output->crtc, CurrentTime, crtc->x, crtc->y, output->modes[bestMode], crtc->rotation, &output_id, 1); + + if (s == Success) + UseXRandR = true; XRRFreeCrtcInfo(crtc); XRRFreeOutputInfo(output); XRRFreeScreenResources(res); - - if (s != Success) - { - CreationParams.Fullscreen = false; - return CreationParams.Fullscreen; - } - - UseXRandR=true; + break; } - else - #endif + + if (UseXRandR == false) { - os::Printer::log("VidMode or RandR extension must be installed to allow Irrlicht " - "to switch to fullscreen mode. Running in windowed mode instead.", ELL_WARNING); + os::Printer::log("Could not get video output. Try to run in windowed mode.", ELL_WARNING); CreationParams.Fullscreen = false; } + #endif return CreationParams.Fullscreen; } @@ -570,7 +573,7 @@ bool CIrrDeviceLinux::createWindow() screennr = DefaultScreen(display); - switchToFullscreen(); + changeResolution(); #ifdef _IRR_COMPILE_WITH_OPENGL_ @@ -1625,7 +1628,6 @@ video::IVideoModeList* CIrrDeviceLinux::getVideoModeList() crtc_x = crtc_y = -1; XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display)); - if (!res) break; @@ -1633,49 +1635,39 @@ video::IVideoModeList* CIrrDeviceLinux::getVideoModeList() for (int i = 0; i < res->noutput; i++) { - output = XRRGetOutputInfo(display, res, res->outputs[i]); - - if (!output || !output->crtc || output->connection == RR_Disconnected) + XRROutputInfo* output_tmp = XRRGetOutputInfo(display, res, res->outputs[i]); + if (!output_tmp || !output_tmp->crtc || output_tmp->connection == RR_Disconnected) { - XRRFreeOutputInfo(output); + XRRFreeOutputInfo(output_tmp); continue; } - crtc = XRRGetCrtcInfo(display, res, output->crtc); - - if (!crtc) + XRRCrtcInfo* crtc_tmp = XRRGetCrtcInfo(display, res, output_tmp->crtc); + if (!crtc_tmp) + { + XRRFreeOutputInfo(output_tmp); + continue; + } + + if (res->outputs[i] == primary_id || + output_id == BadRROutput || crtc_tmp->x < crtc->x || + (crtc_tmp->x == crtc->x && crtc_tmp->y < crtc->y)) { XRRFreeCrtcInfo(crtc); - XRRFreeOutputInfo(output); - continue; + XRRFreeOutputInfo(output); + + output = output_tmp; + crtc = crtc_tmp; + output_id = res->outputs[i]; + } + else + { + XRRFreeCrtcInfo(crtc_tmp); + XRRFreeOutputInfo(output_tmp); } if (res->outputs[i] == primary_id) - { - crtc_x = crtc->x; - crtc_y = crtc->y; - output_id = res->outputs[i]; - - XRRFreeCrtcInfo(crtc); - XRRFreeOutputInfo(output); break; - } - - if (crtc_x == -1 || crtc->x < crtc_x) - { - crtc_x = crtc->x; - crtc_y = crtc->y; - output_id = res->outputs[i]; - } - else if (crtc_x == crtc->x && crtc->y < crtc_y) - { - crtc_x = crtc->x; - crtc_y = crtc->y; - output_id = res->outputs[i]; - } - - XRRFreeCrtcInfo(crtc); - XRRFreeOutputInfo(output); } if (output_id == BadRROutput) @@ -1683,9 +1675,9 @@ video::IVideoModeList* CIrrDeviceLinux::getVideoModeList() os::Printer::log("Could not get video output.", ELL_WARNING); break; } - - output = XRRGetOutputInfo(display, res, output_id); - crtc = XRRGetCrtcInfo(display, res, output->crtc); + + crtc_x = crtc->x; + crtc_y = crtc->y; for (int i = 0; i < res->nmode; i++) { @@ -1719,8 +1711,7 @@ video::IVideoModeList* CIrrDeviceLinux::getVideoModeList() XRRFreeCrtcInfo(crtc); XRRFreeOutputInfo(output); - XRRFreeScreenResources(res); - + XRRFreeScreenResources(res); break; } #endif diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h index d2fd06899..c808b8ebd 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h @@ -151,7 +151,7 @@ namespace irr void initXAtoms(); bool restoreResolution(); - bool switchToFullscreen(); + bool changeResolution(); //! Implementation of the linux cursor control class CCursorControl : public gui::ICursorControl diff --git a/src/graphics/gl_headers.hpp b/src/graphics/gl_headers.hpp index 81789ddf2..91c314ef2 100644 --- a/src/graphics/gl_headers.hpp +++ b/src/graphics/gl_headers.hpp @@ -128,6 +128,7 @@ extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB; #ifdef WIN32 #define Bindless_Texture_Support +#define Base_Instance_Support #endif #endif \ No newline at end of file diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index c8b44bd5c..031b08ef4 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -4,6 +4,7 @@ #include "config/user_config.hpp" #include "utils/profiler.hpp" #include "utils/cpp2011.hpp" +#include "graphics/stkmesh.hpp" #ifdef _IRR_WINDOWS_API_ #define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast(X)) @@ -107,7 +108,7 @@ PFNGLVERTEXATTRIBLPOINTERPROC glVertexAttribLPointer; static bool is_gl_init = false; #ifdef DEBUG -#ifdef WIN32 +#if !defined(__APPLE__) #define ARB_DEBUG_OUTPUT #endif #endif @@ -592,10 +593,33 @@ VAOManager::VAOManager() idx_cnt[0] = idx_cnt[1] = idx_cnt[2] = 0; vtx_mirror[0] = vtx_mirror[1] = vtx_mirror[2] = NULL; idx_mirror[0] = idx_mirror[1] = idx_mirror[2] = NULL; + instance_count[0] = 0; + + glGenBuffers(1, &instance_vbo[0]); + glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[0]); + glBufferData(GL_ARRAY_BUFFER, 10000 * sizeof(float)* 9, 0, GL_STATIC_DRAW); +} + +static void cleanVAOMap(std::map, GLuint> Map) +{ + std::map, GLuint>::iterator It = Map.begin(), E = Map.end(); + for (; It != E; It++) + { + glDeleteVertexArrays(1, &(It->second)); + } +} + +void VAOManager::cleanInstanceVAOs() +{ + cleanVAOMap(InstanceVAO); + cleanVAOMap(ShadowInstanceVAO); + InstanceVAO.clear(); + ShadowInstanceVAO.clear(); } VAOManager::~VAOManager() { + cleanInstanceVAOs(); for (unsigned i = 0; i < 3; i++) { if (vtx_mirror[i]) @@ -609,7 +633,7 @@ VAOManager::~VAOManager() if (vao[i]) glDeleteVertexArrays(1, &vao[i]); } - + glDeleteBuffers(1, &instance_vbo[0]); } void VAOManager::regenerateBuffer(enum VTXTYPE tp) @@ -697,6 +721,65 @@ void VAOManager::regenerateVAO(enum VTXTYPE tp) glBindVertexArray(0); } +void VAOManager::regenerateInstancedVAO() +{ + cleanInstanceVAOs(); + + enum video::E_VERTEX_TYPE IrrVT[] = { video::EVT_STANDARD, video::EVT_2TCOORDS, video::EVT_TANGENTS }; + for (unsigned i = 0; i < VTXTYPE_COUNT; i++) + { + for (unsigned j = 0; j < InstanceTypeCount; j++) + { + video::E_VERTEX_TYPE tp = IrrVT[i]; + if (!vbo[tp] || !ibo[tp]) + continue; + GLuint vao = createVAO(vbo[tp], ibo[tp], tp); + glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[j]); + + glEnableVertexAttribArray(7); + glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0); + glVertexAttribDivisor(7, 1); + glEnableVertexAttribArray(8); + glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float))); + glVertexAttribDivisor(8, 1); + 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); + glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[j]); + + glEnableVertexAttribArray(7); + glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0); + glVertexAttribDivisor(7, 4); + glEnableVertexAttribArray(8); + glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float))); + glVertexAttribDivisor(8, 4); + 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); + } + } + + + +} + size_t VAOManager::getVertexPitch(enum VTXTYPE tp) const { switch (tp) @@ -756,6 +839,7 @@ std::pair VAOManager::getBase(scene::IMeshBuffer *mb) append(mb, tp); regenerateBuffer(tp); regenerateVAO(tp); + regenerateInstancedVAO(); } std::map::iterator It; @@ -767,6 +851,15 @@ std::pair VAOManager::getBase(scene::IMeshBuffer *mb) return std::pair(vtx, It->second); } +size_t VAOManager::appendInstance(enum InstanceType, const std::vector &instance_data) +{ + glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[0]); + glBufferSubData(GL_ARRAY_BUFFER, instance_count[0] * sizeof(InstanceData), instance_data.size() * sizeof(InstanceData), instance_data.data()); + size_t result = instance_count[0]; + instance_count[0] += instance_data.size(); + return result; +} + ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer) { if (!UserConfigParams::m_profiler_enabled) return; diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index 034af4090..62f192864 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -139,25 +139,71 @@ void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = f bool loadCompressedTexture(const std::string& compressed_tex); void saveCompressedTexture(const std::string& compressed_tex); +enum InstanceType +{ + InstanceTypeDefault, + InstanceTypeCount, +}; + +#ifdef WIN32 +#pragma pack(push, 1) +#endif +struct InstanceData +{ + struct + { + float X; + float Y; + float Z; + } Origin; + struct + { + float X; + float Y; + float Z; + } Orientation; + struct + { + float X; + float Y; + float Z; + } Scale; + uint64_t Texture; + uint64_t SecondTexture; +#ifdef WIN32 +}; +#pragma pack(pop) +#else +} __attribute__((packed)); +#endif + class VAOManager : public Singleton { enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT }; GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT]; + GLuint instance_vbo[1]; + size_t instance_count[1]; std::vector storedCPUBuffer[VTXTYPE_COUNT]; void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT]; size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT]; std::map mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT]; + std::map, GLuint> InstanceVAO, ShadowInstanceVAO; + void cleanInstanceVAOs(); void regenerateBuffer(enum VTXTYPE); void regenerateVAO(enum VTXTYPE); + void regenerateInstancedVAO(); size_t getVertexPitch(enum VTXTYPE) const; VTXTYPE getVTXTYPE(video::E_VERTEX_TYPE type); void append(scene::IMeshBuffer *, VTXTYPE tp); public: VAOManager(); std::pair getBase(scene::IMeshBuffer *); + size_t appendInstance(enum InstanceType, const std::vector &instance_data); unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; } unsigned getVAO(video::E_VERTEX_TYPE type) { return vao[getVTXTYPE(type)]; } + unsigned getInstanceVAO(video::E_VERTEX_TYPE vt, enum InstanceType it) { return InstanceVAO[std::pair(vt, it)]; } + unsigned getShadowInstanceVAO(video::E_VERTEX_TYPE vt, enum InstanceType it) { return ShadowInstanceVAO[std::pair(vt, it)]; } ~VAOManager(); }; diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 66eaabe21..b40d279d5 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -483,12 +483,20 @@ void IrrDriver::initDevice() // Parse extensions hasVSLayer = false; + hasBaseInstance = false; // Default false value for hasVSLayer if --no-graphics argument is used if (!ProfileWorld::isNoGraphics()) { if (hasGLExtension("GL_AMD_vertex_shader_layer")) { hasVSLayer = true; + Log::info("GLDriver", "AMD Vertex Shader Layer enabled"); } +#ifdef Base_Instance_Support + if (hasGLExtension("GL_ARB_base_instance")) { + hasBaseInstance = true; + Log::info("GLDriver", "ARB Instance enabled"); + } +#endif } diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 86ca6490e..dec484903 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -199,6 +199,7 @@ class IrrDriver : public IEventReceiver, public NoCopy private: int GLMajorVersion, GLMinorVersion; bool hasVSLayer; + bool hasBaseInstance; bool m_need_ubo_workaround; bool m_need_rh_workaround; /** The irrlicht device. */ @@ -293,6 +294,11 @@ public: return m_need_rh_workaround; } + bool hasARB_base_instance() const + { + return hasBaseInstance; + } + bool hasVSLayerExtension() const { return hasVSLayer; diff --git a/src/graphics/render_geometry.cpp b/src/graphics/render_geometry.cpp index ae9d00c1d..20e6e4620 100644 --- a/src/graphics/render_geometry.cpp +++ b/src/graphics/render_geometry.cpp @@ -176,7 +176,12 @@ struct instanced_custom_unroll_args<> size_t count = mesh->IndexCount; Shader->setUniforms(args...); - glDrawElementsInstanced(ptype, count, itype, 0, instance_count); +#ifdef Base_Instance_Support + if (irr_driver->hasARB_base_instance()) + glDrawElementsInstancedBaseVertexBaseInstance(ptype, count, itype, (const void*)mesh->vaoOffset, instance_count, mesh->vaoBaseVertex, mesh->vaoBaseInstance); + else +#endif + glDrawElementsInstanced(ptype, count, itype, 0, instance_count); } }; @@ -196,36 +201,25 @@ 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 if (mesh.VAOType != VertexType) Log::error("RenderGeometry", "Wrong instanced vertex format"); #endif - glBindVertexArray(mesh.vao); - for (unsigned j = 0; j < TexUnits.size(); j++) + if (!irr_driver->hasARB_base_instance()) + glBindVertexArray(mesh.vao); + 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)); } } @@ -306,15 +300,23 @@ void IrrDriver::renderSolidFirstPass() renderMeshes1stPass(TexUnits(TexUnit(0, true)), AnimatedListMatDetails::getInstance()); renderMeshes1stPass(TexUnits(TexUnit(0, true)), AnimatedListMatUnlit::getInstance()); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault)); renderInstancedMeshes1stPass( TexUnits(TexUnit(0, true)), ListInstancedMatDefault::getInstance()); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault)); renderInstancedMeshes1stPass( TexUnits(TexUnit(0, true)), ListInstancedMatAlphaRef::getInstance()); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault)); renderInstancedMeshes1stPass( TexUnits(TexUnit(0, true)), ListInstancedMatGrass::getInstance()); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_TANGENTS, InstanceTypeDefault)); renderInstancedMeshes1stPass( TexUnits(TexUnit(1, false), TexUnit(0, true)), ListInstancedMatNormalMap::getInstance()); @@ -349,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) @@ -385,42 +377,28 @@ void renderInstancedMeshes2ndPass(const std::vector &TexUnits, std::vec for (unsigned i = 0; i < meshes->size(); i++) { GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i))); - 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 (!irr_driver->hasARB_base_instance()) + glBindVertexArray(mesh.vao); 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)); } @@ -529,15 +507,23 @@ void IrrDriver::renderSolidSecondPass() TexUnit(0, true) ), ListMatNormalMap::getInstance(), createVector(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault)); renderInstancedMeshes2ndPass( TexUnits(TexUnit(0, true)), ListInstancedMatDefault::getInstance(), createVector(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_TANGENTS, InstanceTypeDefault)); renderInstancedMeshes2ndPass( TexUnits(TexUnit(0, true)), ListInstancedMatNormalMap::getInstance(), createVector(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault)); renderInstancedMeshes2ndPass( TexUnits(TexUnit(0, true)), ListInstancedMatAlphaRef::getInstance(), createVector(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault)); DiffSpecSSAOTex.push_back(irr_driver->getDepthStencilTexture()); renderInstancedMeshes2ndPass( TexUnits(TexUnit(0, true)), @@ -788,7 +774,12 @@ struct instanced_shadow_custom_unroll_args<> size_t count = mesh->IndexCount; Shader->setUniforms(args...); - glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count); +#ifdef Base_Instance_Support + if (irr_driver->hasARB_base_instance()) + glDrawElementsInstancedBaseVertexBaseInstance(ptype, count, itype, (const void*) mesh->vaoOffset, 4 * instance_count, mesh->vaoBaseVertex, mesh->vaoBaseInstance); + else +#endif + glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count); } }; @@ -811,27 +802,17 @@ void renderInstancedShadow(const std::vector TextureUnits, const std::ve std::vector Handles; std::vector Textures; GLMesh *mesh = STK::tuple_get<0>(t->at(i)); - glBindVertexArray(mesh->vao_shadow_pass); - for (unsigned j = 0; j < TextureUnits.size(); j++) + if (!irr_driver->hasARB_base_instance()) + glBindVertexArray(mesh->vao_shadow_pass); + 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)); } } @@ -883,9 +864,17 @@ void IrrDriver::renderShadows() renderShadow(std::vector{ 0 }, AnimatedListMatUnlit::getInstance()); renderShadow(noTexUnits, AnimatedListMatDetails::getInstance()); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getShadowInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault)); renderInstancedShadow(noTexUnits, ListInstancedMatDefault::getInstance()); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getShadowInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault)); renderInstancedShadow(std::vector{ 0 }, ListInstancedMatAlphaRef::getInstance()); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getShadowInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault)); renderInstancedShadow(std::vector{ 0 }, ListInstancedMatGrass::getInstance()); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getShadowInstanceVAO(video::EVT_TANGENTS, InstanceTypeDefault)); renderInstancedShadow(noTexUnits, ListInstancedMatNormalMap::getInstance()); glDisable(GL_POLYGON_OFFSET_FILL); 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 64c28206f..3b7b8e225 100644 --- a/src/graphics/stkinstancedscenenode.cpp +++ b/src/graphics/stkinstancedscenenode.cpp @@ -50,41 +50,54 @@ void STKInstancedSceneNode::createGLMeshes() { scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); GLmeshes.push_back(allocateMeshBuffer(mb)); - fillLocalBuffer(GLmeshes.back(), mb); + GLMesh &mesh = GLmeshes.back(); + if (irr_driver->hasARB_base_instance()) + { + std::pair p = VAOManager::getInstance()->getBase(mb); + mesh.vaoBaseVertex = p.first; + mesh.vaoOffset = p.second; + mesh.VAOType = mb->getVertexType(); + } + else + fillLocalBuffer(mesh, mb); + instanceData.push_back(std::vector()); } isMaterialInitialized = false; } -void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh) +void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, const std::vector &instances) { - mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride)); - glGenBuffers(1, &instances_vbo); - glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); - glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); + if (!irr_driver->hasARB_base_instance()) + { + mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride)); + glGenBuffers(1, &instances_vbo); + glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); + glBufferData(GL_ARRAY_BUFFER, instances.size() * sizeof(InstanceData), instances.data(), GL_STATIC_DRAW); - glEnableVertexAttribArray(7); - glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0); - glVertexAttribDivisor(7, 1); - glEnableVertexAttribArray(8); - glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float))); - glVertexAttribDivisor(8, 1); - glEnableVertexAttribArray(9); - glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float))); - glVertexAttribDivisor(9, 1); + glEnableVertexAttribArray(7); + glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0); + glVertexAttribDivisor(7, 1); + glEnableVertexAttribArray(8); + glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float))); + glVertexAttribDivisor(8, 1); + glEnableVertexAttribArray(9); + glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float))); + glVertexAttribDivisor(9, 1); - mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride)); - glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); - glEnableVertexAttribArray(7); - glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0); - glVertexAttribDivisor(7, 4); - glEnableVertexAttribArray(8); - glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float))); - glVertexAttribDivisor(8, 4); - glEnableVertexAttribArray(9); - glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float))); - glVertexAttribDivisor(9, 4); + mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride)); + glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); + glEnableVertexAttribArray(7); + glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0); + glVertexAttribDivisor(7, 4); + glEnableVertexAttribArray(8); + glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float))); + glVertexAttribDivisor(8, 4); + glEnableVertexAttribArray(9); + glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float))); + glVertexAttribDivisor(9, 4); - glBindVertexArray(0); + glBindVertexArray(0); + } } void STKInstancedSceneNode::setFirstTimeMaterial() @@ -100,7 +113,9 @@ void STKInstancedSceneNode::setFirstTimeMaterial() GLMesh &mesh = GLmeshes[i]; MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType()); - initinstancedvaostate(mesh); + initinstancedvaostate(mesh, instanceData[i]); + if (irr_driver->hasARB_base_instance()) + mesh.vaoBaseInstance = VAOManager::getInstance()->appendInstance(InstanceTypeDefault, instanceData[i]); MeshSolidMaterial[MatType].push_back(&mesh); } isMaterialInitialized = true; @@ -108,34 +123,65 @@ void STKInstancedSceneNode::setFirstTimeMaterial() void STKInstancedSceneNode::addInstance(const core::vector3df &origin, const core::vector3df &orientation, const core::vector3df &scale) { - instance_pos.push_back(origin.X); - instance_pos.push_back(origin.Y); - instance_pos.push_back(origin.Z); - instance_pos.push_back(orientation.X); - instance_pos.push_back(orientation.Y); - instance_pos.push_back(orientation.Z); - instance_pos.push_back(scale.X); - instance_pos.push_back(scale.Y); - instance_pos.push_back(scale.Z); + for (unsigned i = 0; i < GLmeshes.size(); i++) + { + GLMesh &mesh = GLmeshes[i]; +#ifdef Bindless_Texture_Support + if (UserConfigParams::m_bindless_textures) + { + 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; - int offset = id * 9; + const InstanceData &instance = instanceData[0][id]; mat.setTranslation(core::vector3df( - instance_pos[offset], - instance_pos[offset + 1], - instance_pos[offset + 2])); + instance.Origin.X, + instance.Origin.Y, + instance.Origin.Z)); mat.setRotationDegrees(core::vector3df( - instance_pos[offset + 3], - instance_pos[offset + 4], - instance_pos[offset + 5])); + instance.Orientation.X, + instance.Orientation.Y, + instance.Orientation.Z)); mat.setScale(core::vector3df( - instance_pos[offset + 6], - instance_pos[offset + 7], - instance_pos[offset + 8])); + instance.Scale.X, + instance.Scale.Y, + instance.Scale.Z)); return mat; } @@ -150,30 +196,32 @@ void STKInstancedSceneNode::render() setFirstTimeMaterial(); - - for(unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++) + if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS) { - GLMesh *mesh = MeshSolidMaterial[MAT_DEFAULT][i]; - ListInstancedMatDefault::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9)); - } + 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[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, instance_pos.size() / 9)); - } + 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[0].size())); + } - windDir = getWind(); - SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT); - for(unsigned i = 0; i < MeshSolidMaterial[MAT_GRASS].size(); i++) - { - GLMesh *mesh = MeshSolidMaterial[MAT_GRASS][i]; - ListInstancedMatGrass::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9, windDir, cb->getPosition())); - } + windDir = getWind(); + SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT); + 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[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, instance_pos.size() / 9)); + 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[0].size())); + } } } diff --git a/src/graphics/stkinstancedscenenode.hpp b/src/graphics/stkinstancedscenenode.hpp index d1063ca6d..74dbc719d 100644 --- a/src/graphics/stkinstancedscenenode.hpp +++ b/src/graphics/stkinstancedscenenode.hpp @@ -22,13 +22,13 @@ protected: int m_ref_count; std::vector MeshSolidMaterial[MAT_COUNT]; std::vector GLmeshes; - std::vector instance_pos; + std::vector > instanceData; core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView; GLuint instances_vbo; void createGLMeshes(); bool isMaterialInitialized; void setFirstTimeMaterial(); - void initinstancedvaostate(GLMesh &mesh); + void initinstancedvaostate(GLMesh &mesh, const std::vector &); void cleanGL(); core::vector3df windDir; public: @@ -40,7 +40,7 @@ public: virtual void render(); void addInstance(const core::vector3df &origin, const core::vector3df &orientation, const core::vector3df &scale); - int getInstanceCount() const { return instance_pos.size() / 9; } + int getInstanceCount() const { return instanceData[0].size(); } core::matrix4 getInstanceTransform(int id); diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index dd21eb6c6..beaee62cb 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -46,6 +46,7 @@ struct GLMesh { core::matrix4 TextureMatrix; size_t vaoBaseVertex; size_t vaoOffset; + size_t vaoBaseInstance; video::E_VERTEX_TYPE VAOType; uint64_t TextureHandles[6]; }; diff --git a/src/utils/debug.cpp b/src/utils/debug.cpp index 62bbc8dd3..a6bfc6fcc 100644 --- a/src/utils/debug.cpp +++ b/src/utils/debug.cpp @@ -439,32 +439,32 @@ bool onEvent(const SEvent &event) { #if !defined(__APPLE__) DebugSliderDialog *dsd = new DebugSliderDialog(); - dsd->setSliderHook( "red_slider", 0, 255, [](){ return irr_driver->getAmbientLight().r * 255.; }, + dsd->setSliderHook( "red_slider", 0, 255, [](){ return irr_driver->getAmbientLight().r * 255.f; }, [](int v){ video::SColorf ambient = irr_driver->getAmbientLight(); - ambient.setColorComponentValue(0, v / 255.); + ambient.setColorComponentValue(0, v / 255.f); irr_driver->setAmbientLight(ambient); } ); - dsd->setSliderHook("green_slider", 0, 255, [](){ return irr_driver->getAmbientLight().g * 255.; }, + dsd->setSliderHook("green_slider", 0, 255, [](){ return irr_driver->getAmbientLight().g * 255.f; }, [](int v){ video::SColorf ambient = irr_driver->getAmbientLight(); - ambient.setColorComponentValue(1, v / 255.); + ambient.setColorComponentValue(1, v / 255.f); irr_driver->setAmbientLight(ambient); } ); - dsd->setSliderHook("blue_slider", 0, 255, [](){ return irr_driver->getAmbientLight().b * 255.; }, + dsd->setSliderHook("blue_slider", 0, 255, [](){ return irr_driver->getAmbientLight().b * 255.f; }, [](int v){ video::SColorf ambient = irr_driver->getAmbientLight(); - ambient.setColorComponentValue(2, v / 255.); + ambient.setColorComponentValue(2, v / 255.f); irr_driver->setAmbientLight(ambient); } ); - dsd->setSliderHook("ssao_radius", 0, 100, [](){ return irr_driver->getSSAORadius() * 10; }, - [](int v){irr_driver->setSSAORadius(v / 10.); } + dsd->setSliderHook("ssao_radius", 0, 100, [](){ return irr_driver->getSSAORadius() * 10.f; }, + [](int v){irr_driver->setSSAORadius(v / 10.f); } ); - dsd->setSliderHook("ssao_k", 0, 100, [](){ return irr_driver->getSSAOK() * 10; }, - [](int v){irr_driver->setSSAOK(v / 10.); } + dsd->setSliderHook("ssao_k", 0, 100, [](){ return irr_driver->getSSAOK() * 10.f; }, + [](int v){irr_driver->setSSAOK(v / 10.f); } ); - dsd->setSliderHook("ssao_sigma", 0, 100, [](){ return irr_driver->getSSAOSigma() * 10; }, - [](int v){irr_driver->setSSAOSigma(v / 10.); } + dsd->setSliderHook("ssao_sigma", 0, 100, [](){ return irr_driver->getSSAOSigma() * 10.f; }, + [](int v){irr_driver->setSSAOSigma(v / 10.f); } ); #endif }