Merge branch 'master' of github.com:supertuxkart/stk-code

This commit is contained in:
hiker 2014-08-25 10:30:12 +10:00
commit aef5b3aaea
28 changed files with 720 additions and 256 deletions

View File

@ -368,10 +368,8 @@ install(DIRECTORY ${STK_DATA_DIR} DESTINATION ${STK_INSTALL_DATA_DIR} PATTERN ".
if(STK_ASSETS_DIR AND CHECK_ASSETS) if(STK_ASSETS_DIR AND CHECK_ASSETS)
install(DIRECTORY ${STK_ASSETS_DIR} DESTINATION ${STK_INSTALL_DATA_DIR}/data PATTERN ".svn" EXCLUDE PATTERN ".git" EXCLUDE) install(DIRECTORY ${STK_ASSETS_DIR} DESTINATION ${STK_INSTALL_DATA_DIR}/data PATTERN ".svn" EXCLUDE PATTERN ".git" EXCLUDE)
endif() 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_32.png data/supertuxkart_128.png DESTINATION share/pixmaps)
install(FILES data/supertuxkart.appdata DESTINATION share/appdata) 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)

View File

@ -9,6 +9,10 @@ layout(location = 3) in vec2 Texcoord;
layout(location = 7) in vec3 Origin; layout(location = 7) in vec3 Origin;
layout(location = 8) in vec3 Orientation; layout(location = 8) in vec3 Orientation;
layout(location = 9) in vec3 Scale; layout(location = 9) in vec3 Scale;
#ifdef GL_ARB_bindless_texture
layout(location = 10) in sampler2D Handle;
#endif
#else #else
in vec3 Position; in vec3 Position;
in vec3 Normal; in vec3 Normal;
@ -22,6 +26,9 @@ in vec3 Scale;
out vec3 nor; out vec3 nor;
out vec2 uv; out vec2 uv;
#ifdef GL_ARB_bindless_texture
flat out sampler2D handle;
#endif
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
mat4 getInverseWorldMatrix(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.); gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(Position, 1.);
nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz; nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz;
uv = Texcoord; uv = Texcoord;
#ifdef GL_ARB_bindless_texture
handle = Handle;
#endif
} }

View File

@ -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.);
}

View File

@ -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.);
}

View File

@ -9,6 +9,11 @@ layout(location = 6) in vec3 Bitangent;
layout(location = 7) in vec3 Origin; layout(location = 7) in vec3 Origin;
layout(location = 8) in vec3 Orientation; layout(location = 8) in vec3 Orientation;
layout(location = 9) in vec3 Scale; 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 #else
in vec3 Position; in vec3 Position;
in vec3 Normal; in vec3 Normal;
@ -27,6 +32,10 @@ out vec3 tangent;
out vec3 bitangent; out vec3 bitangent;
out vec2 uv; out vec2 uv;
out vec4 color; 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 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
mat4 getInverseWorldMatrix(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; bitangent = (TransposeInverseModelView * vec4(Bitangent, 1.)).xyz;
uv = Texcoord; uv = Texcoord;
color = Color.zyxw; color = Color.zyxw;
#ifdef GL_ARB_bindless_texture
handle = Handle;
secondhandle = SecondHandle;
#endif
} }

View File

@ -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.);
}

View File

@ -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.);
}

View File

@ -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.;
}

View File

@ -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.);
}

View File

@ -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();
}

View File

@ -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.);
}

View File

@ -7,6 +7,10 @@ layout(location = 3) in vec2 Texcoord;
layout(location = 7) in vec3 Origin; layout(location = 7) in vec3 Origin;
layout(location = 8) in vec3 Orientation; layout(location = 8) in vec3 Orientation;
layout(location = 9) in vec3 Scale; layout(location = 9) in vec3 Scale;
#ifdef GL_ARB_bindless_texture
layout(location = 10) in sampler2D Handle;
#endif
#else #else
in vec3 Position; in vec3 Position;
in vec4 Color; in vec4 Color;
@ -19,9 +23,15 @@ in vec3 Scale;
#ifdef VSLayer #ifdef VSLayer
out vec2 uv; out vec2 uv;
#ifdef GL_ARB_bindless_texture
flat out sampler2D handle;
#endif
#else #else
out vec2 tc; out vec2 tc;
out int layerId; out int layerId;
#ifdef GL_ARB_bindless_texture
flat out sampler2D hdle;
#endif
#endif #endif
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
@ -34,9 +44,15 @@ void main(void)
gl_Layer = gl_InstanceID & 3; gl_Layer = gl_InstanceID & 3;
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position + windDir * Color.r, 1.); gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
uv = Texcoord; uv = Texcoord;
#ifdef GL_ARB_bindless_texture
handle = Handle;
#endif
#else #else
layerId = gl_InstanceID & 3; layerId = gl_InstanceID & 3;
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position + windDir * Color.r, 1.); gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
tc = Texcoord; tc = Texcoord;
#ifdef GL_ARB_bindless_texture
hdle = Handle;
#endif
#endif #endif
} }

View File

@ -5,6 +5,10 @@ layout(location = 3) in vec2 Texcoord;
layout(location = 7) in vec3 Origin; layout(location = 7) in vec3 Origin;
layout(location = 8) in vec3 Orientation; layout(location = 8) in vec3 Orientation;
layout(location = 9) in vec3 Scale; layout(location = 9) in vec3 Scale;
#ifdef GL_ARB_bindless_texture
layout(location = 10) in sampler2D Handle;
#endif
#else #else
in vec3 Position; in vec3 Position;
in vec2 Texcoord; in vec2 Texcoord;
@ -16,9 +20,15 @@ in vec3 Scale;
#ifdef VSLayer #ifdef VSLayer
out vec2 uv; out vec2 uv;
#ifdef GL_ARB_bindless_texture
flat out sampler2D handle;
#endif
#else #else
out vec2 tc; out vec2 tc;
out int layerId; out int layerId;
#ifdef GL_ARB_bindless_texture
flat out sampler2D hdle;
#endif
#endif #endif
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
@ -31,9 +41,15 @@ void main(void)
gl_Layer = gl_InstanceID & 3; gl_Layer = gl_InstanceID & 3;
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.); gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.);
uv = Texcoord; uv = Texcoord;
#ifdef GL_ARB_bindless_texture
handle = Handle;
#endif
#else #else
layerId = gl_InstanceID & 3; layerId = gl_InstanceID & 3;
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.); gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.);
tc = Texcoord; tc = Texcoord;
#ifdef GL_ARB_bindless_texture
hdle = Handle;
#endif
#endif #endif
} }

View File

@ -1,15 +1,14 @@
[Desktop Entry] [Desktop Entry]
Name=SuperTuxKart Name=SuperTuxKart
Icon=@PREFIX@/share/pixmaps/supertuxkart_128.png Icon=supertuxkart
GenericName=A kart racing game GenericName=A kart racing game
GenericName[de]=Ein Kart-Rennspiel GenericName[de]=Ein Kart-Rennspiel
GenericName[fr]=Un jeu de karting GenericName[fr]=Un jeu de karting
GenericName[gl]=Xogo de carreiras con karts GenericName[gl]=Xogo de carreiras con karts
GenericName[pl]=Wyścigi gokartów GenericName[pl]=Wyścigi gokartów
GenericName[ro]=Un joc de curse cu carturi GenericName[ro]=Un joc de curse cu carturi
Exec=@PREFIX@/@STK_INSTALL_BINARY_DIR@/supertuxkart --no-console Exec=supertuxkart
Terminal=false Terminal=false
StartupNotify=false StartupNotify=false
Type=Application Type=Application
TryExec=@PREFIX@/@STK_INSTALL_BINARY_DIR@/supertuxkart
Categories=Game;ArcadeGame; Categories=Game;ArcadeGame;

View File

@ -251,12 +251,10 @@ bool CIrrDeviceLinux::restoreResolution()
if (UseXRandR && CreationParams.Fullscreen && old_mode != BadRRMode) if (UseXRandR && CreationParams.Fullscreen && old_mode != BadRRMode)
{ {
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display)); XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
if (!res) if (!res)
return false; return false;
XRROutputInfo* output = XRRGetOutputInfo(display, res, output_id); XRROutputInfo* output = XRRGetOutputInfo(display, res, output_id);
if (!output || !output->crtc || output->connection == RR_Disconnected) if (!output || !output->crtc || output->connection == RR_Disconnected)
{ {
XRRFreeOutputInfo(output); XRRFreeOutputInfo(output);
@ -264,10 +262,8 @@ bool CIrrDeviceLinux::restoreResolution()
} }
XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc); XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc);
if (!crtc) if (!crtc)
{ {
XRRFreeCrtcInfo(crtc);
XRRFreeOutputInfo(output); XRRFreeOutputInfo(output);
return false; return false;
} }
@ -288,7 +284,7 @@ bool CIrrDeviceLinux::restoreResolution()
} }
bool CIrrDeviceLinux::switchToFullscreen() bool CIrrDeviceLinux::changeResolution()
{ {
if (!CreationParams.Fullscreen) if (!CreationParams.Fullscreen)
return true; return true;
@ -356,22 +352,33 @@ bool CIrrDeviceLinux::switchToFullscreen()
XFree(modes); XFree(modes);
} }
else
#endif #endif
#ifdef _IRR_LINUX_X11_RANDR_ #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) XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
{ if (!res)
os::Printer::log("Could not get video output. Try to run in windowed mode.", ELL_WARNING); break;
CreationParams.Fullscreen = false;
return CreationParams.Fullscreen;
}
XRROutputInfo* output = XRRGetOutputInfo(display, res, output_id); 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); XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc);
if (!crtc)
{
XRRFreeOutputInfo(output);
XRRFreeScreenResources(res);
break;
}
float refresh_rate, refresh_rate_new; float refresh_rate, refresh_rate_new;
core::dimension2d<u32> mode0_size = core::dimension2d<u32>(0, 0); core::dimension2d<u32> mode0_size = core::dimension2d<u32>(0, 0);
@ -437,25 +444,21 @@ bool CIrrDeviceLinux::switchToFullscreen()
crtc->x, crtc->y, output->modes[bestMode], crtc->x, crtc->y, output->modes[bestMode],
crtc->rotation, &output_id, 1); crtc->rotation, &output_id, 1);
if (s == Success)
UseXRandR = true;
XRRFreeCrtcInfo(crtc); XRRFreeCrtcInfo(crtc);
XRRFreeOutputInfo(output); XRRFreeOutputInfo(output);
XRRFreeScreenResources(res); XRRFreeScreenResources(res);
break;
}
if (s != Success) if (UseXRandR == false)
{ {
os::Printer::log("Could not get video output. Try to run in windowed mode.", ELL_WARNING);
CreationParams.Fullscreen = false; CreationParams.Fullscreen = false;
return CreationParams.Fullscreen;
} }
UseXRandR=true;
}
else
#endif #endif
{
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);
CreationParams.Fullscreen = false;
}
return CreationParams.Fullscreen; return CreationParams.Fullscreen;
} }
@ -570,7 +573,7 @@ bool CIrrDeviceLinux::createWindow()
screennr = DefaultScreen(display); screennr = DefaultScreen(display);
switchToFullscreen(); changeResolution();
#ifdef _IRR_COMPILE_WITH_OPENGL_ #ifdef _IRR_COMPILE_WITH_OPENGL_
@ -1625,7 +1628,6 @@ video::IVideoModeList* CIrrDeviceLinux::getVideoModeList()
crtc_x = crtc_y = -1; crtc_x = crtc_y = -1;
XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display)); XRRScreenResources* res = XRRGetScreenResources(display, DefaultRootWindow(display));
if (!res) if (!res)
break; break;
@ -1633,59 +1635,49 @@ video::IVideoModeList* CIrrDeviceLinux::getVideoModeList()
for (int i = 0; i < res->noutput; i++) for (int i = 0; i < res->noutput; i++)
{ {
output = XRRGetOutputInfo(display, res, res->outputs[i]); XRROutputInfo* output_tmp = XRRGetOutputInfo(display, res, res->outputs[i]);
if (!output_tmp || !output_tmp->crtc || output_tmp->connection == RR_Disconnected)
if (!output || !output->crtc || output->connection == RR_Disconnected)
{ {
XRRFreeOutputInfo(output); XRRFreeOutputInfo(output_tmp);
continue; continue;
} }
crtc = XRRGetCrtcInfo(display, res, output->crtc); XRRCrtcInfo* crtc_tmp = XRRGetCrtcInfo(display, res, output_tmp->crtc);
if (!crtc_tmp)
{
XRRFreeOutputInfo(output_tmp);
continue;
}
if (!crtc) 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); XRRFreeCrtcInfo(crtc);
XRRFreeOutputInfo(output); XRRFreeOutputInfo(output);
continue;
output = output_tmp;
crtc = crtc_tmp;
output_id = res->outputs[i];
}
else
{
XRRFreeCrtcInfo(crtc_tmp);
XRRFreeOutputInfo(output_tmp);
} }
if (res->outputs[i] == primary_id) if (res->outputs[i] == primary_id)
{
crtc_x = crtc->x;
crtc_y = crtc->y;
output_id = res->outputs[i];
XRRFreeCrtcInfo(crtc);
XRRFreeOutputInfo(output);
break; 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) if (output_id == BadRROutput)
{ {
os::Printer::log("Could not get video output.", ELL_WARNING); os::Printer::log("Could not get video output.", ELL_WARNING);
break; break;
} }
output = XRRGetOutputInfo(display, res, output_id); crtc_x = crtc->x;
crtc = XRRGetCrtcInfo(display, res, output->crtc); crtc_y = crtc->y;
for (int i = 0; i < res->nmode; i++) for (int i = 0; i < res->nmode; i++)
{ {
@ -1720,7 +1712,6 @@ video::IVideoModeList* CIrrDeviceLinux::getVideoModeList()
XRRFreeCrtcInfo(crtc); XRRFreeCrtcInfo(crtc);
XRRFreeOutputInfo(output); XRRFreeOutputInfo(output);
XRRFreeScreenResources(res); XRRFreeScreenResources(res);
break; break;
} }
#endif #endif

View File

@ -151,7 +151,7 @@ namespace irr
void initXAtoms(); void initXAtoms();
bool restoreResolution(); bool restoreResolution();
bool switchToFullscreen(); bool changeResolution();
//! Implementation of the linux cursor control //! Implementation of the linux cursor control
class CCursorControl : public gui::ICursorControl class CCursorControl : public gui::ICursorControl

View File

@ -128,6 +128,7 @@ extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
#ifdef WIN32 #ifdef WIN32
#define Bindless_Texture_Support #define Bindless_Texture_Support
#define Base_Instance_Support
#endif #endif
#endif #endif

View File

@ -4,6 +4,7 @@
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "utils/profiler.hpp" #include "utils/profiler.hpp"
#include "utils/cpp2011.hpp" #include "utils/cpp2011.hpp"
#include "graphics/stkmesh.hpp"
#ifdef _IRR_WINDOWS_API_ #ifdef _IRR_WINDOWS_API_
#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast<const char*>(X)) #define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast<const char*>(X))
@ -107,7 +108,7 @@ PFNGLVERTEXATTRIBLPOINTERPROC glVertexAttribLPointer;
static bool is_gl_init = false; static bool is_gl_init = false;
#ifdef DEBUG #ifdef DEBUG
#ifdef WIN32 #if !defined(__APPLE__)
#define ARB_DEBUG_OUTPUT #define ARB_DEBUG_OUTPUT
#endif #endif
#endif #endif
@ -592,10 +593,33 @@ VAOManager::VAOManager()
idx_cnt[0] = idx_cnt[1] = idx_cnt[2] = 0; idx_cnt[0] = idx_cnt[1] = idx_cnt[2] = 0;
vtx_mirror[0] = vtx_mirror[1] = vtx_mirror[2] = NULL; vtx_mirror[0] = vtx_mirror[1] = vtx_mirror[2] = NULL;
idx_mirror[0] = idx_mirror[1] = idx_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<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> Map)
{
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, 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() VAOManager::~VAOManager()
{ {
cleanInstanceVAOs();
for (unsigned i = 0; i < 3; i++) for (unsigned i = 0; i < 3; i++)
{ {
if (vtx_mirror[i]) if (vtx_mirror[i])
@ -609,7 +633,7 @@ VAOManager::~VAOManager()
if (vao[i]) if (vao[i])
glDeleteVertexArrays(1, &vao[i]); glDeleteVertexArrays(1, &vao[i]);
} }
glDeleteBuffers(1, &instance_vbo[0]);
} }
void VAOManager::regenerateBuffer(enum VTXTYPE tp) void VAOManager::regenerateBuffer(enum VTXTYPE tp)
@ -697,6 +721,65 @@ void VAOManager::regenerateVAO(enum VTXTYPE tp)
glBindVertexArray(0); 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<video::E_VERTEX_TYPE, InstanceType>(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<video::E_VERTEX_TYPE, InstanceType>(tp, (InstanceType)j)] = shadow_vao;
glBindVertexArray(0);
}
}
}
size_t VAOManager::getVertexPitch(enum VTXTYPE tp) const size_t VAOManager::getVertexPitch(enum VTXTYPE tp) const
{ {
switch (tp) switch (tp)
@ -756,6 +839,7 @@ std::pair<unsigned, unsigned> VAOManager::getBase(scene::IMeshBuffer *mb)
append(mb, tp); append(mb, tp);
regenerateBuffer(tp); regenerateBuffer(tp);
regenerateVAO(tp); regenerateVAO(tp);
regenerateInstancedVAO();
} }
std::map<scene::IMeshBuffer*, unsigned>::iterator It; std::map<scene::IMeshBuffer*, unsigned>::iterator It;
@ -767,6 +851,15 @@ std::pair<unsigned, unsigned> VAOManager::getBase(scene::IMeshBuffer *mb)
return std::pair<unsigned, unsigned>(vtx, It->second); return std::pair<unsigned, unsigned>(vtx, It->second);
} }
size_t VAOManager::appendInstance(enum InstanceType, const std::vector<InstanceData> &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) ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer)
{ {
if (!UserConfigParams::m_profiler_enabled) return; if (!UserConfigParams::m_profiler_enabled) return;

View File

@ -139,25 +139,71 @@ void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = f
bool loadCompressedTexture(const std::string& compressed_tex); bool loadCompressedTexture(const std::string& compressed_tex);
void saveCompressedTexture(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<VAOManager> class VAOManager : public Singleton<VAOManager>
{ {
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT }; enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT]; GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT];
GLuint instance_vbo[1];
size_t instance_count[1];
std::vector<scene::IMeshBuffer *> storedCPUBuffer[VTXTYPE_COUNT]; std::vector<scene::IMeshBuffer *> storedCPUBuffer[VTXTYPE_COUNT];
void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT]; void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT];
size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT]; size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT];
std::map<scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT]; std::map<scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> InstanceVAO, ShadowInstanceVAO;
void cleanInstanceVAOs();
void regenerateBuffer(enum VTXTYPE); void regenerateBuffer(enum VTXTYPE);
void regenerateVAO(enum VTXTYPE); void regenerateVAO(enum VTXTYPE);
void regenerateInstancedVAO();
size_t getVertexPitch(enum VTXTYPE) const; size_t getVertexPitch(enum VTXTYPE) const;
VTXTYPE getVTXTYPE(video::E_VERTEX_TYPE type); VTXTYPE getVTXTYPE(video::E_VERTEX_TYPE type);
void append(scene::IMeshBuffer *, VTXTYPE tp); void append(scene::IMeshBuffer *, VTXTYPE tp);
public: public:
VAOManager(); VAOManager();
std::pair<unsigned, unsigned> getBase(scene::IMeshBuffer *); std::pair<unsigned, unsigned> getBase(scene::IMeshBuffer *);
size_t appendInstance(enum InstanceType, const std::vector<InstanceData> &instance_data);
unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; } unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; }
unsigned getVAO(video::E_VERTEX_TYPE type) { return vao[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<video::E_VERTEX_TYPE, InstanceType>(vt, it)]; }
unsigned getShadowInstanceVAO(video::E_VERTEX_TYPE vt, enum InstanceType it) { return ShadowInstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(vt, it)]; }
~VAOManager(); ~VAOManager();
}; };

View File

@ -483,12 +483,20 @@ void IrrDriver::initDevice()
// Parse extensions // Parse extensions
hasVSLayer = false; hasVSLayer = false;
hasBaseInstance = false;
// Default false value for hasVSLayer if --no-graphics argument is used // Default false value for hasVSLayer if --no-graphics argument is used
if (!ProfileWorld::isNoGraphics()) if (!ProfileWorld::isNoGraphics())
{ {
if (hasGLExtension("GL_AMD_vertex_shader_layer")) { if (hasGLExtension("GL_AMD_vertex_shader_layer")) {
hasVSLayer = true; 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
} }

View File

@ -199,6 +199,7 @@ class IrrDriver : public IEventReceiver, public NoCopy
private: private:
int GLMajorVersion, GLMinorVersion; int GLMajorVersion, GLMinorVersion;
bool hasVSLayer; bool hasVSLayer;
bool hasBaseInstance;
bool m_need_ubo_workaround; bool m_need_ubo_workaround;
bool m_need_rh_workaround; bool m_need_rh_workaround;
/** The irrlicht device. */ /** The irrlicht device. */
@ -293,6 +294,11 @@ public:
return m_need_rh_workaround; return m_need_rh_workaround;
} }
bool hasARB_base_instance() const
{
return hasBaseInstance;
}
bool hasVSLayerExtension() const bool hasVSLayerExtension() const
{ {
return hasVSLayer; return hasVSLayer;

View File

@ -176,6 +176,11 @@ struct instanced_custom_unroll_args<>
size_t count = mesh->IndexCount; size_t count = mesh->IndexCount;
Shader->setUniforms(args...); Shader->setUniforms(args...);
#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); glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
} }
}; };
@ -196,36 +201,25 @@ void renderInstancedMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vec
glUseProgram(Shader::getInstance()->Program); glUseProgram(Shader::getInstance()->Program);
for (unsigned i = 0; i < meshes->size(); i++) for (unsigned i = 0; i < meshes->size(); i++)
{ {
std::vector<uint64_t> Handles;
std::vector<GLuint> Textures; std::vector<GLuint> Textures;
GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i))); GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i)));
#ifdef DEBUG #ifdef DEBUG
if (mesh.VAOType != VertexType) if (mesh.VAOType != VertexType)
Log::error("RenderGeometry", "Wrong instanced vertex format"); Log::error("RenderGeometry", "Wrong instanced vertex format");
#endif #endif
if (!irr_driver->hasARB_base_instance())
glBindVertexArray(mesh.vao); glBindVertexArray(mesh.vao);
if (!UserConfigParams::m_bindless_textures)
{
for (unsigned j = 0; j < TexUnits.size(); j++) for (unsigned j = 0; j < TexUnits.size(); j++)
{ {
if (!mesh.textures[TexUnits[j].m_id]) if (!mesh.textures[TexUnits[j].m_id])
mesh.textures[j] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); mesh.textures[j] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[TexUnits[j].m_id], TexUnits[j].m_premul_alpha); compressTexture(mesh.textures[TexUnits[j].m_id], TexUnits[j].m_premul_alpha);
if (UserConfigParams::m_bindless_textures)
{
#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
Textures.push_back(getTextureGLuint(mesh.textures[TexUnits[j].m_id])); Textures.push_back(getTextureGLuint(mesh.textures[TexUnits[j].m_id]));
} }
if (UserConfigParams::m_bindless_textures)
Shader::getInstance()->SetTextureHandles(Handles);
else
Shader::getInstance()->SetTextureUnits(Textures); Shader::getInstance()->SetTextureUnits(Textures);
}
instanced_custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes->at(i)); instanced_custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes->at(i));
} }
} }
@ -306,15 +300,23 @@ void IrrDriver::renderSolidFirstPass()
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS, 2, 1>(TexUnits(TexUnit(0, true)), AnimatedListMatDetails::getInstance()); renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS, 2, 1>(TexUnits(TexUnit(0, true)), AnimatedListMatDetails::getInstance());
renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD, 3, 2, 1>(TexUnits(TexUnit(0, true)), AnimatedListMatUnlit::getInstance()); renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD, 3, 2, 1>(TexUnits(TexUnit(0, true)), AnimatedListMatUnlit::getInstance());
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
renderInstancedMeshes1stPass<MeshShader::InstancedObjectPass1Shader, video::EVT_STANDARD>( renderInstancedMeshes1stPass<MeshShader::InstancedObjectPass1Shader, video::EVT_STANDARD>(
TexUnits(TexUnit(0, true)), TexUnits(TexUnit(0, true)),
ListInstancedMatDefault::getInstance()); ListInstancedMatDefault::getInstance());
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
renderInstancedMeshes1stPass<MeshShader::InstancedObjectRefPass1Shader, video::EVT_STANDARD>( renderInstancedMeshes1stPass<MeshShader::InstancedObjectRefPass1Shader, video::EVT_STANDARD>(
TexUnits(TexUnit(0, true)), TexUnits(TexUnit(0, true)),
ListInstancedMatAlphaRef::getInstance()); ListInstancedMatAlphaRef::getInstance());
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
renderInstancedMeshes1stPass<MeshShader::InstancedGrassPass1Shader, video::EVT_STANDARD, 2>( renderInstancedMeshes1stPass<MeshShader::InstancedGrassPass1Shader, video::EVT_STANDARD, 2>(
TexUnits(TexUnit(0, true)), TexUnits(TexUnit(0, true)),
ListInstancedMatGrass::getInstance()); ListInstancedMatGrass::getInstance());
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_TANGENTS, InstanceTypeDefault));
renderInstancedMeshes1stPass<MeshShader::InstancedNormalMapShader, video::EVT_TANGENTS>( renderInstancedMeshes1stPass<MeshShader::InstancedNormalMapShader, video::EVT_TANGENTS>(
TexUnits(TexUnit(1, false), TexUnit(0, true)), TexUnits(TexUnit(1, false), TexUnit(0, true)),
ListInstancedMatNormalMap::getInstance()); ListInstancedMatNormalMap::getInstance());
@ -349,16 +351,6 @@ void renderMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::
} }
else else
Textures.push_back(getTextureGLuint(mesh.textures[TexUnits[j].m_id])); 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 (mesh.VAOType != VertexType) if (mesh.VAOType != VertexType)
@ -385,42 +377,28 @@ void renderInstancedMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vec
for (unsigned i = 0; i < meshes->size(); i++) for (unsigned i = 0; i < meshes->size(); i++)
{ {
GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i))); GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i)));
if (!irr_driver->hasARB_base_instance())
glBindVertexArray(mesh.vao); glBindVertexArray(mesh.vao);
std::vector<GLuint> Textures(Prefilled_tex); if (UserConfigParams::m_bindless_textures)
{
std::vector<uint64_t> Handles(Prefilled_Handles); std::vector<uint64_t> Handles(Prefilled_Handles);
for (unsigned i = 0; i < TexUnits.size(); i++)
Handles.push_back(0);
Shader::getInstance()->SetTextureHandles(Handles);
}
else
{
std::vector<GLuint> Textures(Prefilled_tex);
for (unsigned j = 0; j < TexUnits.size(); j++) for (unsigned j = 0; j < TexUnits.size(); j++)
{ {
if (!mesh.textures[TexUnits[j].m_id]) if (!mesh.textures[TexUnits[j].m_id])
mesh.textures[TexUnits[j].m_id] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); 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); 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])); 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)
Shader::getInstance()->SetTextureHandles(Handles);
else
Shader::getInstance()->SetTextureUnits(Textures); Shader::getInstance()->SetTextureUnits(Textures);
}
}
instanced_custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes->at(i)); instanced_custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes->at(i));
} }
@ -529,15 +507,23 @@ void IrrDriver::renderSolidSecondPass()
TexUnit(0, true) TexUnit(0, true)
), ListMatNormalMap::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex); ), ListMatNormalMap::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectPass2Shader>( renderInstancedMeshes2ndPass<MeshShader::InstancedObjectPass2Shader>(
TexUnits(TexUnit(0, true)), TexUnits(TexUnit(0, true)),
ListInstancedMatDefault::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex); ListInstancedMatDefault::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_TANGENTS, InstanceTypeDefault));
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectPass2Shader>( renderInstancedMeshes2ndPass<MeshShader::InstancedObjectPass2Shader>(
TexUnits(TexUnit(0, true)), TexUnits(TexUnit(0, true)),
ListInstancedMatNormalMap::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex); ListInstancedMatNormalMap::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectRefPass2Shader>( renderInstancedMeshes2ndPass<MeshShader::InstancedObjectRefPass2Shader>(
TexUnits(TexUnit(0, true)), TexUnits(TexUnit(0, true)),
ListInstancedMatAlphaRef::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex); ListInstancedMatAlphaRef::getInstance(), createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
DiffSpecSSAOTex.push_back(irr_driver->getDepthStencilTexture()); DiffSpecSSAOTex.push_back(irr_driver->getDepthStencilTexture());
renderInstancedMeshes2ndPass<MeshShader::InstancedGrassPass2Shader, 3, 2>( renderInstancedMeshes2ndPass<MeshShader::InstancedGrassPass2Shader, 3, 2>(
TexUnits(TexUnit(0, true)), TexUnits(TexUnit(0, true)),
@ -788,6 +774,11 @@ struct instanced_shadow_custom_unroll_args<>
size_t count = mesh->IndexCount; size_t count = mesh->IndexCount;
Shader->setUniforms(args...); Shader->setUniforms(args...);
#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); glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count);
} }
}; };
@ -811,27 +802,17 @@ void renderInstancedShadow(const std::vector<GLuint> TextureUnits, const std::ve
std::vector<uint64_t> Handles; std::vector<uint64_t> Handles;
std::vector<GLuint> Textures; std::vector<GLuint> Textures;
GLMesh *mesh = STK::tuple_get<0>(t->at(i)); GLMesh *mesh = STK::tuple_get<0>(t->at(i));
if (!irr_driver->hasARB_base_instance())
glBindVertexArray(mesh->vao_shadow_pass); glBindVertexArray(mesh->vao_shadow_pass);
if (!UserConfigParams::m_bindless_textures)
{
for (unsigned j = 0; j < TextureUnits.size(); j++) for (unsigned j = 0; j < TextureUnits.size(); j++)
{ {
compressTexture(mesh->textures[TextureUnits[j]], true); compressTexture(mesh->textures[TextureUnits[j]], true);
if (UserConfigParams::m_bindless_textures)
{
#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
Textures.push_back(getTextureGLuint(mesh->textures[TextureUnits[j]])); Textures.push_back(getTextureGLuint(mesh->textures[TextureUnits[j]]));
}
if (UserConfigParams::m_bindless_textures)
T::getInstance()->SetTextureHandles(Handles);
else
T::getInstance()->SetTextureUnits(Textures); T::getInstance()->SetTextureUnits(Textures);
}
}
instanced_shadow_custom_unroll_args<List...>::template exec<T>(T::getInstance(), t->at(i)); instanced_shadow_custom_unroll_args<List...>::template exec<T>(T::getInstance(), t->at(i));
} }
} }
@ -883,9 +864,17 @@ void IrrDriver::renderShadows()
renderShadow<MeshShader::RefShadowShader, EVT_STANDARD, 1>(std::vector<GLuint>{ 0 }, AnimatedListMatUnlit::getInstance()); renderShadow<MeshShader::RefShadowShader, EVT_STANDARD, 1>(std::vector<GLuint>{ 0 }, AnimatedListMatUnlit::getInstance());
renderShadow<MeshShader::ShadowShader, EVT_2TCOORDS, 1>(noTexUnits, AnimatedListMatDetails::getInstance()); renderShadow<MeshShader::ShadowShader, EVT_2TCOORDS, 1>(noTexUnits, AnimatedListMatDetails::getInstance());
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getShadowInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
renderInstancedShadow<MeshShader::InstancedShadowShader>(noTexUnits, ListInstancedMatDefault::getInstance()); renderInstancedShadow<MeshShader::InstancedShadowShader>(noTexUnits, ListInstancedMatDefault::getInstance());
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getShadowInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
renderInstancedShadow<MeshShader::InstancedRefShadowShader>(std::vector<GLuint>{ 0 }, ListInstancedMatAlphaRef::getInstance()); renderInstancedShadow<MeshShader::InstancedRefShadowShader>(std::vector<GLuint>{ 0 }, ListInstancedMatAlphaRef::getInstance());
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getShadowInstanceVAO(video::EVT_STANDARD, InstanceTypeDefault));
renderInstancedShadow<MeshShader::InstancedGrassShadowShader, 2>(std::vector<GLuint>{ 0 }, ListInstancedMatGrass::getInstance()); renderInstancedShadow<MeshShader::InstancedGrassShadowShader, 2>(std::vector<GLuint>{ 0 }, ListInstancedMatGrass::getInstance());
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getShadowInstanceVAO(video::EVT_TANGENTS, InstanceTypeDefault));
renderInstancedShadow<MeshShader::InstancedShadowShader>(noTexUnits, ListInstancedMatNormalMap::getInstance()); renderInstancedShadow<MeshShader::InstancedShadowShader>(noTexUnits, ListInstancedMatNormalMap::getInstance());
glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_POLYGON_OFFSET_FILL);

View File

@ -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/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.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/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(); AssignUniforms();
AssignSamplerNames(Program, 0, "tex"); 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/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.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/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(); AssignUniforms();
AssignSamplerNames(Program, 0, "tex"); 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/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_grass.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/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"); AssignUniforms("windDir");
AssignSamplerNames(Program, 0, "tex"); 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/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.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/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(); AssignUniforms();
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); 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/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.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/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(); AssignUniforms();
AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo"); 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/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.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/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(); AssignUniforms();
AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo"); 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/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_grass.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/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"); AssignUniforms("windDir", "SunDir");
AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "dtex", 4, "Albedo"); AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "dtex", 4, "Albedo");
@ -1158,7 +1158,7 @@ namespace MeshShader
Program = LoadProgram( Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.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()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str());
} }
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
@ -1200,15 +1200,15 @@ namespace MeshShader
Program = LoadProgram( Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.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 else
{ {
Program = LoadProgram( Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.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/object_unlit.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_shadowref.frag").c_str());
} }
AssignSamplerNames(Program, 0, "tex"); AssignSamplerNames(Program, 0, "tex");
@ -1251,15 +1251,15 @@ namespace MeshShader
Program = LoadProgram( Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedgrassshadow.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 else
{ {
Program = LoadProgram( Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedgrassshadow.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_GEOMETRY_SHADER, file_manager->getAsset("shaders/instanced_shadow.geom").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());
} }
AssignSamplerNames(Program, 0, "tex"); AssignSamplerNames(Program, 0, "tex");

View File

@ -439,9 +439,11 @@ public:
void SetTextureHandles(const std::vector<uint64_t> &args) void SetTextureHandles(const std::vector<uint64_t> &args)
{ {
assert(args.size() == TextureLocation.size() && "Wrong Handle count");
for (unsigned i = 0; i < args.size(); i++) for (unsigned i = 0; i < args.size(); i++)
{ {
#ifdef Bindless_Texture_Support #ifdef Bindless_Texture_Support
if (args[i])
glUniformHandleui64ARB(TextureLocation[i], args[i]); glUniformHandleui64ARB(TextureLocation[i], args[i]);
#endif #endif
} }

View File

@ -50,42 +50,55 @@ void STKInstancedSceneNode::createGLMeshes()
{ {
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
GLmeshes.push_back(allocateMeshBuffer(mb)); GLmeshes.push_back(allocateMeshBuffer(mb));
fillLocalBuffer(GLmeshes.back(), mb); GLMesh &mesh = GLmeshes.back();
if (irr_driver->hasARB_base_instance())
{
std::pair<unsigned, unsigned> 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<InstanceData>());
} }
isMaterialInitialized = false; isMaterialInitialized = false;
} }
void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh) void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, const std::vector<InstanceData> &instances)
{
if (!irr_driver->hasARB_base_instance())
{ {
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride)); mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride));
glGenBuffers(1, &instances_vbo); glGenBuffers(1, &instances_vbo);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, instances.size() * sizeof(InstanceData), instances.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(7); glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0); glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
glVertexAttribDivisor(7, 1); glVertexAttribDivisor(7, 1);
glEnableVertexAttribArray(8); glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float))); glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(8, 1); glVertexAttribDivisor(8, 1);
glEnableVertexAttribArray(9); glEnableVertexAttribArray(9);
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float))); glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(9, 1); glVertexAttribDivisor(9, 1);
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride)); mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride));
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glEnableVertexAttribArray(7); glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0); glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
glVertexAttribDivisor(7, 4); glVertexAttribDivisor(7, 4);
glEnableVertexAttribArray(8); glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float))); glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(8, 4); glVertexAttribDivisor(8, 4);
glEnableVertexAttribArray(9); glEnableVertexAttribArray(9);
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float))); glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(9, 4); glVertexAttribDivisor(9, 4);
glBindVertexArray(0); glBindVertexArray(0);
} }
}
void STKInstancedSceneNode::setFirstTimeMaterial() void STKInstancedSceneNode::setFirstTimeMaterial()
{ {
@ -100,7 +113,9 @@ void STKInstancedSceneNode::setFirstTimeMaterial()
GLMesh &mesh = GLmeshes[i]; GLMesh &mesh = GLmeshes[i];
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType()); 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); MeshSolidMaterial[MatType].push_back(&mesh);
} }
isMaterialInitialized = true; isMaterialInitialized = true;
@ -108,34 +123,65 @@ void STKInstancedSceneNode::setFirstTimeMaterial()
void STKInstancedSceneNode::addInstance(const core::vector3df &origin, const core::vector3df &orientation, const core::vector3df &scale) void STKInstancedSceneNode::addInstance(const core::vector3df &origin, const core::vector3df &orientation, const core::vector3df &scale)
{ {
instance_pos.push_back(origin.X); for (unsigned i = 0; i < GLmeshes.size(); i++)
instance_pos.push_back(origin.Y); {
instance_pos.push_back(origin.Z); GLMesh &mesh = GLmeshes[i];
instance_pos.push_back(orientation.X); #ifdef Bindless_Texture_Support
instance_pos.push_back(orientation.Y); if (UserConfigParams::m_bindless_textures)
instance_pos.push_back(orientation.Z); {
instance_pos.push_back(scale.X); for (unsigned j = 0; j < 2; j++)
instance_pos.push_back(scale.Y); {
instance_pos.push_back(scale.Z); 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 STKInstancedSceneNode::getInstanceTransform(int id)
{ {
core::matrix4 mat; core::matrix4 mat;
int offset = id * 9; const InstanceData &instance = instanceData[0][id];
mat.setTranslation(core::vector3df( mat.setTranslation(core::vector3df(
instance_pos[offset], instance.Origin.X,
instance_pos[offset + 1], instance.Origin.Y,
instance_pos[offset + 2])); instance.Origin.Z));
mat.setRotationDegrees(core::vector3df( mat.setRotationDegrees(core::vector3df(
instance_pos[offset + 3], instance.Orientation.X,
instance_pos[offset + 4], instance.Orientation.Y,
instance_pos[offset + 5])); instance.Orientation.Z));
mat.setScale(core::vector3df( mat.setScale(core::vector3df(
instance_pos[offset + 6], instance.Scale.X,
instance_pos[offset + 7], instance.Scale.Y,
instance_pos[offset + 8])); instance.Scale.Z));
return mat; return mat;
} }
@ -150,17 +196,18 @@ void STKInstancedSceneNode::render()
setFirstTimeMaterial(); setFirstTimeMaterial();
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
{
for (unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++) for (unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++)
{ {
GLMesh *mesh = MeshSolidMaterial[MAT_DEFAULT][i]; GLMesh *mesh = MeshSolidMaterial[MAT_DEFAULT][i];
ListInstancedMatDefault::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9)); ListInstancedMatDefault::getInstance()->push_back(STK::make_tuple(mesh, instanceData[0].size()));
} }
for (unsigned i = 0; i < MeshSolidMaterial[MAT_ALPHA_REF].size(); i++) for (unsigned i = 0; i < MeshSolidMaterial[MAT_ALPHA_REF].size(); i++)
{ {
GLMesh *mesh = MeshSolidMaterial[MAT_ALPHA_REF][i]; GLMesh *mesh = MeshSolidMaterial[MAT_ALPHA_REF][i];
ListInstancedMatAlphaRef::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9)); ListInstancedMatAlphaRef::getInstance()->push_back(STK::make_tuple(mesh, instanceData[0].size()));
} }
windDir = getWind(); windDir = getWind();
@ -168,12 +215,13 @@ void STKInstancedSceneNode::render()
for (unsigned i = 0; i < MeshSolidMaterial[MAT_GRASS].size(); i++) for (unsigned i = 0; i < MeshSolidMaterial[MAT_GRASS].size(); i++)
{ {
GLMesh *mesh = MeshSolidMaterial[MAT_GRASS][i]; GLMesh *mesh = MeshSolidMaterial[MAT_GRASS][i];
ListInstancedMatGrass::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9, 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++) for (unsigned i = 0; i < MeshSolidMaterial[MAT_NORMAL_MAP].size(); i++)
{ {
GLMesh *mesh = MeshSolidMaterial[MAT_NORMAL_MAP][i]; GLMesh *mesh = MeshSolidMaterial[MAT_NORMAL_MAP][i];
ListInstancedMatNormalMap::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9)); ListInstancedMatNormalMap::getInstance()->push_back(STK::make_tuple(mesh, instanceData[0].size()));
}
} }
} }

View File

@ -22,13 +22,13 @@ protected:
int m_ref_count; int m_ref_count;
std::vector<GLMesh *> MeshSolidMaterial[MAT_COUNT]; std::vector<GLMesh *> MeshSolidMaterial[MAT_COUNT];
std::vector<GLMesh> GLmeshes; std::vector<GLMesh> GLmeshes;
std::vector<float> instance_pos; std::vector<std::vector<InstanceData> > instanceData;
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView; core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView;
GLuint instances_vbo; GLuint instances_vbo;
void createGLMeshes(); void createGLMeshes();
bool isMaterialInitialized; bool isMaterialInitialized;
void setFirstTimeMaterial(); void setFirstTimeMaterial();
void initinstancedvaostate(GLMesh &mesh); void initinstancedvaostate(GLMesh &mesh, const std::vector<InstanceData> &);
void cleanGL(); void cleanGL();
core::vector3df windDir; core::vector3df windDir;
public: public:
@ -40,7 +40,7 @@ public:
virtual void render(); virtual void render();
void addInstance(const core::vector3df &origin, const core::vector3df &orientation, const core::vector3df &scale); 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); core::matrix4 getInstanceTransform(int id);

View File

@ -46,6 +46,7 @@ struct GLMesh {
core::matrix4 TextureMatrix; core::matrix4 TextureMatrix;
size_t vaoBaseVertex; size_t vaoBaseVertex;
size_t vaoOffset; size_t vaoOffset;
size_t vaoBaseInstance;
video::E_VERTEX_TYPE VAOType; video::E_VERTEX_TYPE VAOType;
uint64_t TextureHandles[6]; uint64_t TextureHandles[6];
}; };

View File

@ -439,32 +439,32 @@ bool onEvent(const SEvent &event)
{ {
#if !defined(__APPLE__) #if !defined(__APPLE__)
DebugSliderDialog *dsd = new DebugSliderDialog(); 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){ [](int v){
video::SColorf ambient = irr_driver->getAmbientLight(); video::SColorf ambient = irr_driver->getAmbientLight();
ambient.setColorComponentValue(0, v / 255.); ambient.setColorComponentValue(0, v / 255.f);
irr_driver->setAmbientLight(ambient); } 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){ [](int v){
video::SColorf ambient = irr_driver->getAmbientLight(); video::SColorf ambient = irr_driver->getAmbientLight();
ambient.setColorComponentValue(1, v / 255.); ambient.setColorComponentValue(1, v / 255.f);
irr_driver->setAmbientLight(ambient); } 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){ [](int v){
video::SColorf ambient = irr_driver->getAmbientLight(); video::SColorf ambient = irr_driver->getAmbientLight();
ambient.setColorComponentValue(2, v / 255.); ambient.setColorComponentValue(2, v / 255.f);
irr_driver->setAmbientLight(ambient); } irr_driver->setAmbientLight(ambient); }
); );
dsd->setSliderHook("ssao_radius", 0, 100, [](){ return irr_driver->getSSAORadius() * 10; }, dsd->setSliderHook("ssao_radius", 0, 100, [](){ return irr_driver->getSSAORadius() * 10.f; },
[](int v){irr_driver->setSSAORadius(v / 10.); } [](int v){irr_driver->setSSAORadius(v / 10.f); }
); );
dsd->setSliderHook("ssao_k", 0, 100, [](){ return irr_driver->getSSAOK() * 10; }, dsd->setSliderHook("ssao_k", 0, 100, [](){ return irr_driver->getSSAOK() * 10.f; },
[](int v){irr_driver->setSSAOK(v / 10.); } [](int v){irr_driver->setSSAOK(v / 10.f); }
); );
dsd->setSliderHook("ssao_sigma", 0, 100, [](){ return irr_driver->getSSAOSigma() * 10; }, dsd->setSliderHook("ssao_sigma", 0, 100, [](){ return irr_driver->getSSAOSigma() * 10.f; },
[](int v){irr_driver->setSSAOSigma(v / 10.); } [](int v){irr_driver->setSSAOSigma(v / 10.f); }
); );
#endif #endif
} }