Merge branch 'master' into gui_screen

This commit is contained in:
hiker 2014-09-05 09:18:17 +10:00
commit 1c23309161
80 changed files with 2595 additions and 1501 deletions

View File

@ -15,12 +15,12 @@ option(USE_WIIUSE "Support for wiimote input devices" ON)
option(USE_FRIBIDI "Support for right-to-left languages" ON)
option(CHECK_ASSETS "Check if assets are installed in ../stk-assets" ON)
if(UNIX)
if(UNIX OR MINGW)
option(USE_CPP2011 "Activate C++ 2011 mode (GCC only)" OFF)
endif()
if(MSVC)
if(MSVC OR MINGW)
# Normally hide the option to build wiiuse on VS, since it depends
# on the installation of the Windows DDK (Driver Developer Kit),
# on the installation of the Windows DDK (Driver Developer Kit),
# which also needs an absolute path :(
option(WIIUSE_BUILD "Build wiiuse lib (only for developers)" OFF)
mark_as_advanced(WIIUSE_BUILD)
@ -28,6 +28,10 @@ else()
set(WIIUSE_BUILD ON)
endif()
if(MINGW)
set(USE_WIIUSE OFF)
endif()
if(UNIX AND NOT APPLE)
option(USE_XRANDR "Use xrandr instead of vidmode" ON)
option(USE_ASAN "Build with Leak/Address sanitizer" OFF)
@ -78,6 +82,11 @@ if(MSVC)
add_definitions(/D_IRR_STATIC_LIB_)
endif()
if(MINGW)
set(ENV{OPENALDIR} ${PROJECT_SOURCE_DIR}/dependencies)
add_definitions(-D_IRR_STATIC_LIB_)
endif()
if(APPLE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch i386")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch i386 -F/Library/Frameworks")
@ -122,8 +131,15 @@ if(USE_FRIBIDI)
endif()
endif()
# OpenMP
find_package(OpenMP)
if (OPENMP_FOUND)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
if(UNIX)
if(UNIX OR MINGW)
# if(USE_CPP2011)
add_definitions("-std=gnu++0x")
# endif()
@ -145,7 +161,7 @@ if(UNIX AND NOT APPLE)
endif()
endif()
# Set some compiler options
if(UNIX)
add_definitions(-Wall)
@ -173,7 +189,7 @@ endif()
# TODO: remove this switch
add_definitions(-DHAVE_OGGVORBIS)
if(WIN32)
if(WIN32 AND NOT MINGW)
configure_file("${STK_SOURCE_DIR}/windows_installer/icon_rc.template" "${PROJECT_BINARY_DIR}/tmp/icon.rc")
endif()
@ -254,7 +270,7 @@ target_link_libraries(supertuxkart
${OGGVORBIS_LIBRARIES}
${OPENAL_LIBRARY}
${OPENGL_LIBRARIES})
if(UNIX AND NOT APPLE)
if(USE_XRANDR)
target_link_libraries(supertuxkart ${XRANDR_LIBRARIES})
@ -288,8 +304,12 @@ if(USE_WIIUSE)
if(APPLE)
find_library(BLUETOOTH_LIBRARY NAMES IOBluetooth PATHS /Developer/Library/Frameworks/IOBluetooth.framework)
target_link_libraries(supertuxkart wiiuse ${BLUETOOTH_LIBRARY})
elseif(MSVC)
add_definitions("/DWIIUSE_STATIC")
elseif(WIN32)
if(MSVC)
add_definitions("/DWIIUSE_STATIC")
else()
add_definitions("-DWIIUSE_STATIC")
endif()
if(WIIUSE_BUILD)
target_link_libraries(supertuxkart wiiuse)
else()
@ -302,12 +322,12 @@ if(USE_WIIUSE)
endif()
if(MSVC)
if(MSVC OR MINGW)
target_link_libraries(supertuxkart iphlpapi.lib)
add_custom_command(TARGET supertuxkart POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${PROJECT_SOURCE_DIR}/dependencies/dll"
$<TARGET_FILE_DIR:supertuxkart>)
$<TARGET_FILE_DIR:supertuxkart>)
add_custom_target(stkshaders SOURCES ${STK_SHADERS})
endif()
@ -316,7 +336,7 @@ add_subdirectory(tools/font_tool)
# ==== Make dist target ====
if(MSVC)
if(MSVC OR MINGW)
# Don't create a dist target for VS
else()
add_custom_target(dist
@ -340,9 +360,9 @@ endif()
# ==== Checking if stk-assets folder exists ====
if(CHECK_ASSETS)
if((IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/karts) AND
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/library) AND
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/music) AND
if((IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/karts) AND
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/library) AND
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/music) AND
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/sfx) AND
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/textures) AND
(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/tracks))

View File

@ -23,7 +23,7 @@ Ubuntu command:
```
sudo apt-get install autoconf automake build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev \
libgl1-mesa-dev libglu1-mesa-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev
libgl1-mesa-dev libglu1-mesa-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev libxrandr-dev
```
Unpack the files from the tarball like this:

View File

@ -22,7 +22,9 @@ void main(void)
{
vec4 color = texture(Albedo, uv);
#ifdef GL_ARB_bindless_texture
#ifdef SRGBBindlessFix
color.xyz = pow(color.xyz, vec3(2.2));
#endif
#endif
vec4 detail = texture(Detail, uv_bis);
color *= detail;

View File

@ -0,0 +1,8 @@
in vec4 glowColor;
flat out vec4 FragColor;
void main()
{
FragColor = vec4(glowColor.rgb, 1.0);
}

View File

@ -0,0 +1,24 @@
layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal;
layout(location = 2) in vec4 Color;
layout(location = 3) in vec2 Texcoord;
layout(location = 5) in vec3 Tangent;
layout(location = 6) in vec3 Bitangent;
layout(location = 7) in vec3 Origin;
layout(location = 8) in vec3 Orientation;
layout(location = 9) in vec3 Scale;
layout(location = 12) in vec4 GlowColor;
flat out vec4 glowColor;
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
void main(void)
{
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation, Scale) * InverseViewMatrix);
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(Position, 1.);
glowColor = GlowColor;
}

View File

@ -33,7 +33,9 @@ void main(void)
vec4 color = texture(Albedo, uv);
#ifdef GL_ARB_bindless_texture
#ifdef SRGBBindlessFix
color.xyz = pow(color.xyz, vec3(2.2));
#endif
#endif
if (color.a < 0.5) discard;
vec3 LightFactor = (scattering * 0.3) + getLightFactor(1.);

View File

@ -0,0 +1,31 @@
#ifndef GL_ARB_bindless_texture
uniform sampler2D Albedo;
uniform sampler2D Detail;
#endif
#ifdef GL_ARB_bindless_texture
flat in sampler2D handle;
flat in sampler2D secondhandle;
#endif
in vec2 uv;
in vec2 uv_bis;
out vec4 FragColor;
vec3 getLightFactor(float specMapValue);
void main(void)
{
#ifdef GL_ARB_bindless_texture
vec4 color = texture(handle, uv);
#ifdef SRGBBindlessFix
color.xyz = pow(color.xyz, vec3(2.2));
#endif
vec4 detail = texture(secondhandle, uv_bis);
#else
vec4 color = texture(Albedo, uv);
vec4 detail = texture(Detail, uv_bis);
#endif
color *= detail;
vec3 LightFactor = getLightFactor(1. - color.a);
FragColor = vec4(color.xyz * LightFactor, 1.);
}

View File

@ -35,7 +35,9 @@ void main(void)
#ifdef GL_ARB_bindless_texture
vec4 color = texture(handle, uv);
#ifdef SRGBBindlessFix
color.xyz = pow(color.xyz, vec3(2.2));
#endif
#else
vec4 color = texture(Albedo, uv);
#endif

View File

@ -14,7 +14,10 @@ vec3 getLightFactor(float specMapValue);
void main(void)
{
#ifdef GL_ARB_bindless_texture
vec4 col = pow(texture(handle, uv), vec4(2.2));
vec4 col = texture(handle, uv);
#ifdef SRGBBindlessFix
col.xyz = pow(col.xyz, vec3(2.2));
#endif
#else
vec4 col = texture(Albedo, uv);
#endif

View File

@ -0,0 +1,26 @@
#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);
#ifdef SRGBBindlessFix
col.xyz = pow(col.xyz, vec3(2.2));
#endif
#else
vec4 col = texture(tex, uv);
#endif
col.xyz *= pow(color.xyz, vec3(2.2));
if (col.a < 0.5) discard;
FragColor = vec4(col.xyz, 1.);
}

View File

@ -0,0 +1,35 @@
// See http://www.ozone3d.net/tutorials/glsl_texturing_p04.php for ref
#ifndef GL_ARB_bindless_texture
uniform sampler2D tex;
#endif
#ifdef GL_ARB_bindless_texture
flat in sampler2D handle;
#endif
in vec3 nor;
out vec4 FragColor;
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
vec3 getLightFactor(float specMapValue);
void main() {
vec3 texc = gl_FragCoord.xyz / vec3(screen, 1.);
vec3 u = getPosFromUVDepth(texc, InverseProjectionMatrix).xyz;
vec3 r = reflect(u, nor);
float m = 2.0 * sqrt(r.x * r.x + r.y * r.y + (r.z + 1.0) * (r.z + 1.0));
r.y = - r.y;
#ifdef GL_ARB_bindless_texture
vec4 detail0 = texture(handle, r.xy / m + .5);
#ifdef SRGBBindlessFix
detail0.xyz = pow(detail0.xyz, vec3(2.2));
#endif
#else
vec4 detail0 = texture(tex, r.xy / m + .5);
#endif
vec3 LightFactor = getLightFactor(1.);
FragColor = vec4(detail0.xyz * LightFactor, 1.);
}

View File

@ -15,7 +15,9 @@ void main(void)
{
#ifdef GL_ARB_bindless_texture
vec4 col = texture(handle, uv);
#ifdef SRGBBindlessFix
col.xyz = pow(col.xyz, vec3(2.2));
#endif
#else
vec4 col = texture(Albedo, uv);
#endif

View File

@ -0,0 +1,27 @@
#ifndef GL_ARB_bindless_texture
uniform sampler2D tex;
#endif
in vec2 uv;
in vec3 nor;
in vec4 color;
#ifdef GL_ARB_bindless_texture
flat in uvec2 handle;
#endif
layout (location = 0) out vec3 RSMColor;
layout (location = 1) out vec3 RSMNormals;
void main()
{
#ifdef GL_ARB_bindless_texture
vec4 col = texture(sampler2D(handle), uv);
#ifdef SRGBBindlessFix
col.xyz = pow(col.xyz, vec3(2.2));
#endif
#else
vec4 col = texture(tex, uv);
#endif
if (col.a < .5) discard;
RSMColor = col.xyz * color.rgb;
RSMNormals = .5 * normalize(nor) + .5;
}

View File

@ -0,0 +1,39 @@
uniform mat4 RSMMatrix;
layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal;
layout(location = 2) in vec4 Color;
layout(location = 3) in vec2 Texcoord;
layout(location = 4) in vec2 SecondTexcoord;
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 uvec2 Handle;
#endif
out vec3 nor;
out vec2 uv;
out vec2 uv_bis;
out vec4 color;
#ifdef GL_ARB_bindless_texture
flat out uvec2 handle;
#endif
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
void main(void)
{
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
mat4 ModelViewProjectionMatrix = RSMMatrix * ModelMatrix;
mat4 TransposeInverseModel = transpose(inverse(ModelMatrix));
gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.);
nor = (TransposeInverseModel * vec4(Normal, 0.)).xyz;
uv = Texcoord;
color = Color.zyxw;
#ifdef GL_ARB_bindless_texture
handle = Handle;
#endif
}

View File

@ -2,14 +2,14 @@ layout(triangles) in;
layout(triangle_strip, max_vertices=3) out;
#ifdef GL_ARB_bindless_texture
flat in sampler2D hdle[3];
flat in uvec2 hdle[3];
#endif
in vec2 tc[3];
in int layerId[3];
out vec2 uv;
#ifdef GL_ARB_bindless_texture
out flat sampler2D handle;
out flat uvec2 handle;
#endif
void main(void)

View File

@ -3,7 +3,7 @@ uniform sampler2D tex;
#endif
#ifdef GL_ARB_bindless_texture
flat in sampler2D handle;
flat in uvec2 handle;
#endif
in vec2 uv;
in vec4 color;
@ -12,7 +12,7 @@ out vec4 FragColor;
void main(void)
{
#ifdef GL_ARB_bindless_texture
vec4 col = texture(handle, uv);
vec4 col = texture(sampler2D(handle), uv);
#else
vec4 col = texture(tex, uv);
#endif

View File

@ -1,3 +1,5 @@
uniform int layer;
uniform vec3 windDir;
#if __VERSION__ >= 330
layout(location = 0) in vec3 Position;
@ -8,7 +10,7 @@ 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 = 10) in uvec2 Handle;
#endif
#else
@ -24,13 +26,13 @@ in vec3 Scale;
#ifdef VSLayer
out vec2 uv;
#ifdef GL_ARB_bindless_texture
flat out sampler2D handle;
flat out uvec2 handle;
#endif
#else
out vec2 tc;
out int layerId;
#ifdef GL_ARB_bindless_texture
flat out sampler2D hdle;
flat out uvec2 hdle;
#endif
#endif
@ -41,14 +43,14 @@ void main(void)
{
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
#ifdef VSLayer
gl_Layer = gl_InstanceID & 3;
gl_Layer = layer;
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;
layerId = layer;
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
tc = Texcoord;
#ifdef GL_ARB_bindless_texture

View File

@ -1,3 +1,5 @@
uniform int layer;
#if __VERSION__ >= 330
layout(location = 0) in vec3 Position;
layout(location = 3) in vec2 Texcoord;
@ -6,7 +8,7 @@ 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 = 10) in uvec2 Handle;
#endif
#else
@ -21,13 +23,13 @@ in vec3 Scale;
#ifdef VSLayer
out vec2 uv;
#ifdef GL_ARB_bindless_texture
flat out sampler2D handle;
flat out uvec2 handle;
#endif
#else
out vec2 tc;
out int layerId;
#ifdef GL_ARB_bindless_texture
flat out sampler2D hdle;
flat out uvec2 hdle;
#endif
#endif
@ -38,14 +40,14 @@ void main(void)
{
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
#ifdef VSLayer
gl_Layer = gl_InstanceID & 3;
gl_Layer = layer;
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.);
uv = Texcoord;
#ifdef GL_ARB_bindless_texture
handle = Handle;
#endif
#else
layerId = gl_InstanceID & 3;
layerId = layer;
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.);
tc = Texcoord;
#ifdef GL_ARB_bindless_texture

View File

@ -13,7 +13,10 @@ vec3 getLightFactor(float specMapValue);
void main(void)
{
#ifdef GL_ARB_bindless_texture
vec4 col = pow(texture(Albedo, uv), vec4(2.2));
vec4 col = texture(Albedo, uv);
#ifdef SRGBBindlessFix
col.xyz = pow(col.xyz, vec3(2.2));
#endif
#else
vec4 col = texture(Albedo, uv);
#endif

View File

@ -12,7 +12,9 @@ void main(void)
{
vec4 col = texture(tex, uv);
#ifdef GL_ARB_bindless_texture
#ifdef SRGBBindlessFix
col.xyz = pow(col.xyz, vec3(2.2));
#endif
#endif
col.xyz *= pow(color.xyz, vec3(2.2));
if (col.a < 0.5) discard;

View File

@ -26,7 +26,9 @@ void main() {
r.y = - r.y;
vec4 detail0 = texture(tex, r.xy / m + .5);
#ifdef GL_ARB_bindless_texture
#ifdef SRGBBindlessFix
detail0.xyz = pow(detail0.xyz, vec3(2.2));
#endif
#endif
vec3 LightFactor = getLightFactor(1.);

View File

@ -14,7 +14,9 @@ void main(void)
{
vec4 col = texture(Albedo, uv);
#ifdef GL_ARB_bindless_texture
#ifdef SRGBBindlessFix
col.xyz = pow(col.xyz, vec3(2.2));
#endif
#endif
col.xyz *= pow(color.xyz, vec3(2.2));
if (col.a * color.a < 0.5) discard;

View File

@ -1,3 +1,4 @@
uniform int layer;
uniform mat4 ModelMatrix;
#if __VERSION__ >= 330
@ -18,11 +19,11 @@ out int layerId;
void main(void)
{
#ifdef VSLayer
gl_Layer = gl_InstanceID & 3;
gl_Layer = layer;
uv = Texcoord;
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.);
#else
layerId = gl_InstanceID & 3;
layerId = layer;
tc = Texcoord;
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.);
#endif

View File

@ -1,3 +1,4 @@
uniform int layer;
uniform mat4 ModelMatrix;
uniform vec3 windDir;
@ -21,11 +22,11 @@ out int layerId;
void main(void)
{
#ifdef VSLayer
gl_Layer = gl_InstanceID & 3;
gl_Layer = layer;
uv = Texcoord;
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
#else
layerId = gl_InstanceID & 3;
layerId = layer;
tc = Texcoord;
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
#endif

View File

@ -33,10 +33,12 @@ void main() {
vec4 detail3 = texture(tex_detail3, uv);
vec4 detail4 = vec4(0.0);
#ifdef GL_ARB_bindless_texture
#ifdef SRGBBindlessFix
detail0.xyz = pow(detail0.xyz, vec3(2.2));
detail1.xyz = pow(detail1.xyz, vec3(2.2));
detail2.xyz = pow(detail2.xyz, vec3(2.2));
detail3.xyz = pow(detail3.xyz, vec3(2.2));
#endif
#endif
vec4 splatted = splatting.r * detail0 +

View File

@ -4,8 +4,8 @@ Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
@ -24,6 +24,12 @@ subject to the following restrictions:
# include <math.h>
#endif
#if defined(__MINGW32__) && __cplusplus >= 201103
#include <cmath>
using std::isinf;
using std::isnan;
#endif
#include "LinearMath/btTransform.h"
//island management, m_activationState1
@ -51,7 +57,7 @@ typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
#endif
/// btCollisionObject can be used to manage collision detection objects.
/// btCollisionObject can be used to manage collision detection objects.
/// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy.
/// They can be added to the btCollisionWorld.
ATTRIBUTE_ALIGNED16(class) btCollisionObject
@ -64,20 +70,20 @@ protected:
///m_interpolationWorldTransform is used for CCD and interpolation
///it can be either previous or future (predicted) transform
btTransform m_interpolationWorldTransform;
//those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities)
//those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities)
//without destroying the continuous interpolated motion (which uses this interpolation velocities)
btVector3 m_interpolationLinearVelocity;
btVector3 m_interpolationAngularVelocity;
btVector3 m_anisotropicFriction;
int m_hasAnisotropicFriction;
btScalar m_contactProcessingThreshold;
btScalar m_contactProcessingThreshold;
btBroadphaseProxy* m_broadphaseHandle;
btCollisionShape* m_collisionShape;
///m_extensionPointer is used by some internal low-level Bullet extensions.
void* m_extensionPointer;
///m_rootCollisionShape is temporarily used to store the original collision shape
///The m_collisionShape might be temporarily replaced by a child collision shape during collision detection purposes
///If it is NULL, the m_collisionShape is not temporarily replaced.
@ -102,14 +108,14 @@ protected:
void* m_userObjectPointer;
///time of impact calculation
btScalar m_hitFraction;
btScalar m_hitFraction;
///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
btScalar m_ccdSweptSphereRadius;
/// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
btScalar m_ccdMotionThreshold;
/// If some object should have elaborate collision filtering by sub-classes
int m_checkCollideWith;
@ -194,7 +200,7 @@ public:
return (m_collisionFlags & CF_NO_CONTACT_RESPONSE)==0;
}
btCollisionObject();
virtual ~btCollisionObject();
@ -232,7 +238,7 @@ public:
m_collisionShape = collisionShape;
}
///Avoid using this internal API call, the extension pointer is used by some Bullet extensions.
///Avoid using this internal API call, the extension pointer is used by some Bullet extensions.
///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
void* internalGetExtensionPointer() const
{
@ -246,7 +252,7 @@ public:
}
SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1;}
void setActivationState(int newState);
void setDeactivationTime(btScalar time)
@ -385,7 +391,7 @@ public:
SIMD_FORCE_INLINE btScalar getHitFraction() const
{
return m_hitFraction;
return m_hitFraction;
}
void setHitFraction(btScalar hitFraction)
@ -393,7 +399,7 @@ public:
m_hitFraction = hitFraction;
}
SIMD_FORCE_INLINE int getCollisionFlags() const
{
return m_collisionFlags;
@ -403,7 +409,7 @@ public:
{
m_collisionFlags = flags;
}
///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
btScalar getCcdSweptSphereRadius() const
{
@ -439,7 +445,7 @@ public:
{
return m_userObjectPointer;
}
///users can point to their objects, userPointer is not used by Bullet
void setUserPointer(void* userPointer)
{
@ -477,11 +483,11 @@ struct btCollisionObjectDoubleData
btVector3DoubleData m_interpolationLinearVelocity;
btVector3DoubleData m_interpolationAngularVelocity;
btVector3DoubleData m_anisotropicFriction;
double m_contactProcessingThreshold;
double m_contactProcessingThreshold;
double m_deactivationTime;
double m_friction;
double m_restitution;
double m_hitFraction;
double m_hitFraction;
double m_ccdSweptSphereRadius;
double m_ccdMotionThreshold;
@ -509,11 +515,11 @@ struct btCollisionObjectFloatData
btVector3FloatData m_interpolationLinearVelocity;
btVector3FloatData m_interpolationAngularVelocity;
btVector3FloatData m_anisotropicFriction;
float m_contactProcessingThreshold;
float m_contactProcessingThreshold;
float m_deactivationTime;
float m_friction;
float m_restitution;
float m_hitFraction;
float m_hitFraction;
float m_ccdSweptSphereRadius;
float m_ccdMotionThreshold;

View File

@ -4,8 +4,8 @@ Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
@ -26,6 +26,11 @@ subject to the following restrictions:
#endif
#include <math.h>
#if defined(__MINGW32__) && __cplusplus >= 201103
#include <cmath>
using std::isnan;
#endif
class btCollisionShape;
class btMotionState;
class btTypedConstraint;
@ -51,7 +56,7 @@ enum btRigidBodyFlags
///The btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape.
///It is recommended for performance and memory use to share btCollisionShape objects whenever possible.
///There are 3 types of rigid bodies:
///There are 3 types of rigid bodies:
///- A) Dynamic rigid bodies, with positive mass. Motion is controlled by rigid body dynamics.
///- B) Fixed objects with zero mass. They are not moving (basically collision objects)
///- C) Kinematic objects, which are objects without mass, but the user can move them. There is on-way interaction, and Bullet calculates a velocity based on the timestep and previous and current world transform.
@ -66,12 +71,12 @@ class btRigidBody : public btCollisionObject
btScalar m_inverseMass;
btVector3 m_linearFactor;
btVector3 m_gravity;
btVector3 m_gravity;
btVector3 m_gravity_acceleration;
btVector3 m_invInertiaLocal;
btVector3 m_totalForce;
btVector3 m_totalTorque;
btScalar m_linearDamping;
btScalar m_angularDamping;
@ -92,9 +97,9 @@ class btRigidBody : public btCollisionObject
btAlignedObjectArray<btTypedConstraint*> m_constraintRefs;
int m_rigidbodyFlags;
int m_debugBodyId;
protected:
@ -111,7 +116,7 @@ public:
///The btRigidBodyConstructionInfo structure provides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body.
///For dynamic objects, you can use the collision shape to approximate the local inertia tensor, otherwise use the zero vector (default argument)
///You can use the motion state to synchronize the world transform between physics and graphics objects.
///You can use the motion state to synchronize the world transform between physics and graphics objects.
///And if the motion state is provided, the rigid body will initialize its initial world transform from the motion state,
///m_startWorldTransform is only used when you don't provide a motion state.
struct btRigidBodyConstructionInfo
@ -168,16 +173,16 @@ public:
///btRigidBody constructor using construction info
btRigidBody( const btRigidBodyConstructionInfo& constructionInfo);
///btRigidBody constructor for backwards compatibility.
///btRigidBody constructor for backwards compatibility.
///To specify friction (etc) during rigid body construction, please use the other constructor (using btRigidBodyConstructionInfo)
btRigidBody( btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0));
virtual ~btRigidBody()
{
{
//No constraints should point to this rigidbody
//Remove constraints from the dynamics world before you delete the related rigidbodies.
btAssert(m_constraintRefs.size()==0);
//Remove constraints from the dynamics world before you delete the related rigidbodies.
btAssert(m_constraintRefs.size()==0);
}
protected:
@ -187,8 +192,8 @@ protected:
public:
void proceedToTransform(const btTransform& newTrans);
void proceedToTransform(const btTransform& newTrans);
///to keep collision detection and dynamics separate we don't store a rigidbody pointer
///but a rigidbody is derived from btCollisionObject, so we can safely perform an upcast
static const btRigidBody* upcast(const btCollisionObject* colObj)
@ -203,15 +208,15 @@ public:
return (btRigidBody*)colObj;
return 0;
}
/// continuous collision detection needs prediction
void predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ;
void saveKinematicState(btScalar step);
void applyGravity();
void setGravity(const btVector3& acceleration);
void setGravity(const btVector3& acceleration);
const btVector3& getGravity() const
{
@ -249,9 +254,9 @@ public:
SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() {
return m_collisionShape;
}
void setMassProps(btScalar mass, const btVector3& inertia);
const btVector3& getLinearFactor() const
{
return m_linearFactor;
@ -265,10 +270,10 @@ public:
m_invMass = m_linearFactor*m_inverseMass;
}
btScalar getInvMass() const { return m_inverseMass; }
const btMatrix3x3& getInvInertiaTensorWorld() const {
return m_invInertiaTensorWorld;
const btMatrix3x3& getInvInertiaTensorWorld() const {
return m_invInertiaTensorWorld;
}
void integrateVelocities(btScalar step);
void setCenterOfMassTransform(const btTransform& xform);
@ -290,7 +295,7 @@ public:
{
return m_totalTorque;
};
const btVector3& getInvInertiaDiagLocal() const
{
return m_invInertiaLocal;
@ -314,8 +319,8 @@ public:
btAssert(!isnan(torque.getZ()));
m_totalTorque += torque*m_angularFactor;
}
void applyForce(const btVector3& force, const btVector3& rel_pos)
void applyForce(const btVector3& force, const btVector3& rel_pos)
{
btAssert(!isnan(force.getX()));
btAssert(!isnan(force.getY()));
@ -326,7 +331,7 @@ public:
applyCentralForce(force);
applyTorque(rel_pos.cross(force*m_linearFactor));
}
void applyCentralImpulse(const btVector3& impulse)
{
btAssert(!isnan(impulse.getX()));
@ -334,7 +339,7 @@ public:
btAssert(!isnan(impulse.getZ()));
m_linearVelocity += impulse *m_linearFactor * m_inverseMass;
}
void applyTorqueImpulse(const btVector3& torque)
{
btAssert(!isnan(torque.getX()));
@ -342,8 +347,8 @@ public:
btAssert(!isnan(torque.getZ()));
m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
}
void applyImpulse(const btVector3& impulse, const btVector3& rel_pos)
void applyImpulse(const btVector3& impulse, const btVector3& rel_pos)
{
btAssert(!isnan(impulse.getX()));
btAssert(!isnan(impulse.getY()));
@ -361,44 +366,44 @@ public:
}
}
void clearForces()
void clearForces()
{
m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
}
void updateInertiaTensor();
const btVector3& getCenterOfMassPosition() const {
return m_worldTransform.getOrigin();
void updateInertiaTensor();
const btVector3& getCenterOfMassPosition() const {
return m_worldTransform.getOrigin();
}
btQuaternion getOrientation() const;
const btTransform& getCenterOfMassTransform() const {
return m_worldTransform;
const btTransform& getCenterOfMassTransform() const {
return m_worldTransform;
}
const btVector3& getLinearVelocity() const {
return m_linearVelocity;
const btVector3& getLinearVelocity() const {
return m_linearVelocity;
}
const btVector3& getAngularVelocity() const {
return m_angularVelocity;
const btVector3& getAngularVelocity() const {
return m_angularVelocity;
}
inline void setLinearVelocity(const btVector3& lin_vel)
{
{
btAssert(!isnan(lin_vel.getX()));
btAssert(!isnan(lin_vel.getY()));
btAssert(!isnan(lin_vel.getZ()));
m_linearVelocity = lin_vel;
m_linearVelocity = lin_vel;
}
inline void setAngularVelocity(const btVector3& ang_vel)
{
inline void setAngularVelocity(const btVector3& ang_vel)
{
btAssert(!isnan(ang_vel.getX()));
btAssert(!isnan(ang_vel.getY()));
btAssert(!isnan(ang_vel.getZ()));
m_angularVelocity = ang_vel;
m_angularVelocity = ang_vel;
}
btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
@ -410,18 +415,18 @@ public:
// return (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep;
}
void translate(const btVector3& v)
void translate(const btVector3& v)
{
m_worldTransform.getOrigin() += v;
m_worldTransform.getOrigin() += v;
}
void getAabb(btVector3& aabbMin,btVector3& aabbMax) const;
SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btVector3& pos, const btVector3& normal) const
{
btVector3 r0 = pos - getCenterOfMassPosition();
@ -478,12 +483,12 @@ public:
}
const btBroadphaseProxy* getBroadphaseProxy() const
{
return m_broadphaseHandle;
}
btBroadphaseProxy* getBroadphaseProxy()
btBroadphaseProxy* getBroadphaseProxy()
{
return m_broadphaseHandle;
}
@ -567,12 +572,12 @@ public:
return m_deltaAngularVelocity;
}
const btVector3& getPushVelocity() const
const btVector3& getPushVelocity() const
{
return m_pushVelocity;
}
const btVector3& getTurnVelocity() const
const btVector3& getTurnVelocity() const
{
return m_turnVelocity;
}
@ -580,7 +585,7 @@ public:
////////////////////////////////////////////////
///some internal methods, don't use them
btVector3& internalGetDeltaLinearVelocity()
{
return m_deltaLinearVelocity;
@ -600,7 +605,7 @@ public:
{
return m_invMass;
}
btVector3& internalGetPushVelocity()
{
return m_pushVelocity;
@ -640,7 +645,7 @@ public:
m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
}
}
void internalWritebackVelocity()
{
if (m_inverseMass)
@ -656,7 +661,7 @@ public:
void internalWritebackVelocity(btScalar timeStep);
///////////////////////////////////////////////
@ -679,7 +684,7 @@ struct btRigidBodyFloatData
btVector3FloatData m_angularVelocity;
btVector3FloatData m_angularFactor;
btVector3FloatData m_linearFactor;
btVector3FloatData m_gravity;
btVector3FloatData m_gravity;
btVector3FloatData m_gravity_acceleration;
btVector3FloatData m_invInertiaLocal;
btVector3FloatData m_totalForce;
@ -705,7 +710,7 @@ struct btRigidBodyDoubleData
btVector3DoubleData m_angularVelocity;
btVector3DoubleData m_angularFactor;
btVector3DoubleData m_linearFactor;
btVector3DoubleData m_gravity;
btVector3DoubleData m_gravity;
btVector3DoubleData m_gravity_acceleration;
btVector3DoubleData m_invInertiaLocal;
btVector3DoubleData m_totalForce;

View File

@ -21,6 +21,10 @@ add_library(enet STATIC
win32.c
)
if(MINGW)
target_link_libraries(enet wsock32 ws2_32 Winmm)
endif()
#if(WIN32)
# find_library(WS2_LIBRARY NAMES "ws2_32" PATHS "C:/Windows/System32")
# target_link_libraries(enet ${WS2_LIBRARY})

View File

@ -16,6 +16,9 @@ add_definitions(-DNDEBUG=1 -DIRRLICHT_EXPORTS=1 -DPNG_THREAD_UNSAFE_OK -DPNG_NO_
if(MSVC)
add_definitions(/D_IRR_STATIC_LIB_)
add_definitions(/D_CRT_SECURE_NO_WARNINGS) # Shut up about unsafe stuff
elseif(MINGW)
add_definitions(-D_IRR_STATIC_LIB_)
add_definitions(-D_CRT_SECURE_NO_WARNINGS) # Shut up about unsafe stuff
else()
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include")
@ -766,16 +769,16 @@ if(APPLE)
source/Irrlicht/MacOSX/AppDelegate.mm
source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm
source/Irrlicht/MacOSX/OSXClipboard.mm)
#list(APPEND CMAKE_C_SOURCE_FILE_EXTENSIONS mm)
#set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS cpp)
set_source_files_properties(source/Irrlicht/MacOSX/AppDelegate.mm PROPERTIES COMPILE_FLAGS "-x objective-c++ -O3 -fno-rtti")
set_source_files_properties(source/Irrlicht/MacOSX/AppDelegate.mm PROPERTIES LANGUAGE C)
set_source_files_properties(source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm PROPERTIES COMPILE_FLAGS "-x objective-c++ -O3 -fno-rtti")
set_source_files_properties(source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm PROPERTIES LANGUAGE C)
set_source_files_properties(source/Irrlicht/MacOSX/OSXClipboard.mm PROPERTIES COMPILE_FLAGS "-x objective-c++ -O3 -fno-rtti")
set_source_files_properties(source/Irrlicht/MacOSX/OSXClipboard.mm PROPERTIES LANGUAGE C)
endif()

View File

@ -464,9 +464,9 @@ namespace UserConfigParams
PARAM_PREFIX BoolUserConfigParam m_gi
PARAM_DEFAULT(BoolUserConfigParam(false, "enable_gi",
&m_video_group, "Enable Global Illumination"));
PARAM_PREFIX BoolUserConfigParam m_bindless_textures
PARAM_DEFAULT(BoolUserConfigParam(false, "enable_bindless_textures",
&m_video_group, "Enable Bindless Texture (Experimental !)"));
PARAM_PREFIX BoolUserConfigParam m_azdo
PARAM_DEFAULT(BoolUserConfigParam(false, "enable_azdo",
&m_video_group, "Enable 'Approaching Zero Driver Overhead' mode (very experimental !)"));
// ---- Debug - not saved to config file
/** If gamepad debugging is enabled. */

View File

@ -24,7 +24,6 @@
#include "audio/music_manager.hpp"
#include "config/user_config.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/rain.hpp"
#include "io/xml_node.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/explosion_animation.hpp"
@ -52,7 +51,6 @@ Camera::Camera(int camera_index, AbstractKart* kart) : m_kart(NULL)
{
m_mode = CM_NORMAL;
m_index = camera_index;
m_rain = NULL;
m_original_kart = kart;
m_camera = irr_driver->addCameraSceneNode();
@ -92,7 +90,6 @@ Camera::Camera(int camera_index, AbstractKart* kart) : m_kart(NULL)
*/
Camera::~Camera()
{
if(m_rain) delete m_rain;
irr_driver->removeCameraSceneNode(m_camera);
if (s_active_camera == this)
@ -222,13 +219,6 @@ void Camera::setupCamera()
m_camera->setFOV(m_fov);
m_camera->setAspectRatio(m_aspect);
m_camera->setFarValue(World::getWorld()->getTrack()->getCameraFar());
if (UserConfigParams::m_weather_effects &&
World::getWorld()->getTrack()->getWeatherType() == WEATHER_RAIN)
{
m_rain = new Rain(this, NULL);
}
} // setupCamera
// ----------------------------------------------------------------------------
@ -530,12 +520,6 @@ void Camera::update(float dt)
getCameraSettings(&above_kart, &cam_angle, &side_way, &distance, &smoothing);
positionCamera(dt, above_kart, cam_angle, side_way, distance, smoothing);
}
if (UserConfigParams::m_graphical_effects && m_rain)
{
m_rain->setPosition( getCameraSceneNode()->getPosition() );
m_rain->update(dt);
} // UserConfigParams::m_graphical_effects
} // update
// ----------------------------------------------------------------------------

View File

@ -41,7 +41,6 @@ namespace irr
using namespace irr;
class AbstractKart;
class Rain;
/**
* \brief Handles the game camera
@ -120,10 +119,6 @@ private:
/** List of all cameras. */
static std::vector<Camera*> m_all_cameras;
/** Used to show rain graphical effects. */
Rain *m_rain;
/** A class that stores information about the different end cameras
* which can be specified in the scene.xml file. */
class EndCameraInformation

View File

@ -73,6 +73,7 @@ extern PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex;
extern PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
extern PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex;
extern PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glDrawElementsInstancedBaseVertexBaseInstance;
extern PFNGLDRAWELEMENTSINDIRECTPROC glDrawElementsIndirect;
extern PFNGLMULTIDRAWELEMENTSINDIRECTPROC glMultiDrawElementsIndirect;
extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
@ -129,6 +130,18 @@ extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
#ifdef WIN32
#define Bindless_Texture_Support
#define Base_Instance_Support
#define Buffer_Storage
#define Multi_Draw_Indirect
#define Draw_Indirect
#endif
struct DrawElementsIndirectCommand{
GLuint count;
GLuint instanceCount;
GLuint firstIndex;
GLuint baseVertex;
GLuint baseInstance;
};
#endif

View File

@ -54,6 +54,7 @@ PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex;
PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex;
PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glDrawElementsInstancedBaseVertexBaseInstance;
PFNGLDRAWELEMENTSINDIRECTPROC glDrawElementsIndirect;
PFNGLMULTIDRAWELEMENTSINDIRECTPROC glMultiDrawElementsIndirect;
PFNGLDELETEBUFFERSPROC glDeleteBuffers;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
@ -121,9 +122,11 @@ CALLBACK
debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar* msg, const void *userparam)
{
#ifdef GL_DEBUG_SEVERITY_NOTIFICATION
// ignore minor notifications sent by some drivers (notably the nvidia one)
if (severity == GL_DEBUG_SEVERITY_NOTIFICATION)
return;
#endif
switch(source)
{
@ -245,6 +248,7 @@ void initGL()
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawElementsInstanced");
glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)IRR_OGL_LOAD_EXTENSION("glDrawElementsInstancedBaseVertex");
glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)IRR_OGL_LOAD_EXTENSION("glDrawElementsInstancedBaseVertexBaseInstance");
glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC)IRR_OGL_LOAD_EXTENSION("glDrawElementsIndirect");
glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC)IRR_OGL_LOAD_EXTENSION("glMultiDrawElementsIndirect");
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteBuffers");
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)IRR_OGL_LOAD_EXTENSION("glGenVertexArrays");
@ -320,7 +324,7 @@ GLuint LoadShader(const char * file, unsigned type)
char versionString[20];
sprintf(versionString, "#version %d\n", irr_driver->getGLSLVersion());
std::string Code = versionString;
if (UserConfigParams::m_bindless_textures)
if (UserConfigParams::m_azdo)
Code += "#extension GL_ARB_bindless_texture : enable\n";
else
{
@ -333,6 +337,8 @@ GLuint LoadShader(const char * file, unsigned type)
Code += "#define UBO_DISABLED\n";
if (irr_driver->hasVSLayerExtension())
Code += "#define VSLayer\n";
if (irr_driver->needsRGBBindlessWorkaround())
Code += "#define SRGBBindlessFix\n";
Code += LoadHeader();
if (Stream.is_open())
{
@ -595,9 +601,22 @@ VAOManager::VAOManager()
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);
for (unsigned i = 0; i < InstanceTypeCount; i++)
{
glGenBuffers(1, &instance_vbo[i]);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[i]);
#ifdef Buffer_Storage
if (irr_driver->hasBufferStorageExtension())
{
glBufferStorage(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
Ptr[i] = glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
}
else
#endif
{
glBufferData(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_STREAM_DRAW);
}
}
}
static void cleanVAOMap(std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> Map)
@ -612,9 +631,7 @@ static void cleanVAOMap(std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>,
void VAOManager::cleanInstanceVAOs()
{
cleanVAOMap(InstanceVAO);
cleanVAOMap(ShadowInstanceVAO);
InstanceVAO.clear();
ShadowInstanceVAO.clear();
}
VAOManager::~VAOManager()
@ -633,7 +650,11 @@ VAOManager::~VAOManager()
if (vao[i])
glDeleteVertexArrays(1, &vao[i]);
}
glDeleteBuffers(1, &instance_vbo[0]);
for (unsigned i = 0; i < InstanceTypeCount; i++)
{
glDeleteBuffers(1, &instance_vbo[i]);
}
}
void VAOManager::regenerateBuffer(enum VTXTYPE tp)
@ -643,7 +664,16 @@ void VAOManager::regenerateBuffer(enum VTXTYPE tp)
glDeleteBuffers(1, &vbo[tp]);
glGenBuffers(1, &vbo[tp]);
glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]);
glBufferData(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_DYNAMIC_DRAW);
#ifdef Buffer_Storage
if (irr_driver->hasBufferStorageExtension())
{
glBufferStorage(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
VBOPtr[tp] = glMapBufferRange(GL_ARRAY_BUFFER, 0, vtx_cnt[tp] * getVertexPitch(tp), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
}
else
#endif
glBufferData(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_DYNAMIC_DRAW);
if (ibo[tp])
glDeleteBuffers(1, &ibo[tp]);
@ -728,13 +758,11 @@ void VAOManager::regenerateInstancedVAO()
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]);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeDefault]);
glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
@ -751,29 +779,65 @@ void VAOManager::regenerateInstancedVAO()
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;
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeDefault)] = vao;
GLuint shadow_vao = createVAO(vbo[tp], ibo[tp], tp);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[j]);
vao = createVAO(vbo[tp], ibo[tp], tp);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeShadow]);
glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
glVertexAttribDivisor(7, 4);
glVertexAttribDivisor(7, 1);
glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(8, 4);
glVertexAttribDivisor(8, 1);
glEnableVertexAttribArray(9);
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(9, 4);
glVertexAttribDivisor(9, 1);
glEnableVertexAttribArray(10);
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
glVertexAttribDivisor(10, 4);
glVertexAttribDivisor(10, 1);
glEnableVertexAttribArray(11);
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)+2 * sizeof(unsigned)));
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;
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeShadow)] = vao;
vao = createVAO(vbo[tp], ibo[tp], tp);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeRSM]);
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, InstanceTypeRSM)] = vao;
vao = createVAO(vbo[tp], ibo[tp], tp);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeGlow]);
glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), 0);
glVertexAttribDivisor(7, 1);
glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(8, 1);
glEnableVertexAttribArray(9);
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(9, 1);
glEnableVertexAttribArray(12);
glVertexAttribPointer(12, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(GlowInstanceData), (GLvoid*)(9 * sizeof(float)));
glVertexAttribDivisor(12, 1);
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeGlow)] = vao;
glBindVertexArray(0);
}
}

View File

@ -142,6 +142,9 @@ void saveCompressedTexture(const std::string& compressed_tex);
enum InstanceType
{
InstanceTypeDefault,
InstanceTypeShadow,
InstanceTypeRSM,
InstanceTypeGlow,
InstanceTypeCount,
};
@ -172,22 +175,53 @@ struct InstanceData
uint64_t SecondTexture;
#ifdef WIN32
};
#pragma pack(pop)
#else
} __attribute__((packed));
#endif
struct GlowInstanceData
{
struct
{
float X;
float Y;
float Z;
} Origin;
struct
{
float X;
float Y;
float Z;
} Orientation;
struct
{
float X;
float Y;
float Z;
} Scale;
unsigned Color;
#ifdef WIN32
};
#else
} __attribute__((packed));
#endif
#ifdef WIN32
#pragma pack(pop)
#endif
class VAOManager : public Singleton<VAOManager>
{
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];
GLuint instance_vbo[InstanceTypeCount];
size_t instance_count[InstanceTypeCount];
void *Ptr[InstanceTypeCount];
void *VBOPtr[VTXTYPE_COUNT];
std::vector<scene::IMeshBuffer *> storedCPUBuffer[VTXTYPE_COUNT];
void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[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<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> InstanceVAO, ShadowInstanceVAO;
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> InstanceVAO;
void cleanInstanceVAOs();
void regenerateBuffer(enum VTXTYPE);
@ -200,10 +234,12 @@ public:
VAOManager();
std::pair<unsigned, unsigned> getBase(scene::IMeshBuffer *);
size_t appendInstance(enum InstanceType, const std::vector<InstanceData> &instance_data);
GLuint getInstanceBuffer(InstanceType it) { return instance_vbo[it]; }
void *getInstanceBufferPtr(InstanceType it) { return Ptr[it]; }
unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; }
void *getVBOPtr(video::E_VERTEX_TYPE type) { return VBOPtr[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();
};

View File

@ -449,6 +449,12 @@ void ParticleSystemProxy::render() {
draw();
}
bool ParticleSystemProxy::update()
{
doParticleSystem(os::Timer::getTime());
return (IsVisible && (Particles.size() != 0));
}
void ParticleSystemProxy::OnRegisterSceneNode()
{
doParticleSystem(os::Timer::getTime());

View File

@ -81,6 +81,7 @@ public:
const float* getColorTo() const { return m_color_to; }
void setHeightmap(const std::vector<std::vector<float> >&, float, float, float, float);
void setFlip();
bool update();
};
#endif // GPUPARTICLES_H

View File

@ -166,6 +166,11 @@ void IrrDriver::IncreaseObjectCount()
object_count[m_phase]++;
}
void IrrDriver::IncreasePolyCount(unsigned Polys)
{
poly_count[m_phase] += Polys;
}
core::array<video::IRenderTarget> &IrrDriver::getMainSetup()
{
return m_mrt;
@ -470,6 +475,7 @@ void IrrDriver::initDevice()
m_need_ubo_workaround = false;
m_need_rh_workaround = false;
m_need_srgb_workaround = false;
#ifdef WIN32
// Fix for Intel Sandy Bridge on Windows which supports GL up to 3.1 only
if (strstr((const char *)glGetString(GL_VENDOR), "Intel") != NULL && (GLMajorVersion == 3 && GLMinorVersion == 1))
@ -478,12 +484,18 @@ void IrrDriver::initDevice()
// Fix for Nvidia and instanced RH
if (strstr((const char *)glGetString(GL_VENDOR), "NVIDIA") != NULL)
m_need_rh_workaround = true;
// Fix for AMD and bindless sRGB textures
if (strstr((const char *)glGetString(GL_VENDOR), "ATI") != NULL)
m_need_srgb_workaround = true;
}
m_glsl = (GLMajorVersion > 3 || (GLMajorVersion == 3 && GLMinorVersion >= 1));
// Parse extensions
hasVSLayer = false;
hasBaseInstance = false;
hasBuffserStorage = false;
hasDrawIndirect = false;
// Default false value for hasVSLayer if --no-graphics argument is used
if (!ProfileWorld::isNoGraphics())
{
@ -491,11 +503,23 @@ void IrrDriver::initDevice()
hasVSLayer = true;
Log::info("GLDriver", "AMD Vertex Shader Layer enabled");
}
#ifdef Buffer_Storage
if (hasGLExtension("GL_ARB_buffer_storage")) {
hasBuffserStorage = true;
Log::info("GLDriver", "ARB Buffer Storage enabled");
}
#endif
#ifdef Base_Instance_Support
if (hasGLExtension("GL_ARB_base_instance")) {
hasBaseInstance = true;
Log::info("GLDriver", "ARB Instance enabled");
}
#endif
#ifdef Draw_Indirect
if (hasGLExtension("GL_ARB_draw_indirect")) {
hasDrawIndirect = true;
Log::info("GLDriver", "ARB Draw Indirect enabled");
}
#endif
}
@ -1612,6 +1636,7 @@ video::ITexture* IrrDriver::applyMask(video::ITexture* texture,
// ----------------------------------------------------------------------------
void IrrDriver::setRTT(RTT* rtt)
{
memset(m_shadow_camnodes, 0, 4 * sizeof(void*));
m_rtts = rtt;
}
// ----------------------------------------------------------------------------
@ -1714,13 +1739,14 @@ void IrrDriver::displayFPS()
if (UserConfigParams::m_artist_debug_mode)
{
sprintf(
buffer, "FPS: %i/%i/%i - Objects (P1:%d P2:%d T:%d) - LightDst : ~%d",
buffer, "FPS: %i/%i/%i - PolyCount (Solid:%d Shadows:%d) - LightDst : ~%d",
min, fps, max,
object_count[SOLID_NORMAL_AND_DEPTH_PASS],
object_count[SOLID_NORMAL_AND_DEPTH_PASS],
object_count[TRANSPARENT_PASS],
poly_count[SOLID_NORMAL_AND_DEPTH_PASS],
poly_count[SHADOW_PASS],
m_last_light_bucket_distance
);
poly_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
poly_count[SHADOW_PASS] = 0;
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
object_count[TRANSPARENT_PASS] = 0;
@ -2425,8 +2451,8 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy,
if (sun)
{
m_sun_interposer->setPosition(pos);
m_sun_interposer->updateAbsolutePosition();
//m_sun_interposer->setPosition(pos);
//m_sun_interposer->updateAbsolutePosition();
m_lensflare->setPosition(pos);
m_lensflare->updateAbsolutePosition();

View File

@ -112,6 +112,7 @@ enum QueryPerf
{
Q_SOLID_PASS1,
Q_SHADOWS,
Q_RSM,
Q_RH,
Q_GI,
Q_ENVMAP,
@ -200,8 +201,12 @@ private:
int GLMajorVersion, GLMinorVersion;
bool hasVSLayer;
bool hasBaseInstance;
bool hasDrawIndirect;
bool hasBuffserStorage;
bool m_need_ubo_workaround;
bool m_need_rh_workaround;
bool m_need_srgb_workaround;
GLsync m_sync;
/** The irrlicht device. */
IrrlichtDevice *m_device;
/** Irrlicht scene manager. */
@ -294,16 +299,31 @@ public:
return m_need_rh_workaround;
}
bool needsRGBBindlessWorkaround() const
{
return m_need_srgb_workaround;
}
bool hasARB_base_instance() const
{
return hasBaseInstance;
}
bool hasARB_draw_indirect() const
{
return hasDrawIndirect;
}
bool hasVSLayerExtension() const
{
return hasVSLayer;
}
bool hasBufferStorageExtension() const
{
return hasBuffserStorage;
}
video::SColorf getAmbientLight() const;
struct GlowData {
@ -341,12 +361,14 @@ private:
/** Performance stats */
unsigned m_last_light_bucket_distance;
unsigned object_count[PASS_COUNT];
unsigned poly_count[PASS_COUNT];
u32 m_renderpass;
u32 m_lensflare_query;
bool m_query_issued;
class STKMeshSceneNode *m_sun_interposer;
scene::CLensFlareSceneNode *m_lensflare;
scene::ICameraSceneNode *m_suncam;
scene::ICameraSceneNode *m_shadow_camnodes[4];
float m_shadows_cam[4][24];
std::vector<GlowData> m_glowing;
@ -388,6 +410,7 @@ private:
void renderLights(unsigned pointlightCount);
void renderShadowsDebug();
void doScreenShot();
void PrepareDrawCalls(scene::ICameraSceneNode *camnode);
public:
IrrDriver();
~IrrDriver();
@ -403,6 +426,7 @@ public:
return sun_ortho_matrix;
}
void IncreaseObjectCount();
void IncreasePolyCount(unsigned);
core::array<video::IRenderTarget> &getMainSetup();
void updateConfigIfRelevant();
void setAllMaterialFlags(scene::IMesh *mesh) const;

View File

@ -137,19 +137,24 @@ void LODNode::OnAnimate(u32 timeMs)
}
}
void LODNode::OnRegisterSceneNode()
void LODNode::updateVisibility(bool* shown)
{
if (!isVisible()) return;
if (m_nodes.size() == 0) return;
bool shown = false;
int level = getLevel();
if (level>=0)
for (int i = 0; i < m_nodes.size(); i++)
{
m_nodes[level]->updateAbsolutePosition();
m_nodes[level]->OnRegisterSceneNode();
shown = true;
m_nodes[i]->setVisible(i == level);
if (i == level && shown != NULL)
*shown = level;
}
}
void LODNode::OnRegisterSceneNode()
{
bool shown;
updateVisibility(&shown);
const u32 now = irr_driver->getDevice()->getTimer()->getTime();
@ -158,6 +163,7 @@ void LODNode::OnRegisterSceneNode()
m_nodes[0]->getType() == scene::ESNT_ANIMATED_MESH) &&
now > m_last_tick)
{
int level = getLevel();
if (m_previous_visibility == WAS_HIDDEN && shown)
{
scene::IMesh* mesh;
@ -254,20 +260,7 @@ void LODNode::OnRegisterSceneNode()
m_previous_visibility = (shown ? WAS_SHOWN : WAS_HIDDEN);
m_last_tick = now;
// If this node has children other than the LOD nodes, draw them
core::list<ISceneNode*>::Iterator it;
for (it = Children.begin(); it != Children.end(); it++)
{
if (m_nodes_set.find(*it) == m_nodes_set.end())
{
assert(*it != NULL);
if ((*it)->isVisible())
{
(*it)->OnRegisterSceneNode();
}
}
}
scene::ISceneNode::OnRegisterSceneNode();
}
void LODNode::add(int level, scene::ISceneNode* node, bool reparent)

View File

@ -83,6 +83,8 @@ public:
int getLevel();
void updateVisibility(bool* shown = NULL);
/*
//! Returns a reference to the current relative transformation matrix.
//! This is the matrix, this scene node uses instead of scale, translation

View File

@ -608,8 +608,10 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
if (World::getWorld() != NULL)
hasgodrays = World::getWorld()->getTrack()->hasGodRays();
if (isRace && UserConfigParams::m_light_shaft && m_sunpixels > 30 && hasgodrays)
if (isRace && UserConfigParams::m_light_shaft && hasgodrays)
{
Track* track = World::getWorld()->getTrack();
glEnable(GL_DEPTH_TEST);
// Grab the sky
out_fbo->Bind();
@ -617,12 +619,14 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
irr_driver->renderSkybox(camnode);
// Set the sun's color
const SColor col = World::getWorld()->getTrack()->getSunColor();
const SColor col = track->getGodRaysColor();
ColorizeProvider * const colcb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE);
colcb->setColor(col.getRed() / 255.0f, col.getGreen() / 255.0f, col.getBlue() / 255.0f);
// The sun interposer
STKMeshSceneNode *sun = irr_driver->getSunInterposer();
sun->setPosition(track->getGodRaysPosition());
sun->updateAbsolutePosition();
irr_driver->getSceneManager()->drawAll(ESNRP_CAMERA);
irr_driver->setPhase(GLOW_PASS);
sun->render();
@ -637,7 +641,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER1), irr_driver->getFBO(FBO_QUARTER2));
// Calculate the sun's position in texcoords
const core::vector3df pos = sun->getPosition();
const core::vector3df pos = track->getGodRaysPosition();
float ndc[4];
core::matrix4 trans = camnode->getProjectionMatrix();
trans *= camnode->getViewMatrix();

View File

@ -34,7 +34,6 @@
#include "graphics/screenquad.hpp"
#include "graphics/shaders.hpp"
#include "graphics/stkmeshscenenode.hpp"
#include "graphics/stkinstancedscenenode.hpp"
#include "graphics/wind.hpp"
#include "io/file_manager.hpp"
#include "items/item.hpp"
@ -47,6 +46,7 @@
#include "utils/helpers.hpp"
#include "utils/log.hpp"
#include "utils/profiler.hpp"
#include "stkscenemanager.hpp"
#include <algorithm>
#include <limits>
@ -272,22 +272,30 @@ void IrrDriver::renderGLSL(float dt)
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadow, bool forceRTT)
{
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
m_scene_manager->setActiveCamera(camnode);
PROFILER_PUSH_CPU_MARKER("- Draw Call Generation", 0xFF, 0xFF, 0xFF);
PrepareDrawCalls(camnode);
PROFILER_POP_CPU_MARKER();
// Shadows
{
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS));
// To avoid wrong culling, use the largest view possible
m_scene_manager->setActiveCamera(m_suncam);
if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights &&
UserConfigParams::m_shadows && !irr_driver->needUBOWorkaround() && hasShadow)
{
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
renderShadows();
PROFILER_POP_CPU_MARKER();
if (UserConfigParams::m_gi)
{
PROFILER_PUSH_CPU_MARKER("- RSM", 0xFF, 0x0, 0xFF);
renderRSM();
PROFILER_POP_CPU_MARKER();
}
}
m_scene_manager->setActiveCamera(camnode);
PROFILER_POP_CPU_MARKER();
}
PROFILER_PUSH_CPU_MARKER("- Solid Pass 1", 0xFF, 0x00, 0x00);
@ -323,6 +331,8 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
renderSolidSecondPass();
PROFILER_POP_CPU_MARKER();
m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
if (getNormals())
{
m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind();
@ -514,7 +524,9 @@ void IrrDriver::renderParticles()
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT);
for (unsigned i = 0; i < ParticlesList::getInstance()->size(); ++i)
ParticlesList::getInstance()->at(i)->render();
// m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT);
}
/** Given a matrix transform and a set of points returns an orthogonal projection matrix that maps coordinates of
@ -593,6 +605,11 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
memcpy(&tmp[48], irr_driver->getInvProjMatrix().pointer(), 16 * sizeof(float));
const core::matrix4 &SunCamViewMatrix = m_suncam->getViewMatrix();
for (unsigned i = 0; i < 4; i++)
{
if (!m_shadow_camnodes[i])
m_shadow_camnodes[i] = (scene::ICameraSceneNode *) m_suncam->clone();
}
sun_ortho_matrix.clear();
if (World::getWorld() && World::getWorld()->getTrack())
@ -670,8 +687,8 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
const float units_per_w = w / 1024;
const float units_per_h = h / 1024;*/
m_suncam->setProjectionMatrix(getTighestFitOrthoProj(SunCamViewMatrix, vectors) , true);
m_suncam->render();
m_shadow_camnodes[i]->setProjectionMatrix(getTighestFitOrthoProj(SunCamViewMatrix, vectors) , true);
m_shadow_camnodes[i]->render();
sun_ortho_matrix.push_back(getVideoDriver()->getTransform(video::ETS_PROJECTION) * getVideoDriver()->getTransform(video::ETS_VIEW));
}
@ -703,6 +720,7 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
assert(sun_ortho_matrix.size() == 4);
camnode->setNearValue(oldnear);
camnode->setFarValue(oldfar);
camnode->render();
size_t size = irr_driver->getShadowViewProj().size();
for (unsigned i = 0; i < size; i++)
@ -768,20 +786,40 @@ void IrrDriver::renderGlow(std::vector<GlowData>& glows)
glDepthMask(GL_FALSE);
glDisable(GL_BLEND);
glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_STANDARD));
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_STANDARD));
for (u32 i = 0; i < glowcount; i++)
{
const GlowData &dat = glows[i];
scene::ISceneNode * const cur = dat.node;
scene::ISceneNode * cur = dat.node;
//TODO : implement culling on gpu
// Quick box-based culling
// const core::aabbox3df nodebox = cur->getTransformedBoundingBox();
// if (!nodebox.intersectsWithBox(cambox))
// continue;
STKMeshSceneNode *node = static_cast<STKMeshSceneNode *>(cur);
node->setGlowColors(SColor(0, dat.b * 255.f, dat.g * 255.f, dat.r * 255.f));
if (!irr_driver->hasARB_draw_indirect())
node->render();
}
cb->setColor(dat.r, dat.g, dat.b);
cur->render();
if (irr_driver->hasARB_draw_indirect())
{
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, GlowPassCmd::getInstance()->drawindirectcmd);
glUseProgram(MeshShader::InstancedColorizeShader::getInstance()->Program);
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeGlow));
if (UserConfigParams::m_azdo)
{
if (GlowPassCmd::getInstance()->Size)
{
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT,
(const void*)(GlowPassCmd::getInstance()->Offset * sizeof(DrawElementsIndirectCommand)),
GlowPassCmd::getInstance()->Size,
sizeof(DrawElementsIndirectCommand));
}
}
else
{
for (unsigned i = 0; i < ListInstancedGlow::getInstance()->size(); i++)
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((GlowPassCmd::getInstance()->Offset + i) * sizeof(DrawElementsIndirectCommand)));
}
}
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,6 @@
#include "graphics/screenquad.hpp"
#include "graphics/shaders.hpp"
#include "graphics/stkmeshscenenode.hpp"
#include "graphics/stkinstancedscenenode.hpp"
#include "graphics/wind.hpp"
#include "io/file_manager.hpp"
#include "items/item.hpp"

View File

@ -16,7 +16,6 @@
#include "graphics/screenquad.hpp"
#include "graphics/shaders.hpp"
#include "graphics/stkmeshscenenode.hpp"
#include "graphics/stkinstancedscenenode.hpp"
#include "graphics/wind.hpp"
#include "io/file_manager.hpp"
#include "items/item.hpp"
@ -449,6 +448,7 @@ GLuint generateCubeMapFromTextures(const std::vector<video::ITexture *> &texture
else
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB_ALPHA, size, size, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
for (unsigned i = 0; i < 6; i++)
delete[] rgba[i];
return result;
@ -553,7 +553,7 @@ void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
return;
if (!SkyboxCubeMap)
generateSkyboxCubemap();
glBindVertexArray(MeshShader::SkyboxShader::cubevao);
glBindVertexArray(MeshShader::SkyboxShader::getInstance()->cubevao);
glDisable(GL_CULL_FACE);
assert(SkyboxTextures.size() == 6);
@ -568,15 +568,10 @@ void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
core::matrix4 invtransform;
transform.getInverse(invtransform);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, SkyboxCubeMap);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glUseProgram(MeshShader::SkyboxShader::Program);
MeshShader::SkyboxShader::setUniforms(transform,
core::vector2df(float(UserConfigParams::m_width),
float(UserConfigParams::m_height)),
0);
glUseProgram(MeshShader::SkyboxShader::getInstance()->Program);
MeshShader::SkyboxShader::getInstance()->setUniforms(transform);
MeshShader::SkyboxShader::getInstance()->SetTextureUnits(createVector<GLuint>(SkyboxCubeMap));
glDrawElements(GL_TRIANGLES, 6 * 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}

View File

@ -115,8 +115,8 @@ RTT::RTT(size_t width, size_t height)
RenderTargetTextures[RTT_MLAA_BLEND] = generateRTT(res, GL_SRGB8_ALPHA8, GL_BGR, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_SSAO] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_DISPLACE] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_DIFFUSE] = generateRTT(res, GL_RGB16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_SPECULAR] = generateRTT(res, GL_RGB16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_DIFFUSE] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_SPECULAR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_HALF1] = generateRTT(half, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_QUARTER1] = generateRTT(quarter, GL_RGBA16F, GL_BGRA, GL_FLOAT);

View File

@ -408,7 +408,6 @@ void Shaders::loadShaders()
initShadowVPMUBO();
initParticleQuadVBO();
MeshShader::BubbleShader::init();
MeshShader::SkyboxShader::init();
MeshShader::ViewFrustrumShader::init();
UtilShader::ColoredLine::init();
}
@ -713,6 +712,20 @@ void BindTextureTrilinearAnisotropic(GLuint TU, GLuint tex)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)aniso);
}
void BindCubemapTrilinear(unsigned TU, unsigned tex)
{
glActiveTexture(GL_TEXTURE0 + TU);
glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
int aniso = UserConfigParams::m_anisotropic;
if (aniso == 0) aniso = 1;
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)aniso);
}
GLuint createShadowSampler()
{
#ifdef GL_VERSION_3_3
@ -931,6 +944,21 @@ namespace MeshShader
AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "Detail");
}
InstancedDetailledObjectPass2Shader::InstancedDetailledObjectPass2Shader()
{
Program = LoadProgram(
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/instanced_detailledobject_pass2.frag").c_str());
AssignUniforms();
AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "Detail");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
ObjectUnlitShader::ObjectUnlitShader()
{
Program = LoadProgram(
@ -944,6 +972,20 @@ namespace MeshShader
AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "tex");
}
InstancedObjectUnlitShader::InstancedObjectUnlitShader()
{
Program = LoadProgram(
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/instanced_object_unlit.frag").c_str());
AssignUniforms();
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "tex");
}
ObjectRefPass2Shader::ObjectRefPass2Shader()
{
Program = LoadProgram(
@ -999,6 +1041,22 @@ namespace MeshShader
AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "tex");
}
InstancedSphereMapShader::InstancedSphereMapShader()
{
Program = LoadProgram(
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/utils/getPosFromUVDepth.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_objectpass_spheremap.frag").c_str());
AssignUniforms();
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "tex");
}
SplattingShader::SplattingShader()
{
Program = LoadProgram(
@ -1092,6 +1150,18 @@ namespace MeshShader
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
InstancedColorizeShader::InstancedColorizeShader()
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/glow_object.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/glow_object.frag").c_str());
AssignUniforms();
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
ShadowShader::ShadowShader()
{
// Geometry shader needed
@ -1110,7 +1180,7 @@ namespace MeshShader
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str());
}
AssignUniforms("ModelMatrix");
AssignUniforms("layer", "ModelMatrix");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
@ -1128,6 +1198,20 @@ namespace MeshShader
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
InstancedRSMShader::InstancedRSMShader()
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_rsm.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_rsm.frag").c_str());
AssignUniforms("RSMMatrix");
AssignSamplerNames(Program, 0, "tex");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
SplattingRSMShader::SplattingRSMShader()
{
Program = LoadProgram(
@ -1161,6 +1245,7 @@ namespace MeshShader
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/instanced_shadow.geom").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str());
}
AssignUniforms("layer");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
@ -1183,7 +1268,7 @@ namespace MeshShader
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str());
}
AssignUniforms("ModelMatrix");
AssignUniforms("layer", "ModelMatrix");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
@ -1210,7 +1295,7 @@ namespace MeshShader
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/instanced_shadow.geom").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_shadowref.frag").c_str());
}
AssignUniforms("layer");
AssignSamplerNames(Program, 0, "tex");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
@ -1234,7 +1319,7 @@ namespace MeshShader
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str());
}
AssignUniforms("ModelMatrix", "windDir");
AssignUniforms("layer", "ModelMatrix", "windDir");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
@ -1264,7 +1349,7 @@ namespace MeshShader
AssignSamplerNames(Program, 0, "tex");
AssignUniforms("windDir");
AssignUniforms("layer", "windDir");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
@ -1297,20 +1382,13 @@ namespace MeshShader
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
GLuint SkyboxShader::Program;
GLuint SkyboxShader::attrib_position;
GLuint SkyboxShader::uniform_MM;
GLuint SkyboxShader::uniform_tex;
GLuint SkyboxShader::cubevao;
void SkyboxShader::init()
SkyboxShader::SkyboxShader()
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/sky.frag").c_str());
attrib_position = glGetAttribLocation(Program, "Position");
uniform_MM = glGetUniformLocation(Program, "ModelMatrix");
uniform_tex = glGetUniformLocation(Program, "tex");
AssignUniforms("ModelMatrix");
AssignSamplerNames(Program, 0, "tex");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
@ -1318,20 +1396,12 @@ namespace MeshShader
glGenVertexArrays(1, &cubevao);
glBindVertexArray(cubevao);
glBindBuffer(GL_ARRAY_BUFFER, SharedObject::cubevbo);
glEnableVertexAttribArray(attrib_position);
glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, SharedObject::cubeindexes);
glBindVertexArray(0);
}
void SkyboxShader::setUniforms(const core::matrix4 &ModelMatrix, const core::vector2df &screen, unsigned TU_tex)
{
if (irr_driver->needUBOWorkaround())
bypassUBO(Program);
glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer());
glUniform1i(uniform_tex, TU_tex);
}
NormalVisualizer::NormalVisualizer()
{
Program = LoadProgram(

View File

@ -186,6 +186,7 @@ enum SamplerType {
Nearest_Filtered,
Shadow_Sampler,
Volume_Linear_Filtered,
Trilinear_cubemap,
};
void setTextureSampler(GLenum, GLuint, GLuint, GLuint);
@ -325,6 +326,29 @@ struct CreateSamplers<Trilinear_Anisotropic_Filtered, tp...>
void BindTextureTrilinearAnisotropic(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct CreateSamplers<Trilinear_cubemap, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createTrilinearSampler());
e.push_back(GL_TEXTURE_CUBE_MAP);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindCubemapTrilinear(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct BindTexture<Trilinear_cubemap, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindCubemapTrilinear(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
template<SamplerType...tp>
struct BindTexture<Trilinear_Anisotropic_Filtered, tp...>
{
@ -389,10 +413,12 @@ class TextureRead
private:
template<unsigned N, typename...Args>
void AssignTextureNames_impl(GLuint)
{}
{
static_assert(N == sizeof...(tp), "Wrong number of texture name");
}
template<unsigned N, typename...Args>
void AssignTextureNames_impl(GLuint Program, GLuint TexUnit, const char *name, Args...args...)
void AssignTextureNames_impl(GLuint Program, GLuint TexUnit, const char *name, Args...args)
{
GLuint location = glGetUniformLocation(Program, name);
TextureLocation.push_back(location);
@ -524,12 +550,24 @@ public:
DetailledObjectPass2Shader();
};
class InstancedDetailledObjectPass2Shader : public ShaderHelperSingleton<InstancedDetailledObjectPass2Shader>, public TextureRead<Nearest_Filtered, Nearest_Filtered, Bilinear_Filtered, Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered>
{
public:
InstancedDetailledObjectPass2Shader();
};
class ObjectUnlitShader : public ShaderHelperSingleton<ObjectUnlitShader, core::matrix4, core::matrix4>, public TextureRead<Nearest_Filtered, Nearest_Filtered, Bilinear_Filtered, Trilinear_Anisotropic_Filtered>
{
public:
ObjectUnlitShader();
};
class InstancedObjectUnlitShader : public ShaderHelperSingleton<InstancedObjectUnlitShader>, public TextureRead<Nearest_Filtered, Nearest_Filtered, Bilinear_Filtered, Trilinear_Anisotropic_Filtered>
{
public:
InstancedObjectUnlitShader();
};
class ObjectRefPass2Shader : public ShaderHelperSingleton<ObjectRefPass2Shader, core::matrix4, core::matrix4>, public TextureRead<Nearest_Filtered, Nearest_Filtered, Bilinear_Filtered, Trilinear_Anisotropic_Filtered>
{
public:
@ -554,6 +592,12 @@ public:
SphereMapShader();
};
class InstancedSphereMapShader : public ShaderHelperSingleton<InstancedSphereMapShader>, public TextureRead<Nearest_Filtered, Nearest_Filtered, Bilinear_Filtered, Trilinear_Anisotropic_Filtered>
{
public:
InstancedSphereMapShader();
};
class SplattingShader : public ShaderHelperSingleton<SplattingShader, core::matrix4>, public TextureRead<Nearest_Filtered, Nearest_Filtered, Bilinear_Filtered, Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered>
{
public:
@ -595,7 +639,13 @@ public:
ColorizeShader();
};
class ShadowShader : public ShaderHelperSingleton<ShadowShader, core::matrix4>, public TextureRead<>
class InstancedColorizeShader : public ShaderHelperSingleton<InstancedColorizeShader>
{
public:
InstancedColorizeShader();
};
class ShadowShader : public ShaderHelperSingleton<ShadowShader, int, core::matrix4>, public TextureRead<>
{
public:
ShadowShader();
@ -607,6 +657,12 @@ public:
RSMShader();
};
class InstancedRSMShader : public ShaderHelperSingleton<InstancedRSMShader, core::matrix4>, public TextureRead<Trilinear_Anisotropic_Filtered>
{
public:
InstancedRSMShader();
};
class SplattingRSMShader : public ShaderHelperSingleton<SplattingRSMShader, core::matrix4, core::matrix4>,
public TextureRead<Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered>
{
@ -614,31 +670,31 @@ public:
SplattingRSMShader();
};
class InstancedShadowShader : public ShaderHelperSingleton<InstancedShadowShader>, public TextureRead<>
class InstancedShadowShader : public ShaderHelperSingleton<InstancedShadowShader, int>, public TextureRead<>
{
public:
InstancedShadowShader();
};
class RefShadowShader : public ShaderHelperSingleton<RefShadowShader, core::matrix4>, public TextureRead<Trilinear_Anisotropic_Filtered>
class RefShadowShader : public ShaderHelperSingleton<RefShadowShader, int, core::matrix4>, public TextureRead<Trilinear_Anisotropic_Filtered>
{
public:
RefShadowShader();
};
class InstancedRefShadowShader : public ShaderHelperSingleton<InstancedRefShadowShader>, public TextureRead<Trilinear_Anisotropic_Filtered>
class InstancedRefShadowShader : public ShaderHelperSingleton<InstancedRefShadowShader, int>, public TextureRead<Trilinear_Anisotropic_Filtered>
{
public:
InstancedRefShadowShader();
};
class GrassShadowShader : public ShaderHelperSingleton<GrassShadowShader, core::matrix4, core::vector3df>, public TextureRead<Trilinear_Anisotropic_Filtered>
class GrassShadowShader : public ShaderHelperSingleton<GrassShadowShader, int, core::matrix4, core::vector3df>, public TextureRead<Trilinear_Anisotropic_Filtered>
{
public:
GrassShadowShader();
};
class InstancedGrassShadowShader : public ShaderHelperSingleton<InstancedGrassShadowShader, core::vector3df>, public TextureRead<Trilinear_Anisotropic_Filtered>
class InstancedGrassShadowShader : public ShaderHelperSingleton<InstancedGrassShadowShader, int, core::vector3df>, public TextureRead<Trilinear_Anisotropic_Filtered>
{
public:
InstancedGrassShadowShader();
@ -656,16 +712,11 @@ public:
DisplaceShader();
};
class SkyboxShader
class SkyboxShader : public ShaderHelperSingleton<SkyboxShader, core::matrix4>, public TextureRead<Trilinear_cubemap>
{
public:
static GLuint Program;
static GLuint attrib_position;
static GLuint uniform_MM, uniform_tex;
static GLuint cubevao;
static void init();
static void setUniforms(const core::matrix4 &ModelMatrix, const core::vector2df &screen, unsigned TU_tex);
SkyboxShader();
GLuint cubevao;
};
class NormalVisualizer : public ShaderHelperSingleton<NormalVisualizer, core::matrix4, core::matrix4, video::SColor>

View File

@ -75,12 +75,12 @@ scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, gui::ScalableFon
for (unsigned int i = 0; i < m_chars.size(); i++)
{
core::vector3df char_pos(m_chars[i].m_destRect.UpperLeftCorner.X,
m_chars[i].m_destRect.UpperLeftCorner.Y, 0);
core::vector3df char_pos((float) m_chars[i].m_destRect.UpperLeftCorner.X,
(float) m_chars[i].m_destRect.UpperLeftCorner.Y, 0);
char_pos *= scale;
core::vector3df char_pos2(m_chars[i].m_destRect.LowerRightCorner.X,
m_chars[i].m_destRect.LowerRightCorner.Y, 0);
core::vector3df char_pos2((float)m_chars[i].m_destRect.LowerRightCorner.X,
(float) m_chars[i].m_destRect.LowerRightCorner.Y, 0);
char_pos2 *= scale;
core::dimension2di char_size_i = m_chars[i].m_destRect.getSize();
@ -100,8 +100,8 @@ scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, gui::ScalableFon
buffer = map_itr->second;
}
float tex_width = m_chars[i].m_texture->getSize().Width;
float tex_height = m_chars[i].m_texture->getSize().Height;
float tex_width = (float) m_chars[i].m_texture->getSize().Width;
float tex_height = (float)m_chars[i].m_texture->getSize().Height;
video::S3DVertex vertices[] =

View File

@ -33,6 +33,15 @@ void STKAnimatedMesh::cleanGLMeshes()
glDeleteVertexArrays(1, &(mesh.vao));
glDeleteBuffers(1, &(mesh.vertex_buffer));
glDeleteBuffers(1, &(mesh.index_buffer));
if (mesh.instance_buffer)
glDeleteBuffers(1, &(mesh.instance_buffer));
#ifdef Bindless_Texture_Support
for (unsigned j = 0; j < 6; j++)
{
if (mesh.TextureHandles[j] && glIsTextureHandleResidentARB(mesh.TextureHandles[j]))
glMakeTextureHandleNonResidentARB(mesh.TextureHandles[j]);
}
#endif
}
}
@ -45,21 +54,13 @@ void STKAnimatedMesh::setMesh(scene::IAnimatedMesh* mesh)
CAnimatedMeshSceneNode::setMesh(mesh);
}
void STKAnimatedMesh::render()
void STKAnimatedMesh::update()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
bool isTransparentPass =
SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
++PassCount;
scene::IMesh* m = getMeshForCurrentFrame();
if (m)
{
Box = m->getBoundingBox();
}
else
{
Log::error("animated mesh", "Animated Mesh returned no mesh to render.");
@ -99,11 +100,21 @@ void STKAnimatedMesh::render()
{
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
MeshSolidMaterial[MatType].push_back(&mesh);
InitTextures(mesh, MatType);
}
if (irr_driver->hasARB_base_instance())
{
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
mesh.vaoBaseVertex = p.first;
mesh.vaoOffset = p.second;
}
else
{
fillLocalBuffer(mesh, mb);
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
glBindVertexArray(0);
}
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
mesh.vaoBaseVertex = p.first;
mesh.vaoOffset = p.second;
mesh.VAOType = mb->getVertexType();
}
}
firstTime = false;
@ -114,31 +125,47 @@ void STKAnimatedMesh::render()
const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
if (isObject(material.MaterialType))
{
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == TRANSPARENT_PASS)
size_t size = mb->getVertexCount() * GLmeshes[i].Stride, offset = GLmeshes[i].vaoBaseVertex * GLmeshes[i].Stride;
void *buf;
if (irr_driver->hasBufferStorageExtension())
{
buf = VAOManager::getInstance()->getVBOPtr(mb->getVertexType());
buf = (char *)buf + offset;
}
else
{
glBindVertexArray(0);
size_t size = mb->getVertexCount() * GLmeshes[i].Stride;
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getVBO(mb->getVertexType()));
if (irr_driver->hasARB_base_instance())
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getVBO(mb->getVertexType()));
else
glBindBuffer(GL_ARRAY_BUFFER, GLmeshes[i].vertex_buffer);
GLbitfield bitfield = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
void * buf = glMapBufferRange(GL_ARRAY_BUFFER, GLmeshes[i].vaoBaseVertex * GLmeshes[i].Stride, size, bitfield);
memcpy(buf, mb->getVertices(), size);
buf = glMapBufferRange(GL_ARRAY_BUFFER, offset, size, bitfield);
}
memcpy(buf, mb->getVertices(), size);
if (!irr_driver->hasBufferStorageExtension())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
if (mb)
GLmeshes[i].TextureMatrix = getMaterial(i).getTextureMatrix(0);
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
bool transparent = (rnd && rnd->isTransparent());
// only render transparent buffer if this is the transparent render pass
// and solid only in solid pass
if (transparent != isTransparentPass)
continue;
}
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
}
void STKAnimatedMesh::render()
{
bool isTransparentPass =
SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
++PassCount;
update();
/* if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
{
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
core::matrix4 invmodel;
@ -146,19 +173,19 @@ void STKAnimatedMesh::render()
GLMesh* mesh;
for_in(mesh, MeshSolidMaterial[MAT_DEFAULT])
pushVector(AnimatedListMatDefault::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
pushVector(ListMatDefault::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterial[MAT_ALPHA_REF])
pushVector(AnimatedListMatAlphaRef::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
pushVector(ListMatAlphaRef::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterial[MAT_DETAIL])
pushVector(AnimatedListMatDetails::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
pushVector(ListMatDetails::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterial[MAT_UNLIT])
pushVector(AnimatedListMatUnlit::getInstance(), mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY, mesh->TextureMatrix);
pushVector(ListMatUnlit::getInstance(), mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY, mesh->TextureMatrix);
return;
}
}*/
if (irr_driver->getPhase() == TRANSPARENT_PASS)
{

View File

@ -7,16 +7,15 @@
#include "graphics/stkmesh.hpp"
#include "utils/ptr_vector.hpp"
class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode
class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode, public STKMeshCommon
{
protected:
bool firstTime;
PtrVector<GLMesh, REF> MeshSolidMaterial[MAT_COUNT];
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix;
void cleanGLMeshes();
public:
virtual void update();
STKAnimatedMesh(irr::scene::IAnimatedMesh* mesh, irr::scene::ISceneNode* parent,
irr::scene::ISceneManager* mgr, irr::s32 id,
const irr::core::vector3df& position = irr::core::vector3df(0,0,0),
@ -25,6 +24,7 @@ public:
virtual void render();
virtual void setMesh(irr::scene::IAnimatedMesh* mesh);
virtual bool glow() const { return false; }
};
#endif // STKANIMATEDMESH_HPP

View File

@ -1,227 +0,0 @@
#include "stkinstancedscenenode.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/callbacks.hpp"
STKInstancedSceneNode::STKInstancedSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
const irr::core::vector3df& position,
const irr::core::vector3df& rotation,
const irr::core::vector3df& scale) :
CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
{
m_ref_count = 0;
irr_driver->grabAllTextures(mesh);
if (irr_driver->isGLSL())
{
createGLMeshes();
setAutomaticCulling(0);
}
}
void STKInstancedSceneNode::cleanGL()
{
for (u32 i = 0; i < GLmeshes.size(); ++i)
{
GLMesh mesh = GLmeshes[i];
if (!mesh.vertex_buffer)
continue;
if (mesh.vao)
glDeleteVertexArrays(1, &(mesh.vao));
if (mesh.vao_shadow_pass)
glDeleteVertexArrays(1, &(mesh.vao_shadow_pass));
glDeleteBuffers(1, &(mesh.vertex_buffer));
glDeleteBuffers(1, &(mesh.index_buffer));
}
glDeleteBuffers(1, &instances_vbo);
}
STKInstancedSceneNode::~STKInstancedSceneNode()
{
irr_driver->dropAllTextures(getMesh());
irr_driver->removeMeshFromCache(getMesh());
if (irr_driver->isGLSL())
cleanGL();
}
void STKInstancedSceneNode::createGLMeshes()
{
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
GLmeshes.push_back(allocateMeshBuffer(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;
}
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));
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, 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, 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);
}
}
void STKInstancedSceneNode::setFirstTimeMaterial()
{
if (isMaterialInitialized)
return;
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
if (!mb)
continue;
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
GLMesh &mesh = GLmeshes[i];
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
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;
}
void STKInstancedSceneNode::addInstance(const core::vector3df &origin, const core::vector3df &orientation, const core::vector3df &scale)
{
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;
const InstanceData &instance = instanceData[0][id];
mat.setTranslation(core::vector3df(
instance.Origin.X,
instance.Origin.Y,
instance.Origin.Z));
mat.setRotationDegrees(core::vector3df(
instance.Orientation.X,
instance.Orientation.Y,
instance.Orientation.Z));
mat.setScale(core::vector3df(
instance.Scale.X,
instance.Scale.Y,
instance.Scale.Z));
return mat;
}
void STKInstancedSceneNode::render()
{
if (!irr_driver->isGLSL())
{
CMeshSceneNode::render();
return;
}
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++)
{
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, 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, instanceData[0].size(), windDir, cb->getPosition()));
}
for (unsigned i = 0; i < MeshSolidMaterial[MAT_NORMAL_MAP].size(); i++)
{
GLMesh *mesh = MeshSolidMaterial[MAT_NORMAL_MAP][i];
ListInstancedMatNormalMap::getInstance()->push_back(STK::make_tuple(mesh, instanceData[0].size()));
}
}
}

View File

@ -1,60 +0,0 @@
#ifndef STKINSTANCEDSCENENODE_HPP
#define STKINSTANCEDSCENENODE_HPP
#include "stkmesh.hpp"
#include "utils/leak_check.hpp"
class ListInstancedMatDefault : public MeshList<ListInstancedMatDefault, GLMesh *, size_t>
{};
class ListInstancedMatAlphaRef : public MeshList<ListInstancedMatAlphaRef, GLMesh *, size_t>
{};
class ListInstancedMatGrass : public MeshList<ListInstancedMatGrass, GLMesh *, size_t, core::vector3df, core::vector3df>
{};
class ListInstancedMatNormalMap : public MeshList<ListInstancedMatNormalMap, GLMesh *, size_t>
{};
class STKInstancedSceneNode : public irr::scene::CMeshSceneNode
{
protected:
int m_ref_count;
std::vector<GLMesh *> MeshSolidMaterial[MAT_COUNT];
std::vector<GLMesh> GLmeshes;
std::vector<std::vector<InstanceData> > instanceData;
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView;
GLuint instances_vbo;
void createGLMeshes();
bool isMaterialInitialized;
void setFirstTimeMaterial();
void initinstancedvaostate(GLMesh &mesh, const std::vector<InstanceData> &);
void cleanGL();
core::vector3df windDir;
public:
STKInstancedSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
const irr::core::vector3df& position = irr::core::vector3df(0, 0, 0),
const irr::core::vector3df& rotation = irr::core::vector3df(0, 0, 0),
const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f));
~STKInstancedSceneNode();
virtual void render();
void addInstance(const core::vector3df &origin, const core::vector3df &orientation, const core::vector3df &scale);
int getInstanceCount() const { return instanceData[0].size(); }
core::matrix4 getInstanceTransform(int id);
void instanceGrab() { m_ref_count++; }
void instanceDrop()
{
m_ref_count--;
if (m_ref_count <= 0)
{
delete this;
}
}
LEAK_CHECK();
};
#endif

View File

@ -126,6 +126,7 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
GLMesh result = {};
if (!mb)
return result;
result.mb = mb;
result.IndexCount = mb->getIndexCount();
switch (mb->getIndexType())
@ -178,6 +179,7 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
for (unsigned i = 0; i < 6; i++)
result.textures[i] = mb->getMaterial().getTexture(i);
result.TextureMatrix = 0;
result.VAOType = mb->getVertexType();
return result;
}
@ -229,7 +231,7 @@ core::matrix4 computeMVP(const core::matrix4 &ModelMatrix)
return ModelViewProjectionMatrix;
}
core::vector3df getWind()
core::vector3df getWindDir()
{
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
GrassShaderProvider *gsp = (GrassShaderProvider *)irr_driver->getCallback(ES_GRASS);
@ -292,4 +294,48 @@ bool isObject(video::E_MATERIAL_TYPE type)
if (type == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
return true;
return false;
}
static void
SetTexture(GLMesh &mesh, unsigned i, bool isSrgb)
{
if (!mesh.textures[i])
mesh.textures[i] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[i], isSrgb);
#ifdef Bindless_Texture_Support
if (UserConfigParams::m_azdo)
{
if (!mesh.TextureHandles[i])
mesh.TextureHandles[i] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[i]), MeshShader::ObjectPass1Shader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[i]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[i]);
}
#endif
}
void InitTextures(GLMesh &mesh, MeshMaterial Mat)
{
switch (Mat)
{
default:
case MAT_DEFAULT:
case MAT_ALPHA_REF:
case MAT_GRASS:
case MAT_SPHEREMAP:
case MAT_UNLIT:
SetTexture(mesh, 0, true);
break;
case MAT_DETAIL:
case MAT_NORMAL_MAP:
SetTexture(mesh, 0, true);
SetTexture(mesh, 1, false);
break;
case MAT_SPLATTING:
SetTexture(mesh, 0, true);
SetTexture(mesh, 1, true);
SetTexture(mesh, 2, true);
SetTexture(mesh, 3, true);
SetTexture(mesh, 4, true);
break;
}
}

View File

@ -35,9 +35,9 @@ enum TransparentMaterial
struct GLMesh {
GLuint vao;
GLuint vao_shadow_pass;
GLuint vertex_buffer;
GLuint index_buffer;
GLuint instance_buffer;
video::ITexture *textures[6];
GLenum PrimitiveType;
GLenum IndexType;
@ -46,9 +46,9 @@ struct GLMesh {
core::matrix4 TextureMatrix;
size_t vaoBaseVertex;
size_t vaoOffset;
size_t vaoBaseInstance;
video::E_VERTEX_TYPE VAOType;
uint64_t TextureHandles[6];
scene::IMeshBuffer *mb;
};
GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb);
@ -58,61 +58,122 @@ GLuint createVAO(GLuint vbo, GLuint idx, video::E_VERTEX_TYPE type);
core::matrix4 computeMVP(const core::matrix4 &ModelViewProjectionMatrix);
bool isObject(video::E_MATERIAL_TYPE type);
core::vector3df getWind();
core::vector3df getWindDir();
class STKMeshCommon
{
public:
PtrVector<GLMesh, REF> MeshSolidMaterial[MAT_COUNT];
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
virtual void update() = 0;
virtual bool glow() const = 0;
virtual bool isImmediateDraw() const { return false; }
};
template<typename T, typename... Args>
class MeshList : public Singleton<T>, public std::vector<STK::Tuple<Args...> >
{};
class MeshList : public Singleton<T>
{
public:
std::vector<STK::Tuple<Args...> > SolidPass, Shadows[4], RSM;
void clear()
{
SolidPass.clear();
RSM.clear();
for (unsigned i = 0; i < 4; i++)
Shadows[i].clear();
}
};
template<typename T>
class InstancedMeshList : public Singleton<T>
{
public:
std::vector<GLMesh *> SolidPass, Shadows[4], RSM;
void clear()
{
SolidPass.clear();
RSM.clear();
for (unsigned i = 0; i < 4; i++)
Shadows[i].clear();
}
};
// -----------------------------------------Mat Default---------------------------------------------------- //
class ListMatDefault : public MeshList<ListMatDefault, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
{};
class AnimatedListMatDefault : public MeshList<AnimatedListMatDefault, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
class ListInstancedMatDefault : public InstancedMeshList<ListInstancedMatDefault>
{};
// -----------------------------------------Mat Alpha Ref---------------------------------------------------- //
class ListMatAlphaRef : public MeshList<ListMatAlphaRef, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
{};
class AnimatedListMatAlphaRef : public MeshList<AnimatedListMatAlphaRef, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
class ListInstancedMatAlphaRef : public InstancedMeshList<ListInstancedMatAlphaRef>
{};
// -----------------------------------------Mat Normap Map---------------------------------------------------- //
class ListMatNormalMap : public MeshList<ListMatNormalMap, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
{};
class ListInstancedMatNormalMap : public InstancedMeshList<ListInstancedMatNormalMap>
{};
// -----------------------------------------Mat Grass---------------------------------------------------- //
class ListMatGrass : public MeshList<ListMatGrass, GLMesh *, core::matrix4, core::matrix4, core::vector3df>
{};
class ListInstancedMatGrass : public InstancedMeshList<ListInstancedMatGrass>
{};
// -----------------------------------------Mat Sphere Map---------------------------------------------------- //
class ListMatSphereMap : public MeshList<ListMatSphereMap, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
{};
class ListInstancedMatSphereMap : public InstancedMeshList<ListInstancedMatSphereMap>
{};
// -----------------------------------------Mat Splatting---------------------------------------------------- //
class ListMatSplatting : public MeshList<ListMatSplatting, GLMesh *, core::matrix4, core::matrix4>
{};
// -----------------------------------------Mat Unlit---------------------------------------------------- //
class ListMatUnlit : public MeshList<ListMatUnlit, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
{};
class AnimatedListMatUnlit : public MeshList<AnimatedListMatUnlit, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
class ListInstancedMatUnlit : public InstancedMeshList<ListInstancedMatUnlit>
{};
// -----------------------------------------Mat Details---------------------------------------------------- //
class ListMatDetails : public MeshList<ListMatDetails, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
{};
class AnimatedListMatDetails : public MeshList<AnimatedListMatDetails, GLMesh *, core::matrix4, core::matrix4, core::matrix4>
class ListInstancedMatDetails : public InstancedMeshList<ListInstancedMatDetails>
{};
class ListBlendTransparent : public MeshList<ListBlendTransparent, GLMesh *, core::matrix4, core::matrix4>
// Transparent
template <typename T, typename ...Args>
class MiscList : public Singleton<T>, public std::vector<STK::Tuple<Args...> >
{};
class ListAdditiveTransparent : public MeshList<ListAdditiveTransparent, GLMesh *, core::matrix4, core::matrix4>
class ListBlendTransparent : public MiscList<ListBlendTransparent, GLMesh *, core::matrix4, core::matrix4>
{};
class ListBlendTransparentFog : public MeshList<ListBlendTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
class ListAdditiveTransparent : public MiscList<ListAdditiveTransparent, GLMesh *, core::matrix4, core::matrix4>
{};
class ListAdditiveTransparentFog : public MeshList<ListAdditiveTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
class ListBlendTransparentFog : public MiscList<ListBlendTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
{};
class ListDisplacement : public MeshList<ListDisplacement, GLMesh *, core::matrix4>
class ListAdditiveTransparentFog : public MiscList<ListAdditiveTransparentFog, GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
{};
class ListDisplacement : public MiscList<ListDisplacement, GLMesh *, core::matrix4>
{};
class ListInstancedGlow : public Singleton<ListInstancedGlow>, public std::vector<GLMesh *>
{};
// Forward pass (for transparents meshes)
@ -121,4 +182,6 @@ void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatr
MeshMaterial MaterialTypeToMeshMaterial(video::E_MATERIAL_TYPE, video::E_VERTEX_TYPE);
TransparentMaterial MaterialTypeToTransparentMaterial(video::E_MATERIAL_TYPE, f32 MaterialTypeParam);
void InitTextures(GLMesh &mesh, MeshMaterial);
#endif // STKMESH_H

View File

@ -21,6 +21,7 @@ STKMeshSceneNode::STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent,
isDisplacement = false;
immediate_draw = false;
update_each_frame = false;
isGlow = false;
if (createGLMeshes)
this->createGLMeshes();
@ -70,35 +71,31 @@ void STKMeshSceneNode::setFirstTimeMaterial()
if (rnd->isTransparent())
{
TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type, MaterialTypeParam);
if (immediate_draw)
{
fillLocalBuffer(mesh, mb);
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
glBindVertexArray(0);
}
else
if (!immediate_draw)
TransparentMesh[TranspMat].push_back(&mesh);
}
else
{
assert(!isDisplacement);
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
if (immediate_draw)
if (!immediate_draw)
{
fillLocalBuffer(mesh, mb);
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
glBindVertexArray(0);
InitTextures(mesh, MatType);
MeshSolidMaterial[MatType].push_back(&mesh);
}
else
MeshSolidMaterials[MatType].push_back(&mesh);
}
if (!immediate_draw)
if (!immediate_draw && 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);
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
glBindVertexArray(0);
}
}
isMaterialInitialized = true;
@ -113,12 +110,23 @@ void STKMeshSceneNode::cleanGLMeshes()
continue;
if (mesh.vao)
glDeleteVertexArrays(1, &(mesh.vao));
glDeleteBuffers(1, &(mesh.vertex_buffer));
glDeleteBuffers(1, &(mesh.index_buffer));
if (mesh.vertex_buffer)
glDeleteBuffers(1, &(mesh.vertex_buffer));
if (mesh.index_buffer)
glDeleteBuffers(1, &(mesh.index_buffer));
if (mesh.instance_buffer)
glDeleteBuffers(1, &(mesh.instance_buffer));
#ifdef Bindless_Texture_Support
for (unsigned j = 0; j < 6; j++)
{
if (mesh.TextureHandles[j] && glIsTextureHandleResidentARB(mesh.TextureHandles[j]))
glMakeTextureHandleNonResidentARB(mesh.TextureHandles[j]);
}
#endif
}
GLmeshes.clear();
for (unsigned i = 0; i < MAT_COUNT; i++)
MeshSolidMaterials[i].clearWithoutDeleting();
MeshSolidMaterial[i].clearWithoutDeleting();
}
void STKMeshSceneNode::setMesh(irr::scene::IMesh* mesh)
@ -135,14 +143,12 @@ STKMeshSceneNode::~STKMeshSceneNode()
void STKMeshSceneNode::drawGlow(const GLMesh &mesh)
{
ColorizeProvider * const cb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE);
assert(mesh.VAOType == video::EVT_STANDARD);
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
MeshShader::ColorizeShader::getInstance()->setUniforms(AbsoluteTransformation, video::SColorf(cb->getRed(), cb->getGreen(), cb->getBlue()));
MeshShader::ColorizeShader::getInstance()->setUniforms(AbsoluteTransformation, video::SColorf(glowcolor.getRed() / 255.f, glowcolor.getGreen() / 255.f, glowcolor.getBlue() / 255.f));
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
}
@ -163,26 +169,8 @@ void STKMeshSceneNode::updatevbo()
}
}
static video::ITexture *spareWhiteTex = 0;
void STKMeshSceneNode::OnRegisterSceneNode()
void STKMeshSceneNode::update()
{
if (isDisplacement)
SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
else
CMeshSceneNode::OnRegisterSceneNode();
}
void STKMeshSceneNode::render()
{
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
if (!Mesh || !driver)
return;
++PassCount;
Box = Mesh->getBoundingBox();
setFirstTimeMaterial();
@ -194,13 +182,50 @@ void STKMeshSceneNode::render()
continue;
GLmeshes[i].TextureMatrix = getMaterial(i).getTextureMatrix(0);
}
}
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS && immediate_draw)
void STKMeshSceneNode::OnRegisterSceneNode()
{
if (isDisplacement)
SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
else
CMeshSceneNode::OnRegisterSceneNode();
}
static video::ITexture *spareWhiteTex = 0;
void STKMeshSceneNode::render()
{
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
if (!Mesh || !driver)
return;
++PassCount;
update();
bool isTransparent;
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
if (!mb)
continue;
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
isTransparent = rnd->isTransparent();
break;
}
if ((irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS) && immediate_draw && !isTransparent)
{
core::matrix4 invmodel;
AbsoluteTransformation.getInverse(invmodel);
glDisable(GL_CULL_FACE);
if (update_each_frame)
updatevbo();
@ -214,6 +239,21 @@ void STKMeshSceneNode::render()
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
if (!mesh.textures[0])
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[0], true);
if (UserConfigParams::m_azdo)
{
#ifdef Bindless_Texture_Support
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
MeshShader::ObjectPass1Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0]));
#endif
}
else
MeshShader::ObjectPass1Shader::getInstance()->SetTextureUnits(std::vector < GLuint > { getTextureGLuint(mesh.textures[0]) });
MeshShader::ObjectPass1Shader::getInstance()->setUniforms(AbsoluteTransformation, invmodel);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
@ -224,53 +264,25 @@ void STKMeshSceneNode::render()
return;
}
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
if (irr_driver->getPhase() == SOLID_LIT_PASS && immediate_draw && !isTransparent)
{
core::matrix4 invmodel;
AbsoluteTransformation.getInverse(invmodel);
GLMesh* mesh;
for_in(mesh, MeshSolidMaterials[MAT_DEFAULT])
pushVector(ListMatDefault::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterials[MAT_ALPHA_REF])
pushVector(ListMatAlphaRef::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterials[MAT_SPHEREMAP])
pushVector(ListMatSphereMap::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterials[MAT_DETAIL])
pushVector(ListMatDetails::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
windDir = getWind();
for_in(mesh, MeshSolidMaterials[MAT_GRASS])
pushVector(ListMatGrass::getInstance(), mesh, AbsoluteTransformation, invmodel, windDir);
for_in(mesh, MeshSolidMaterials[MAT_UNLIT])
pushVector(ListMatUnlit::getInstance(), mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterials[MAT_SPLATTING])
pushVector(ListMatSplatting::getInstance(), mesh, AbsoluteTransformation, invmodel);
for_in(mesh, MeshSolidMaterials[MAT_NORMAL_MAP])
pushVector(ListMatNormalMap::getInstance(), mesh, AbsoluteTransformation, invmodel, core::matrix4::EM4CONST_IDENTITY);
return;
}
if (irr_driver->getPhase() == SOLID_LIT_PASS)
{
core::matrix4 invmodel;
AbsoluteTransformation.getInverse(invmodel);
if (immediate_draw)
glDisable(GL_CULL_FACE);
if (!spareWhiteTex)
spareWhiteTex = getUnicolorTexture(video::SColor(255, 255, 255, 255));
glUseProgram(MeshShader::ObjectPass2Shader::getInstance()->Program);
// Only untextured
for (unsigned i = 0; i < GLmeshes.size(); i++)
{
glDisable(GL_CULL_FACE);
if (!spareWhiteTex)
spareWhiteTex = getUnicolorTexture(video::SColor(255, 255, 255, 255));
glUseProgram(MeshShader::ObjectPass2Shader::getInstance()->Program);
// Only untextured
for (unsigned i = 0; i < GLmeshes.size(); i++)
irr_driver->IncreaseObjectCount();
GLMesh &mesh = GLmeshes[i];
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
if (UserConfigParams::m_azdo)
{
irr_driver->IncreaseObjectCount();
GLMesh &mesh = GLmeshes[i];
@ -278,17 +290,54 @@ void STKMeshSceneNode::render()
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(spareWhiteTex) });
if (UserConfigParams::m_azdo)
{
#ifdef Bindless_Texture_Support
GLuint64 DiffuseHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_DIFFUSE), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(DiffuseHandle))
glMakeTextureHandleResidentARB(DiffuseHandle);
GLuint64 SpecularHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_SPECULAR), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[1]);
if (!glIsTextureHandleResidentARB(SpecularHandle))
glMakeTextureHandleResidentARB(SpecularHandle);
GLuint64 SSAOHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_HALF1_R), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[2]);
if (!glIsTextureHandleResidentARB(SSAOHandle))
glMakeTextureHandleResidentARB(SSAOHandle);
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(spareWhiteTex), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
MeshShader::ObjectPass2Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, mesh.TextureHandles[0]));
#endif
}
else
MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits(createVector<GLuint>(
irr_driver->getRenderTargetTexture(RTT_DIFFUSE),
irr_driver->getRenderTargetTexture(RTT_SPECULAR),
irr_driver->getRenderTargetTexture(RTT_HALF1_R),
getTextureGLuint(spareWhiteTex)));
MeshShader::ObjectPass2Shader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
glBindVertexArray(0);
}
glEnable(GL_CULL_FACE);
return;
else
MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits(createVector<GLuint>(
irr_driver->getRenderTargetTexture(RTT_DIFFUSE),
irr_driver->getRenderTargetTexture(RTT_SPECULAR),
irr_driver->getRenderTargetTexture(RTT_HALF1_R),
getTextureGLuint(mesh.textures[0])));
MeshShader::ObjectPass2Shader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
glBindVertexArray(0);
}
glEnable(GL_CULL_FACE);
return;
}
@ -300,12 +349,15 @@ void STKMeshSceneNode::render()
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
if (!mb)
continue;
glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD));
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD));
else
glBindVertexArray(GLmeshes[i].vao);
drawGlow(GLmeshes[i]);
}
}
if (irr_driver->getPhase() == TRANSPARENT_PASS)
if (irr_driver->getPhase() == TRANSPARENT_PASS && isTransparent)
{
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
@ -340,8 +392,10 @@ void STKMeshSceneNode::render()
tmpcol.getGreen() / 255.0f,
tmpcol.getBlue() / 255.0f);
if (!mesh.textures[0])
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[0], true);
if (UserConfigParams::m_bindless_textures)
if (UserConfigParams::m_azdo)
{
#ifdef Bindless_Texture_Support
if (!mesh.TextureHandles[0])
@ -371,9 +425,10 @@ void STKMeshSceneNode::render()
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
if (!mesh.textures[0])
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[0], true);
if (UserConfigParams::m_bindless_textures)
if (UserConfigParams::m_azdo)
{
#ifdef Bindless_Texture_Support
if (!mesh.TextureHandles[0])
@ -397,47 +452,16 @@ void STKMeshSceneNode::render()
}
GLMesh* mesh;
if (World::getWorld() && World::getWorld()->isFogEnabled())
{
const Track * const track = World::getWorld()->getTrack();
// Todo : put everything in a ubo
const float fogmax = track->getFogMax();
const float startH = track->getFogStartHeight();
const float endH = track->getFogEndHeight();
const float start = track->getFogStart();
const float end = track->getFogEnd();
const video::SColor tmpcol = track->getFogColor();
video::SColorf col(tmpcol.getRed() / 255.0f,
tmpcol.getGreen() / 255.0f,
tmpcol.getBlue() / 255.0f);
for_in(mesh, TransparentMesh[TM_DEFAULT])
pushVector(ListBlendTransparentFog::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix,
fogmax, startH, endH, start, end, col);
for_in(mesh, TransparentMesh[TM_ADDITIVE])
pushVector(ListAdditiveTransparentFog::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix,
fogmax, startH, endH, start, end, col);
}
else
{
for_in(mesh, TransparentMesh[TM_DEFAULT])
pushVector(ListBlendTransparent::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix);
for_in(mesh, TransparentMesh[TM_ADDITIVE])
pushVector(ListAdditiveTransparent::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix);
}
for_in(mesh, TransparentMesh[TM_DISPLACEMENT])
pushVector(ListDisplacement::getInstance(), mesh, AbsoluteTransformation);
if (!TransparentMesh[TM_BUBBLE].empty())
glUseProgram(MeshShader::BubbleShader::Program);
glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD));
if (irr_driver->hasARB_base_instance())
glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD));
for_in(mesh, TransparentMesh[TM_BUBBLE])
{
if (irr_driver->hasARB_base_instance())
glBindVertexArray(mesh->vao);
drawBubble(*mesh, ModelViewProjectionMatrix);
}
return;
}
}

View File

@ -4,11 +4,9 @@
#include "stkmesh.hpp"
#include "utils/ptr_vector.hpp"
class STKMeshSceneNode : public irr::scene::CMeshSceneNode
class STKMeshSceneNode : public irr::scene::CMeshSceneNode, public STKMeshCommon
{
protected:
PtrVector<GLMesh, REF> MeshSolidMaterials[MAT_COUNT];
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix;
core::vector3df windDir;
@ -24,7 +22,10 @@ protected:
bool immediate_draw;
bool update_each_frame;
bool isDisplacement;
bool isGlow;
video::SColor glowcolor;
public:
virtual void update();
void setReloadEachFrame(bool);
STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
const irr::core::vector3df& position = irr::core::vector3df(0, 0, 0),
@ -35,6 +36,7 @@ public:
virtual void setMesh(irr::scene::IMesh* mesh);
virtual void OnRegisterSceneNode();
virtual ~STKMeshSceneNode();
virtual bool isImmediateDraw() const { return immediate_draw; }
void setIsDisplacement(bool v) {
isDisplacement = v;
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
@ -46,6 +48,9 @@ public:
mb->getMaterial().MaterialType = irr_driver->getShader(ES_DISPLACE);
}
}
virtual bool glow() const { return isGlow; }
void setGlowColors(const video::SColor &c) { isGlow = true; glowcolor = c; }
video::SColor getGlowColor() const { return glowcolor; }
};
#endif

View File

@ -0,0 +1,653 @@
#include "stkscenemanager.hpp"
#include "stkmesh.hpp"
#include "irr_driver.hpp"
#include <ISceneManager.h>
#include <ISceneNode.h>
#include "stkanimatedmesh.hpp"
#include "stkmeshscenenode.hpp"
#include "utils/ptr_vector.hpp"
#include <ICameraSceneNode.h>
#include <SViewFrustum.h>
#include "callbacks.hpp"
#include "utils/cpp2011.hpp"
#include <omp.h>
#include "modes/world.hpp"
#include "tracks/track.hpp"
#include "lod_node.hpp"
#include <unordered_map>
static void
FillInstances_impl(std::vector<std::pair<GLMesh *, scene::ISceneNode *> > InstanceList, InstanceData * InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer,
size_t &InstanceBufferOffset, size_t &CommandBufferOffset, size_t &PolyCount)
{
// Should never be empty
GLMesh *mesh = InstanceList.front().first;
DrawElementsIndirectCommand &CurrentCommand = CommandBuffer[CommandBufferOffset++];
CurrentCommand.baseVertex = mesh->vaoBaseVertex;
CurrentCommand.count = mesh->IndexCount;
CurrentCommand.firstIndex = mesh->vaoOffset / 2;
CurrentCommand.baseInstance = InstanceBufferOffset;
CurrentCommand.instanceCount = InstanceList.size();
PolyCount += InstanceList.size() * mesh->IndexCount / 3;
for (unsigned i = 0; i < InstanceList.size(); i++)
{
auto &Tp = InstanceList[i];
InstanceData &Instance = InstanceBuffer[InstanceBufferOffset++];
scene::ISceneNode *node = Tp.second;
const core::matrix4 &mat = node->getAbsoluteTransformation();
const core::vector3df &Origin = mat.getTranslation();
const core::vector3df &Orientation = mat.getRotationDegrees();
const core::vector3df &Scale = mat.getScale();
Instance.Origin.X = Origin.X;
Instance.Origin.Y = Origin.Y;
Instance.Origin.Z = Origin.Z;
Instance.Orientation.X = Orientation.X;
Instance.Orientation.Y = Orientation.Y;
Instance.Orientation.Z = Orientation.Z;
Instance.Scale.X = Scale.X;
Instance.Scale.Y = Scale.Y;
Instance.Scale.Z = Scale.Z;
Instance.Texture = mesh->TextureHandles[0];
Instance.SecondTexture = mesh->TextureHandles[1];
}
}
static void
FillInstancesGlow_impl(std::vector<std::pair<GLMesh *, STKMeshCommon *> > InstanceList, GlowInstanceData * InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer,
size_t &InstanceBufferOffset, size_t &CommandBufferOffset)
{
// Should never be empty
GLMesh *mesh = InstanceList.front().first;
DrawElementsIndirectCommand &CurrentCommand = CommandBuffer[CommandBufferOffset++];
CurrentCommand.baseVertex = mesh->vaoBaseVertex;
CurrentCommand.count = mesh->IndexCount;
CurrentCommand.firstIndex = mesh->vaoOffset / 2;
CurrentCommand.baseInstance = InstanceBufferOffset;
CurrentCommand.instanceCount = InstanceList.size();
for (unsigned i = 0; i < InstanceList.size(); i++)
{
STKMeshSceneNode *node = dynamic_cast<STKMeshSceneNode*>(InstanceList[i].second);
GlowInstanceData &Instance = InstanceBuffer[InstanceBufferOffset++];
const core::matrix4 &mat = node->getAbsoluteTransformation();
const core::vector3df &Origin = mat.getTranslation();
const core::vector3df &Orientation = mat.getRotationDegrees();
const core::vector3df &Scale = mat.getScale();
Instance.Color = node->getGlowColor().color;
Instance.Origin.X = Origin.X;
Instance.Origin.Y = Origin.Y;
Instance.Origin.Z = Origin.Z;
Instance.Orientation.X = Orientation.X;
Instance.Orientation.Y = Orientation.Y;
Instance.Orientation.Z = Orientation.Z;
Instance.Scale.X = Scale.X;
Instance.Scale.Y = Scale.Y;
Instance.Scale.Z = Scale.Z;
}
}
static
void FillInstances(const std::unordered_map<scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > &GatheredGLMesh, std::vector<GLMesh *> &InstancedList,
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, size_t &Polycount)
{
auto It = GatheredGLMesh.begin(), E = GatheredGLMesh.end();
for (; It != E; ++It)
{
FillInstances_impl(It->second, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, Polycount);
if (!UserConfigParams::m_azdo)
InstancedList.push_back(It->second.front().first);
}
}
static
void FillInstancesGrass(const std::unordered_map<scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > &GatheredGLMesh, std::vector<GLMesh *> &InstancedList,
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, const core::vector3df &dir, size_t &PolyCount)
{
auto It = GatheredGLMesh.begin(), E = GatheredGLMesh.end();
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
for (; It != E; ++It)
{
FillInstances_impl(It->second, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, PolyCount);
if (!UserConfigParams::m_azdo)
InstancedList.push_back(It->second.front().first);
}
}
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > MeshForSolidPass[MAT_COUNT];
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > MeshForShadowPass[4][MAT_COUNT];
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > MeshForRSMPass[MAT_COUNT];
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, STKMeshCommon *> > > MeshForGlowPass;
static core::vector3df windDir;
static void
handleSTKCommon(scene::ISceneNode *Node, std::vector<scene::ISceneNode *> *ImmediateDraw, bool IsCulledForSolid, bool IsCulledForShadow[4], bool IsCulledForRSM)
{
STKMeshCommon *node = dynamic_cast<STKMeshCommon*>(Node);
if (!node)
return;
node->update();
if (node->isImmediateDraw())
{
ImmediateDraw->push_back(Node);
return;
}
for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat)
{
GLMesh *mesh;
if (!IsCulledForSolid)
{
if (irr_driver->hasARB_draw_indirect())
{
for_in(mesh, node->MeshSolidMaterial[Mat])
{
if (node->glow())
MeshForGlowPass[mesh->mb].push_back(std::make_pair(mesh, node));
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
ModelMatrix.getInverse(InvModelMatrix);
if (mesh->TextureMatrix.isIdentity())
MeshForSolidPass[Mat][mesh->mb].push_back(std::make_pair(mesh, Node));
else
{
switch (Mat)
{
case MAT_DEFAULT:
ListMatDefault::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_ALPHA_REF:
ListMatAlphaRef::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_UNLIT:
ListMatUnlit::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
}
}
}
}
else
{
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
ModelMatrix.getInverse(InvModelMatrix);
for_in(mesh, node->MeshSolidMaterial[Mat])
{
switch (Mat)
{
case MAT_DEFAULT:
ListMatDefault::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_ALPHA_REF:
ListMatAlphaRef::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_NORMAL_MAP:
ListMatNormalMap::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_DETAIL:
ListMatDetails::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_UNLIT:
ListMatUnlit::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_SPHEREMAP:
ListMatSphereMap::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_SPLATTING:
ListMatSplatting::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix));
break;
case MAT_GRASS:
ListMatGrass::getInstance()->SolidPass.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, windDir));
break;
}
}
}
}
for (unsigned cascade = 0; cascade < 4; ++cascade)
{
if (!IsCulledForShadow[cascade])
{
if (irr_driver->hasARB_draw_indirect())
{
for_in(mesh, node->MeshSolidMaterial[Mat])
MeshForShadowPass[cascade][Mat][mesh->mb].push_back(std::make_pair(mesh, Node));
}
else
{
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
ModelMatrix.getInverse(InvModelMatrix);
for_in(mesh, node->MeshSolidMaterial[Mat])
{
switch (Mat)
{
case MAT_DEFAULT:
ListMatDefault::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_ALPHA_REF:
ListMatAlphaRef::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_NORMAL_MAP:
ListMatNormalMap::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_DETAIL:
ListMatDetails::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_UNLIT:
ListMatUnlit::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_SPHEREMAP:
ListMatSphereMap::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_SPLATTING:
ListMatSplatting::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix));
break;
case MAT_GRASS:
ListMatGrass::getInstance()->Shadows[cascade].push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, windDir));
}
}
}
}
}
if (!IsCulledForRSM)
{
if (irr_driver->hasARB_draw_indirect())
{
for_in(mesh, node->MeshSolidMaterial[Mat])
MeshForRSMPass[Mat][mesh->mb].push_back(std::make_pair(mesh, Node));
}
else
{
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
ModelMatrix.getInverse(InvModelMatrix);
for_in(mesh, node->MeshSolidMaterial[Mat])
{
switch (Mat)
{
case MAT_DEFAULT:
ListMatDefault::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_ALPHA_REF:
ListMatAlphaRef::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_NORMAL_MAP:
ListMatNormalMap::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_DETAIL:
ListMatDetails::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_UNLIT:
ListMatUnlit::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_SPHEREMAP:
ListMatSphereMap::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, mesh->TextureMatrix));
break;
case MAT_SPLATTING:
ListMatSplatting::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix));
break;
case MAT_GRASS:
ListMatGrass::getInstance()->RSM.push_back(STK::make_tuple(mesh, ModelMatrix, InvModelMatrix, windDir));
break;
}
}
}
}
}
// Transparent
if (!IsCulledForSolid)
{
GLMesh *mesh;
if (World::getWorld() && World::getWorld()->isFogEnabled())
{
const Track * const track = World::getWorld()->getTrack();
// Todo : put everything in a ubo
const float fogmax = track->getFogMax();
const float startH = track->getFogStartHeight();
const float endH = track->getFogEndHeight();
const float start = track->getFogStart();
const float end = track->getFogEnd();
const video::SColor tmpcol = track->getFogColor();
video::SColorf col(tmpcol.getRed() / 255.0f,
tmpcol.getGreen() / 255.0f,
tmpcol.getBlue() / 255.0f);
for_in(mesh, node->TransparentMesh[TM_DEFAULT])
pushVector(ListBlendTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix,
fogmax, startH, endH, start, end, col);
for_in(mesh, node->TransparentMesh[TM_ADDITIVE])
pushVector(ListAdditiveTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix,
fogmax, startH, endH, start, end, col);
}
else
{
for_in(mesh, node->TransparentMesh[TM_DEFAULT])
pushVector(ListBlendTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix);
for_in(mesh, node->TransparentMesh[TM_ADDITIVE])
pushVector(ListAdditiveTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix);
}
for_in(mesh, node->TransparentMesh[TM_DISPLACEMENT])
pushVector(ListDisplacement::getInstance(), mesh, Node->getAbsoluteTransformation());
}
}
static void
parseSceneManager(core::list<scene::ISceneNode*> List, std::vector<scene::ISceneNode *> *ImmediateDraw,
scene::ICameraSceneNode* cam, scene::ICameraSceneNode *shadowCams[4], scene::ICameraSceneNode *RSM_cam)
{
core::list<scene::ISceneNode*>::Iterator I = List.begin(), E = List.end();
for (; I != E; ++I)
{
if (LODNode *node = dynamic_cast<LODNode *>(*I))
node->updateVisibility();
if (!(*I)->isVisible())
continue;
(*I)->updateAbsolutePosition();
core::aabbox3d<f32> tbox = (*I)->getBoundingBox();
(*I)->getAbsoluteTransformation().transformBoxEx(tbox);
bool IsCulledForSolid = !(tbox.intersectsWithBox(cam->getViewFrustum()->getBoundingBox()));
bool IsCulledForShadow[4];
for (unsigned i = 0; i < 4; ++i)
IsCulledForShadow[i] = !(tbox.intersectsWithBox(shadowCams[i]->getViewFrustum()->getBoundingBox()));
bool IsCulledForRSM = !(tbox.intersectsWithBox(RSM_cam->getViewFrustum()->getBoundingBox()));
if (!IsCulledForSolid)
{
if (ParticleSystemProxy *node = dynamic_cast<ParticleSystemProxy *>(*I))
{
if (node->update())
ParticlesList::getInstance()->push_back(node);
continue;
}
}
handleSTKCommon(*I, ImmediateDraw, IsCulledForSolid, IsCulledForShadow, IsCulledForRSM);
parseSceneManager((*I)->getChildren(), ImmediateDraw, cam, shadowCams, RSM_cam);
}
}
template<MeshMaterial Mat> static void
GenDrawCalls(unsigned cascade, std::vector<GLMesh *> &InstancedList,
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, size_t &PolyCount)
{
if (irr_driver->hasARB_draw_indirect())
ShadowPassCmd::getInstance()->Offset[cascade][Mat] = CommandBufferOffset; // Store command buffer offset
FillInstances(MeshForShadowPass[cascade][Mat], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, PolyCount);
if (UserConfigParams::m_azdo)
ShadowPassCmd::getInstance()->Size[cascade][Mat] = CommandBufferOffset - ShadowPassCmd::getInstance()->Offset[cascade][Mat];
}
template<MeshMaterial Mat> static void
GenDrawCallsGrass(unsigned cascade, std::vector<GLMesh *> &InstancedList,
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, const core::vector3df &dir, size_t &PolyCount)
{
if (irr_driver->hasARB_draw_indirect())
ShadowPassCmd::getInstance()->Offset[cascade][Mat] = CommandBufferOffset; // Store command buffer offset
FillInstancesGrass(MeshForShadowPass[cascade][Mat], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, dir, PolyCount);
if (UserConfigParams::m_azdo)
ShadowPassCmd::getInstance()->Size[cascade][Mat] = CommandBufferOffset - ShadowPassCmd::getInstance()->Offset[cascade][Mat];
}
void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
{
windDir = getWindDir();
ListBlendTransparent::getInstance()->clear();
ListAdditiveTransparent::getInstance()->clear();
ListBlendTransparentFog::getInstance()->clear();
ListAdditiveTransparentFog::getInstance()->clear();
ListDisplacement::getInstance()->clear();
ListMatDefault::getInstance()->clear();
ListMatAlphaRef::getInstance()->clear();
ListMatSphereMap::getInstance()->clear();
ListMatDetails::getInstance()->clear();
ListMatUnlit::getInstance()->clear();
ListMatNormalMap::getInstance()->clear();
ListMatGrass::getInstance()->clear();
ListMatSplatting::getInstance()->clear();
ImmediateDrawList::getInstance()->clear();
ParticlesList::getInstance()->clear();
ListInstancedGlow::getInstance()->clear();
for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat)
{
MeshForSolidPass[Mat].clear();
MeshForRSMPass[Mat].clear();
for (unsigned cascade = 0; cascade < 4; ++cascade)
MeshForShadowPass[cascade][Mat].clear();
}
MeshForGlowPass.clear();
core::list<scene::ISceneNode*> List = m_scene_manager->getRootSceneNode()->getChildren();
bool isCulled[4] = {};
// Add a 20 ms timeout
if (!m_sync)
m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
GLenum reason = glClientWaitSync(m_sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000000);
/* switch (reason)
{
case GL_ALREADY_SIGNALED:
printf("Already Signaled\n");
break;
case GL_TIMEOUT_EXPIRED:
printf("Timeout Expired\n");
break;
case GL_CONDITION_SATISFIED:
printf("Condition Satisfied\n");
break;
case GL_WAIT_FAILED:
printf("Wait Failed\n");
break;
}*/
parseSceneManager(List, ImmediateDrawList::getInstance(), camnode, m_shadow_camnodes, m_suncam);
if (!irr_driver->hasARB_draw_indirect())
return;
InstanceData *InstanceBuffer;
InstanceData *ShadowInstanceBuffer;
InstanceData *RSMInstanceBuffer;
GlowInstanceData *GlowInstanceBuffer;
DrawElementsIndirectCommand *CmdBuffer;
DrawElementsIndirectCommand *ShadowCmdBuffer;
DrawElementsIndirectCommand *RSMCmdBuffer;
DrawElementsIndirectCommand *GlowCmdBuffer;
if (irr_driver->hasBufferStorageExtension())
{
InstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeDefault);
ShadowInstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeShadow);
RSMInstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeRSM);
GlowInstanceBuffer = (GlowInstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeGlow);
CmdBuffer = SolidPassCmd::getInstance()->Ptr;
ShadowCmdBuffer = ShadowPassCmd::getInstance()->Ptr;
GlowCmdBuffer = GlowPassCmd::getInstance()->Ptr;
RSMCmdBuffer = RSMPassCmd::getInstance()->Ptr;
}
ListInstancedMatDefault::getInstance()->clear();
ListInstancedMatAlphaRef::getInstance()->clear();
ListInstancedMatGrass::getInstance()->clear();
ListInstancedMatNormalMap::getInstance()->clear();
ListInstancedMatSphereMap::getInstance()->clear();
ListInstancedMatDetails::getInstance()->clear();
ListInstancedMatUnlit::getInstance()->clear();
size_t SolidPoly = 0, ShadowPoly = 0, MiscPoly = 0;
#pragma omp parallel sections
{
#pragma omp section
{
size_t offset = 0, current_cmd = 0;
if (!irr_driver->hasBufferStorageExtension())
{
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeDefault));
InstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, SolidPassCmd::getInstance()->drawindirectcmd);
CmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
// Default Material
SolidPassCmd::getInstance()->Offset[MAT_DEFAULT] = current_cmd;
FillInstances(MeshForSolidPass[MAT_DEFAULT], ListInstancedMatDefault::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly);
SolidPassCmd::getInstance()->Size[MAT_DEFAULT] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_DEFAULT];
// Alpha Ref
SolidPassCmd::getInstance()->Offset[MAT_ALPHA_REF] = current_cmd;
FillInstances(MeshForSolidPass[MAT_ALPHA_REF], ListInstancedMatAlphaRef::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly);
SolidPassCmd::getInstance()->Size[MAT_ALPHA_REF] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_ALPHA_REF];
// Unlit
SolidPassCmd::getInstance()->Offset[MAT_UNLIT] = current_cmd;
FillInstances(MeshForSolidPass[MAT_UNLIT], ListInstancedMatUnlit::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly);
SolidPassCmd::getInstance()->Size[MAT_UNLIT] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_UNLIT];
// Spheremap
SolidPassCmd::getInstance()->Offset[MAT_SPHEREMAP] = current_cmd;
FillInstances(MeshForSolidPass[MAT_SPHEREMAP], ListInstancedMatSphereMap::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly);
SolidPassCmd::getInstance()->Size[MAT_SPHEREMAP] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_SPHEREMAP];
// Detail
SolidPassCmd::getInstance()->Offset[MAT_DETAIL] = current_cmd;
FillInstances(MeshForSolidPass[MAT_DETAIL], ListInstancedMatDetails::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly);
SolidPassCmd::getInstance()->Size[MAT_DETAIL] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_DETAIL];
// Normal Map
SolidPassCmd::getInstance()->Offset[MAT_NORMAL_MAP] = current_cmd;
FillInstances(MeshForSolidPass[MAT_NORMAL_MAP], ListInstancedMatNormalMap::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly);
SolidPassCmd::getInstance()->Size[MAT_NORMAL_MAP] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_NORMAL_MAP];
// Grass
SolidPassCmd::getInstance()->Offset[MAT_GRASS] = current_cmd;
FillInstancesGrass(MeshForSolidPass[MAT_GRASS], ListInstancedMatGrass::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, windDir, SolidPoly);
SolidPassCmd::getInstance()->Size[MAT_GRASS] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_GRASS];
if (!irr_driver->hasBufferStorageExtension())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
}
#pragma omp section
{
size_t offset = 0, current_cmd = 0;
if (!irr_driver->hasBufferStorageExtension())
{
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeGlow));
GlowInstanceBuffer = (GlowInstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, GlowPassCmd::getInstance()->drawindirectcmd);
GlowCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
// Glow
if (irr_driver->hasARB_draw_indirect())
GlowPassCmd::getInstance()->Offset = offset; // Store command buffer offset
auto It = MeshForGlowPass.begin(), E = MeshForGlowPass.end();
for (; It != E; ++It)
{
FillInstancesGlow_impl(It->second, GlowInstanceBuffer, GlowCmdBuffer, offset, current_cmd);
if (!UserConfigParams::m_azdo)
ListInstancedGlow::getInstance()->push_back(It->second.front().first);
}
if (UserConfigParams::m_azdo)
GlowPassCmd::getInstance()->Size = current_cmd - GlowPassCmd::getInstance()->Offset;
if (!irr_driver->hasBufferStorageExtension())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
}
#pragma omp section
{
irr_driver->setPhase(SHADOW_PASS);
size_t offset = 0, current_cmd = 0;
if (!irr_driver->hasBufferStorageExtension())
{
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeShadow));
ShadowInstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, ShadowPassCmd::getInstance()->drawindirectcmd);
ShadowCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
for (unsigned i = 0; i < 4; i++)
{
// Mat default
GenDrawCalls<MAT_DEFAULT>(i, ListInstancedMatDefault::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat AlphaRef
GenDrawCalls<MAT_ALPHA_REF>(i, ListInstancedMatAlphaRef::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat Unlit
GenDrawCalls<MAT_UNLIT>(i, ListInstancedMatUnlit::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat NormalMap
GenDrawCalls<MAT_NORMAL_MAP>(i, ListInstancedMatNormalMap::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat Spheremap
GenDrawCalls<MAT_SPHEREMAP>(i, ListInstancedMatSphereMap::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat Detail
GenDrawCalls<MAT_DETAIL>(i, ListInstancedMatDetails::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat Grass
GenDrawCallsGrass<MAT_GRASS>(i, ListInstancedMatGrass::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, windDir, ShadowPoly);
}
if (!irr_driver->hasBufferStorageExtension())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
}
#pragma omp section
{
size_t offset = 0, current_cmd = 0;
if (!irr_driver->hasBufferStorageExtension())
{
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeRSM));
RSMInstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, RSMPassCmd::getInstance()->drawindirectcmd);
RSMCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
// Default Material
RSMPassCmd::getInstance()->Offset[MAT_DEFAULT] = current_cmd;
FillInstances(MeshForRSMPass[MAT_DEFAULT], ListInstancedMatDefault::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly);
RSMPassCmd::getInstance()->Size[MAT_DEFAULT] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_DEFAULT];
// Alpha Ref
RSMPassCmd::getInstance()->Offset[MAT_ALPHA_REF] = current_cmd;
FillInstances(MeshForRSMPass[MAT_ALPHA_REF], ListInstancedMatAlphaRef::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly);
RSMPassCmd::getInstance()->Size[MAT_ALPHA_REF] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_ALPHA_REF];
// Unlit
RSMPassCmd::getInstance()->Offset[MAT_UNLIT] = current_cmd;
FillInstances(MeshForRSMPass[MAT_UNLIT], ListInstancedMatUnlit::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly);
RSMPassCmd::getInstance()->Size[MAT_UNLIT] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_UNLIT];
// Detail
RSMPassCmd::getInstance()->Offset[MAT_DETAIL] = current_cmd;
FillInstances(MeshForRSMPass[MAT_DETAIL], ListInstancedMatDetails::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly);
RSMPassCmd::getInstance()->Size[MAT_DETAIL] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_DETAIL];
// Normal Map
RSMPassCmd::getInstance()->Offset[MAT_NORMAL_MAP] = current_cmd;
FillInstances(MeshForRSMPass[MAT_NORMAL_MAP], ListInstancedMatNormalMap::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly);
RSMPassCmd::getInstance()->Size[MAT_NORMAL_MAP] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_NORMAL_MAP];
if (!irr_driver->hasBufferStorageExtension())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
}
}
poly_count[SOLID_NORMAL_AND_DEPTH_PASS] += SolidPoly;
poly_count[SHADOW_PASS] += ShadowPoly;
glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
}

View File

@ -0,0 +1,68 @@
// Not really a scene manager yet but hold algorithm that
// rework scene manager output
#ifndef HEADER_STKSCENEMANAGER_HPP
#define HEADER_STKSCENEMANAGER_HPP
#include "utils/singleton.hpp"
#include "gl_headers.hpp"
#include "stkmesh.hpp"
#include "gpuparticles.hpp"
template<typename T>
class CommandBuffer : public Singleton<T>
{
public:
GLuint drawindirectcmd;
DrawElementsIndirectCommand *Ptr;
CommandBuffer()
{
glGenBuffers(1, &drawindirectcmd);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawindirectcmd);
#ifdef Buffer_Storage
if (irr_driver->hasBufferStorageExtension())
{
glBufferStorage(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
Ptr = (DrawElementsIndirectCommand *)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
}
else
#endif
{
glBufferData(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_STREAM_DRAW);
}
}
};
class ImmediateDrawList : public Singleton<ImmediateDrawList>, public std::vector<scene::ISceneNode *>
{};
class ParticlesList : public Singleton<ParticlesList>, public std::vector<ParticleSystemProxy *>
{};
class SolidPassCmd : public CommandBuffer<SolidPassCmd>
{
public:
size_t Offset[MAT_COUNT], Size[MAT_COUNT];
};
class ShadowPassCmd : public CommandBuffer<ShadowPassCmd>
{
public:
size_t Offset[4][MAT_COUNT], Size[4][MAT_COUNT];
};
class RSMPassCmd : public CommandBuffer<RSMPassCmd>
{
public:
size_t Offset[MAT_COUNT], Size[MAT_COUNT];
};
class GlowPassCmd : public CommandBuffer<GlowPassCmd>
{
public:
size_t Offset, Size;
};
#endif

View File

@ -18,92 +18,80 @@
#include "audio/sfx_base.hpp"
#include "audio/sfx_manager.hpp"
#include "graphics/camera.hpp"
#include "graphics/glwrap.hpp"
#include "graphics/gpuparticles.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/material_manager.hpp"
#include "graphics/material.hpp"
#include "graphics/per_camera_node.hpp"
#include "graphics/rain.hpp"
#include "graphics/shaders.hpp"
#include "graphics/weather.hpp"
#include "modes/world.hpp"
#include "states_screens/race_gui.hpp"
#include "utils/constants.hpp"
#include "utils/random_generator.hpp"
#include <ISceneManager.h>
#include <SMeshBuffer.h>
// The weather manager
using namespace video;
using namespace scene;
using namespace core;
// The rain manager
Rain::Rain(Camera *camera, irr::scene::ISceneNode* parent) : m_thunder_sound(0)
Weather::Weather(bool lightning, std::string sound)
{
m_lightning = camera->getIndex()==0;
m_lightning = lightning;
m_thunder_sound = NULL;
m_weather_sound = NULL;
if (m_lightning)
m_thunder_sound = sfx_manager->createSoundSource("thunder");
{
m_thunder_sound = sfx_manager->createSoundSource("thunder");
}
Material* m = material_manager->getMaterial("rain.png");
assert(m != NULL);
if (sound != "")
{
m_weather_sound = sfx_manager->createSoundSource(sound);
}
RandomGenerator g;
m_next_lightning = (float)g.get(35);
// RainNode *node = new RainNode(irr_driver->getSceneManager(), m->getTexture());
// m_node = irr_driver->addPerCameraNode(node, camera->getCameraSceneNode(), parent);
// m_node->setAutomaticCulling(0);
} // Rain
} // Weather
// ----------------------------------------------------------------------------
Rain::~Rain()
Weather::~Weather()
{
// m_node->drop(); // drop STK's reference
// m_node->remove(); // Then remove it from the scene graph.
if (m_lightning && m_thunder_sound != NULL) sfx_manager->deleteSFX(m_thunder_sound);
if (m_thunder_sound != NULL)
sfx_manager->deleteSFX(m_thunder_sound);
if (m_weather_sound != NULL)
sfx_manager->deleteSFX(m_weather_sound);
}
// ----------------------------------------------------------------------------
void Rain::update(float dt)
void Weather::update(float dt)
{
if (m_lightning)
{
m_next_lightning -= dt;
if (m_next_lightning < 0.0f)
{
RaceGUIBase* gui_base = World::getWorld()->getRaceGUI();
if (gui_base != NULL)
{
gui_base->doLightning();
if (m_thunder_sound) m_thunder_sound->play();
}
if (m_thunder_sound)
{
m_thunder_sound->play();
}
}
RandomGenerator g;
m_next_lightning = 35 + (float)g.get(35);
}
}
} // update
// ----------------------------------------------------------------------------
void Rain::setPosition(const core::vector3df& position)
void Weather::playSound()
{
// m_node->getChild()->setPosition(position);
} // setPosition
// ----------------------------------------------------------------------------
void Rain::setCamera(scene::ICameraSceneNode* camera)
{
// m_node->setCamera(camera);
if (m_weather_sound)
{
m_weather_sound->setLoop(true);
m_weather_sound->play();
}
}

View File

@ -16,38 +16,25 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_RAIN_HPP
#define HEADER_RAIN_HPP
class Camera;
class PerCameraNode;
#include <vector3d.h>
namespace irr
{
namespace video { class SMaterial; class ITexture; }
namespace scene { class ICameraSceneNode; class ISceneNode; }
}
using namespace irr;
#ifndef HEADER_WEATHER_HPP
#define HEADER_WEATHER_HPP
class SFXBase;
class Rain
class Weather
{
PerCameraNode* m_node;
float m_next_lightning;
bool m_lightning;
float m_next_lightning;
SFXBase* m_thunder_sound;
SFXBase* m_weather_sound;
public:
Rain(Camera* camera, irr::scene::ISceneNode* parent);
virtual ~Rain();
Weather(bool lightning, std::string sound);
virtual ~Weather();
void update(float dt);
void setPosition(const irr::core::vector3df& position);
void setCamera(scene::ICameraSceneNode* camera);
void playSound();
};
#endif

View File

@ -491,6 +491,7 @@ void DynamicRibbonWidget::clearItems()
{
m_items.clear();
m_animated_contents = false;
m_scroll_offset = 0;
}
// -----------------------------------------------------------------------------
void DynamicRibbonWidget::elementRemoved()

View File

@ -150,7 +150,7 @@ FileManager::FileManager()
if(exe_path.size()==0 || exe_path[exe_path.size()-1]!='/')
exe_path += "/";
if ( getenv ( "SUPERTUXKART_DATADIR" ) != NULL )
root_dir = std::string(getenv("SUPERTUXKART_DATADIR"))+"/" ;
root_dir = std::string(getenv("SUPERTUXKART_DATADIR"))+"/data/" ;
#ifdef __APPLE__
else if( macSetBundlePathIfRelevant( root_dir ) ) { root_dir = root_dir + "data/"; }
#endif
@ -174,7 +174,7 @@ FileManager::FileManager()
else
{
#ifdef SUPERTUXKART_DATADIR
root_dir = SUPERTUXKART_DATADIR;
root_dir = SUPERTUXKART_DATADIR"/data/";
if(root_dir.size()==0 || root_dir[root_dir.size()-1]!='/')
root_dir+='/';
@ -186,6 +186,8 @@ FileManager::FileManager()
addRootDirs(root_dir);
if( fileExists(root_dir+"../../stk-assets"))
addRootDirs(root_dir+"../../stk-assets");
if( fileExists(root_dir+"../../supertuxkart-assets"))
addRootDirs(root_dir+"../../supertuxkart-assets");
if ( getenv ( "SUPERTUXKART_ROOT_PATH" ) != NULL )
addRootDirs(getenv("SUPERTUXKART_ROOT_PATH"));
@ -736,10 +738,10 @@ void FileManager::checkAndCreateConfigDir()
// Try to use the APPDATA directory to store config files and highscore
// lists. If not defined, used the current directory.
if(getenv("APPDATA")!=NULL)
if (getenv("APPDATA") != NULL)
{
m_user_config_dir = getenv("APPDATA");
if(!checkAndCreateDirectory(m_user_config_dir))
if (!checkAndCreateDirectory(m_user_config_dir))
{
Log::error("[FileManager]", "Can't create config dir '%s"
", falling back to '.'.", m_user_config_dir.c_str());
@ -753,7 +755,7 @@ void FileManager::checkAndCreateConfigDir()
#elif defined(__APPLE__)
if (getenv("HOME")!=NULL)
if (getenv("HOME") != NULL)
{
m_user_config_dir = getenv("HOME");
}
@ -773,8 +775,10 @@ void FileManager::checkAndCreateConfigDir()
// Remaining unix variants. Use the new standards for config directory
// i.e. either XDG_CONFIG_HOME or $HOME/.config
if (getenv("XDG_CONFIG_HOME")!=NULL){
if (getenv("XDG_CONFIG_HOME") !=NULL)
{
m_user_config_dir = getenv("XDG_CONFIG_HOME");
checkAndCreateDirectory(m_user_config_dir);
}
else if (!getenv("HOME"))
{
@ -786,6 +790,8 @@ void FileManager::checkAndCreateConfigDir()
else
{
m_user_config_dir = getenv("HOME");
checkAndCreateDirectory(m_user_config_dir);
m_user_config_dir += "/.config";
if(!checkAndCreateDirectory(m_user_config_dir))
{

View File

@ -121,6 +121,7 @@ World::World() : WorldStatus(), m_clear_color(255,100,101,140)
m_self_destruct = false;
m_schedule_tutorial = false;
m_is_network_world = false;
m_weather = NULL;
m_stop_music_when_dialog_open = true;
@ -195,6 +196,12 @@ void World::init()
ReplayPlay::get()->Load();
powerup_manager->updateWeightsForRace(num_karts);
if (UserConfigParams::m_weather_effects)
{
m_weather = new Weather(m_track->getWeatherLightning(),
m_track->getWeatherSound());
}
} // init
//-----------------------------------------------------------------------------
@ -262,7 +269,6 @@ void World::reset()
//Reset the Rubber Ball Collect Time to some negative value.
powerup_manager->setBallCollectTime(-100);
} // reset
//-----------------------------------------------------------------------------
@ -376,6 +382,9 @@ World::~World()
// gui and this must be deleted.
delete m_race_gui;
}
if (m_weather != NULL)
delete m_weather;
for ( unsigned int i = 0 ; i < m_karts.size() ; i++ )
delete m_karts[i];
@ -925,6 +934,11 @@ void World::update(float dt)
{
Camera::getCamera(i)->update(dt);
}
if (UserConfigParams::m_graphical_effects && m_weather)
{
m_weather->update(dt);
}
projectile_manager->update(dt);

View File

@ -28,6 +28,7 @@
#include <vector>
#include <stdexcept>
#include "graphics/weather.hpp"
#include "modes/world_status.hpp"
#include "race/highscores.hpp"
#include "states_screens/race_gui_base.hpp"
@ -161,6 +162,10 @@ protected:
/** Set when the world is online and counts network players. */
bool m_is_network_world;
/** Used to show weather graphical effects. */
Weather* m_weather;
virtual void onGo();
/** Returns true if the race is over. Must be defined by all modes. */
@ -343,6 +348,9 @@ public:
void setNetworkWorld(bool is_networked) { m_is_network_world = is_networked; }
bool isNetworkWorld() const { return m_is_network_world; }
/** Returns a pointer to the weather. */
Weather* getWeather() {return m_weather;}
}; // World
#endif

View File

@ -44,7 +44,9 @@ WorldStatus::WorldStatus()
m_play_racestart_sounds = true;
IrrlichtDevice *device = irr_driver->getDevice();
if (device->getTimer()->isStopped()) device->getTimer()->start();
if (device->getTimer()->isStopped())
device->getTimer()->start();
} // WorldStatus
//-----------------------------------------------------------------------------
@ -56,13 +58,15 @@ void WorldStatus::reset()
m_auxiliary_timer = 0.0f;
// Using SETUP_PHASE will play the track into sfx first, and has no
// other side effects.
m_phase = UserConfigParams::m_race_now ? RACE_PHASE : SETUP_PHASE;
m_phase = UserConfigParams::m_race_now ? RACE_PHASE : SETUP_PHASE;
m_previous_phase = UNDEFINED_PHASE;
// Just in case that the game is reset during the intro phase
m_track_intro_sound->stop();
IrrlichtDevice *device = irr_driver->getDevice();
if (device->getTimer()->isStopped()) device->getTimer()->start();
if (device->getTimer()->isStopped())
device->getTimer()->start();
} // reset
//-----------------------------------------------------------------------------
@ -74,7 +78,9 @@ WorldStatus::~WorldStatus()
sfx_manager->deleteSFX(m_start_sound);
sfx_manager->deleteSFX(m_track_intro_sound);
IrrlichtDevice *device = irr_driver->getDevice();
if (device->getTimer()->isStopped()) device->getTimer()->start();
if (device->getTimer()->isStopped())
device->getTimer()->start();
} // ~WorldStatus
//-----------------------------------------------------------------------------
@ -96,14 +102,12 @@ void WorldStatus::setClockMode(const ClockType mode, const float initial_time)
void WorldStatus::enterRaceOverState()
{
// Don't enter race over if it's already race over
if( m_phase == DELAY_FINISH_PHASE
|| m_phase == RESULT_DISPLAY_PHASE
|| m_phase == FINISH_PHASE )
if (m_phase == DELAY_FINISH_PHASE || m_phase == RESULT_DISPLAY_PHASE ||
m_phase == FINISH_PHASE)
return;
m_phase = DELAY_FINISH_PHASE;
m_auxiliary_timer = 0.0f;
} // enterRaceOverState
//-----------------------------------------------------------------------------
@ -120,7 +124,7 @@ void WorldStatus::terminateRace()
*/
void WorldStatus::update(const float dt)
{
switch(m_phase)
switch (m_phase)
{
// Note: setup phase must be a separate phase, since the race_manager
// checks the phase when updating the camera: in the very first time
@ -130,10 +134,17 @@ void WorldStatus::update(const float dt)
case SETUP_PHASE:
m_auxiliary_timer = 0.0f;
m_phase = TRACK_INTRO_PHASE;
if (m_play_racestart_sounds)
{
m_track_intro_sound->play();
}
if (World::getWorld()->getWeather() != NULL)
{
World::getWorld()->getWeather()->playSound();
}
return;
case TRACK_INTRO_PHASE:
m_auxiliary_timer += dt;
@ -141,7 +152,9 @@ void WorldStatus::update(const float dt)
if (UserConfigParams::m_artist_debug_mode &&
race_manager->getNumberOfKarts() == 1 &&
race_manager->getTrackName() != "tutorial")
{
m_auxiliary_timer += dt * 6;
}
// Work around a bug that occurred on linux once:
// the sfx_manager kept on reporting that it is playing,
@ -149,61 +162,86 @@ void WorldStatus::update(const float dt)
// ... phase. Since the sound effect is about 3 seconds
// long, we use the aux timer to force the next phase
// after 3.5 seconds.
if(m_track_intro_sound->getStatus()==SFXManager::SFX_PLAYING
&& m_auxiliary_timer<3.5f)
if (m_track_intro_sound->getStatus() == SFXManager::SFX_PLAYING &&
m_auxiliary_timer < 3.5f)
return;
// Wait before ready phase if sounds are disabled
if(!UserConfigParams::m_sfx && m_auxiliary_timer<3.0f)
if (!UserConfigParams::m_sfx && m_auxiliary_timer < 3.0f)
return;
m_auxiliary_timer = 0.0f;
if (m_play_racestart_sounds) m_prestart_sound->play();
if (m_play_racestart_sounds)
m_prestart_sound->play();
m_phase = READY_PHASE;
for(unsigned int i=0; i<World::getWorld()->getNumKarts(); i++)
for (unsigned int i = 0; i < World::getWorld()->getNumKarts(); i++)
{
World::getWorld()->getKart(i)->startEngineSFX();
}
break;
case READY_PHASE:
if(m_auxiliary_timer>1.0)
if (m_auxiliary_timer > 1.0)
{
if (m_play_racestart_sounds) m_prestart_sound->play();
m_phase=SET_PHASE;
if (m_play_racestart_sounds)
{
m_prestart_sound->play();
}
m_phase = SET_PHASE;
}
m_auxiliary_timer += dt;
// In artist debug mode, when without opponents, skip the ready/set/go counter faster
if (UserConfigParams::m_artist_debug_mode &&
race_manager->getNumberOfKarts() == 1 &&
race_manager->getTrackName() != "tutorial")
{
m_auxiliary_timer += dt*6;
}
return;
case SET_PHASE :
if(m_auxiliary_timer>2.0)
case SET_PHASE:
if (m_auxiliary_timer > 2.0)
{
// set phase is over, go to the next one
m_phase=GO_PHASE;
if (m_play_racestart_sounds) m_start_sound->play();
m_phase = GO_PHASE;
if (m_play_racestart_sounds)
{
m_start_sound->play();
}
World::getWorld()->getTrack()->startMusic();
// event
onGo();
}
m_auxiliary_timer += dt;
// In artist debug mode, when without opponents, skip the ready/set/go counter faster
if (UserConfigParams::m_artist_debug_mode &&
race_manager->getNumberOfKarts() == 1 &&
race_manager->getTrackName() != "tutorial")
{
m_auxiliary_timer += dt*6;
}
return;
case GO_PHASE :
if (m_auxiliary_timer>2.5f && music_manager->getCurrentMusic())
music_manager->startMusic(music_manager->getCurrentMusic());
if(m_auxiliary_timer>3.0f) // how long to display the 'go' message
{
m_phase=MUSIC_PHASE;
music_manager->startMusic(music_manager->getCurrentMusic());
}
if (m_auxiliary_timer > 3.0f) // how long to display the 'go' message
{
m_phase = MUSIC_PHASE;
}
m_auxiliary_timer += dt;
@ -212,31 +250,38 @@ void WorldStatus::update(const float dt)
if (UserConfigParams::m_artist_debug_mode &&
race_manager->getNumberOfKarts() == 1 &&
race_manager->getTrackName() != "tutorial")
{
m_auxiliary_timer += dt*6;
}
break;
case MUSIC_PHASE:
// how long to display the 'music' message
if(m_auxiliary_timer>stk_config->m_music_credit_time)
m_phase=RACE_PHASE;
if (m_auxiliary_timer>stk_config->m_music_credit_time)
{
m_phase = RACE_PHASE;
}
m_auxiliary_timer += dt;
break;
case RACE_PHASE:
// Nothing to do for race phase, switch to delay finish phase
// happens when
break;
case DELAY_FINISH_PHASE :
case DELAY_FINISH_PHASE:
{
m_auxiliary_timer += dt;
// Change to next phase if delay is over
if(m_auxiliary_timer > stk_config->m_delay_finish_time)
if (m_auxiliary_timer > stk_config->m_delay_finish_time)
{
m_phase = RESULT_DISPLAY_PHASE;
terminateRace();
}
break;
}
case RESULT_DISPLAY_PHASE :
case RESULT_DISPLAY_PHASE:
{
break;
}
@ -249,7 +294,7 @@ void WorldStatus::update(const float dt)
default: break;
}
switch(m_clock_mode)
switch (m_clock_mode)
{
case CLOCK_CHRONO:
m_time += dt;
@ -290,11 +335,14 @@ void WorldStatus::setTime(const float time)
*/
void WorldStatus::pause(Phase phase)
{
assert(m_previous_phase==UNDEFINED_PHASE);
assert(m_previous_phase == UNDEFINED_PHASE);
m_previous_phase = m_phase;
m_phase = phase;
IrrlichtDevice *device = irr_driver->getDevice();
if (!device->getTimer()->isStopped()) device->getTimer()->stop();
if (!device->getTimer()->isStopped())
device->getTimer()->stop();
} // pause
//-----------------------------------------------------------------------------
@ -307,5 +355,7 @@ void WorldStatus::unpause()
// in pause to detect incorrect pause/unpause sequences.
m_previous_phase = UNDEFINED_PHASE;
IrrlichtDevice *device = irr_driver->getDevice();
if (device->getTimer()->isStopped()) device->getTimer()->start();
if (device->getTimer()->isStopped())
device->getTimer()->start();
} // unpause

View File

@ -117,7 +117,10 @@ ClientNetworkManager::ClientNetworkManager()
ClientNetworkManager::~ClientNetworkManager()
{
pthread_cancel(*m_thread_keyboard);
// On windows in release mode there is no console, and the
// thread is not created.
if(m_thread_keyboard)
pthread_cancel(*m_thread_keyboard);
}
void ClientNetworkManager::run()
@ -133,10 +136,17 @@ void ClientNetworkManager::run()
Log::info("ClientNetworkManager", "Host initialized.");
// On windows in release mode the console is suppressed, so nothing can
// be read from std::cin. Since getline(std::cin,...) then returns
// an empty string, the waitInput thread is running all the time, consuming
// CPU. Therefore don't start the console thread in this case.
#if defined(WIN32) && defined(_MSC_VER) && !defined(DEBUG)
m_thread_keyboard = NULL;
#else
// listen keyboard console input
m_thread_keyboard = (pthread_t*)(malloc(sizeof(pthread_t)));
pthread_create(m_thread_keyboard, NULL, waitInput, NULL);
#endif
NetworkManager::run();
Log::info("ClientNetworkManager", "Ready !");

View File

@ -28,6 +28,11 @@
#include "utils/random_generator.hpp"
#include <assert.h>
#ifdef __MINGW32__
# define _WIN32_WINNT 0x501
#endif
#ifdef WIN32
# include <winsock2.h>
# include <ws2tcpip.h>
@ -36,6 +41,7 @@
#endif
#include <sys/types.h>
int stunRand()
{
static bool init = false;

View File

@ -24,9 +24,16 @@
#include "utils/time.hpp"
#include <string.h>
#ifdef WIN32
#if defined(WIN32) && !defined(__MINGW32__)
# include "Ws2tcpip.h"
# define inet_ntop InetNtop
// TODO: It's very ugly hack which allows to compile STK on windows using gcc.
// Solution would be nice seen.
#elif defined(__MINGW32__)
# include "Ws2tcpip.h"
# define inet_ntop
#else
# include <arpa/inet.h>
# include <errno.h>

View File

@ -25,7 +25,6 @@ using namespace irr;
#include "graphics/material_manager.hpp"
#include "graphics/mesh_tools.hpp"
#include "graphics/stkinstancedscenenode.hpp"
#include "io/file_manager.hpp"
#include "io/xml_node.hpp"
#include "modes/world.hpp"
@ -241,16 +240,6 @@ void PhysicalObject::init()
Log::fatal("PhysicalObject", "Unknown node type");
}
}
else if (dynamic_cast<TrackObjectPresentationInstancing*>(presentation) != NULL)
{
TrackObjectPresentationInstancing* instancing = dynamic_cast<TrackObjectPresentationInstancing*>(presentation);
STKInstancedSceneNode* instancing_group = instancing->getInstancingGroup();
if (instancing_group != NULL)
{
scene::IMesh* mesh = instancing_group->getMesh();
MeshTools::minMax3D(mesh, &min, &max);
}
}
else
{
Log::fatal("PhysicalObject", "Unknown node type");

View File

@ -22,7 +22,6 @@ using namespace irr;
#include "graphics/irr_driver.hpp"
#include "graphics/lod_node.hpp"
#include "graphics/mesh_tools.hpp"
#include "graphics/stkinstancedscenenode.hpp"
#include "io/xml_node.hpp"
#include "tracks/track.hpp"
@ -111,35 +110,6 @@ LODNode* ModelDefinitionLoader::instanciateAsLOD(const XMLNode* node, scene::ISc
// ----------------------------------------------------------------------------
STKInstancedSceneNode* ModelDefinitionLoader::instanciate(const irr::core::vector3df& position,
const irr::core::vector3df& rotation,
const irr::core::vector3df scale,
const std::string& name)
{
if (m_instancing_nodes.find(name) == m_instancing_nodes.end())
{
if (m_lod_groups.find(name) == m_lod_groups.end())
{
Log::warn("Instancing", "Cannot find instancing model <%s>", name.c_str());
return NULL;
}
scene::IMesh* mesh = irr_driver->getMesh(m_lod_groups[name][0].m_model_file);
mesh = MeshTools::createMeshWithTangents(mesh, &MeshTools::isNormalMap);
irr_driver->setAllMaterialFlags(mesh);
m_instancing_nodes[name] = new STKInstancedSceneNode(mesh,
irr_driver->getSceneManager()->getRootSceneNode(), irr_driver->getSceneManager(), -1);
m_track->addNode(m_instancing_nodes[name]);
}
m_instancing_nodes[name]->addInstance(position, rotation, scale);
m_instancing_nodes[name]->instanceGrab();
return m_instancing_nodes[name];
}
// ----------------------------------------------------------------------------
void ModelDefinitionLoader::clear()
{
m_lod_groups.clear();

View File

@ -83,10 +83,6 @@ public:
void addModelDefinition(const XMLNode* xml);
LODNode* instanciateAsLOD(const XMLNode* xml_node, scene::ISceneNode* parent);
STKInstancedSceneNode* instanciate(const core::vector3df& position,
const irr::core::vector3df& rotation,
const irr::core::vector3df scale,
const std::string& name);
void clear();

View File

@ -37,7 +37,6 @@
#include "graphics/particle_emitter.hpp"
#include "graphics/particle_kind.hpp"
#include "graphics/particle_kind_manager.hpp"
#include "graphics/stkinstancedscenenode.hpp"
#include "graphics/stk_text_billboard.hpp"
#include "guiengine/scalable_font.hpp"
#include "io/file_manager.hpp"
@ -132,7 +131,10 @@ Track::Track(const std::string &filename)
m_sky_particles = NULL;
m_sky_dx = 0.05f;
m_sky_dy = 0.0f;
m_weather_type = WEATHER_NONE;
m_godrays_opacity = 1.0f;
m_godrays_color = video::SColor(255, 255, 255, 255);
m_weather_lightning = false;
m_weather_sound = "";
m_cache_track = UserConfigParams::m_cache_overworld &&
m_ident=="overworld";
m_minimap_x_scale = 1.0f;
@ -439,6 +441,9 @@ void Track::loadTrackInfo()
m_fog_height_end = 100.0f;
m_gravity = 9.80665f;
m_smooth_normals = false;
m_godrays = false;
m_godrays_opacity = 1.0f;
m_godrays_color = video::SColor(255, 255, 255, 255);
/* ARGB */
m_fog_color = video::SColor(255, 77, 179, 230);
m_default_ambient_color = video::SColor(255, 120, 120, 120);
@ -481,7 +486,6 @@ void Track::loadTrackInfo()
root->get("bloom-threshold", &m_bloom_threshold);
root->get("lens-flare", &m_lensflare);
root->get("shadows", &m_shadows);
root->get("god-rays", &m_godrays);
root->get("displacement-speed", &m_displacement_speed);
root->get("caustics-speed", &m_caustics_speed);
root->get("color-level-in", &m_color_inlevel);
@ -737,24 +741,10 @@ void Track::convertTrackToBullet(scene::ISceneNode *node)
node->updateAbsolutePosition();
std::vector<core::matrix4> matrices;
STKInstancedSceneNode* instancing_node = dynamic_cast<STKInstancedSceneNode*>(node);
if (instancing_node != NULL)
{
int count = instancing_node->getInstanceCount();
for (int i = 0; i < count; i++)
{
matrices.push_back(instancing_node->getInstanceTransform(i));
}
}
else
{
matrices.push_back(node->getAbsoluteTransformation());
}
matrices.push_back(node->getAbsoluteTransformation());
const core::vector3df &pos = node->getAbsolutePosition();
scene::IMesh *mesh;
// In case of readonly materials we have to get the material from
// the mesh, otherwise from the node. This is esp. important for
@ -1058,20 +1048,6 @@ bool Track::loadMainTrack(const XMLNode &root)
}
}
// Load instancing models (for the moment they are loaded the same way as LOD to simplify implementation)
const XMLNode *instancing_xml_node = root.getNode("instancing");
if (instancing_xml_node != NULL)
{
for (unsigned int i = 0; i < instancing_xml_node->getNumNodes(); i++)
{
const XMLNode* lod_group_xml = instancing_xml_node->getNode(i);
for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++)
{
lodLoader.addModelDefinition(lod_group_xml->getNode(j));
}
}
}
for (unsigned int i=0; i<track_node->getNumNodes(); i++)
{
const XMLNode *n=track_node->getNode(i);
@ -1724,6 +1700,14 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
node->get("fog-end-height", &m_fog_height_end);
}
if (const XMLNode *node = root->getNode("lightshaft"))
{
m_godrays = true;
node->get("opacity", &m_godrays_opacity);
node->get("color", &m_godrays_color);
node->get("xyz", &m_godrays_position);
}
loadMainTrack(*root);
unsigned int main_track_count = m_all_nodes.size();
@ -1743,20 +1727,6 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
}
}
// Load instancing models (for the moment they are loaded the same way as LOD to simplify implementation)
const XMLNode *instancing_xml_node = root->getNode("instancing");
if (instancing_xml_node != NULL)
{
for (unsigned int i = 0; i < instancing_xml_node->getNumNodes(); i++)
{
const XMLNode* lod_group_xml = instancing_xml_node->getNode(i);
for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++)
{
model_def_loader.addModelDefinition(lod_group_xml->getNode(j));
}
}
}
std::map<std::string, XMLNode*> library_nodes;
loadObjects(root, path, model_def_loader, true, NULL, library_nodes);
@ -1997,20 +1967,6 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
}
}
}
// Load instancing definitions
const XMLNode *instancing_xml_node = libroot->getNode("instancing");
if (instancing_xml_node != NULL)
{
for (unsigned int i = 0; i < instancing_xml_node->getNumNodes(); i++)
{
const XMLNode* instancing_group_xml = instancing_xml_node->getNode(i);
for (unsigned int j = 0; j < instancing_group_xml->getNumNodes(); j++)
{
model_def_loader.addModelDefinition(instancing_group_xml->getNode(j));
}
}
}
}
else
{
@ -2089,27 +2045,16 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
else if (name == "weather")
{
std::string weather_particles;
std::string weather_type;
node->get("particles", &weather_particles);
node->get("type", &weather_type);
node->get("lightning", &m_weather_lightning);
node->get("sound", &m_weather_sound);
if (weather_particles.size() > 0)
{
m_sky_particles =
ParticleKindManager::get()->getParticles(weather_particles);
}
else if (weather_type.size() > 0)
{
if (weather_type == "rain")
{
m_weather_type = WEATHER_RAIN;
}
else
{
Log::error("track", "Unknown weather type : '%s'",
weather_type.c_str());
}
}
else
{
Log::error("track", "Bad weather node found - ignored.\n");
@ -2126,7 +2071,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
}
else if (name == "instancing")
{
// handled above
// TODO: eventually remove, this is now automatic
}
else if (name == "subtitles")
{

View File

@ -62,12 +62,6 @@ class XMLNode;
const int HEIGHT_MAP_RESOLUTION = 256;
enum WeatherType
{
WEATHER_NONE,
WEATHER_RAIN
};
struct OverworldForceField
{
core::vector3df m_position;
@ -310,7 +304,8 @@ private:
ParticleKind* m_sky_particles;
/** Use a special built-in wheather */
WeatherType m_weather_type;
bool m_weather_lightning;
std::string m_weather_sound;
/** A simple class to keep information about a track mode. */
class TrackMode
@ -383,7 +378,12 @@ private:
float m_bloom_threshold;
bool m_lensflare;
bool m_godrays;
core::vector3df m_godrays_position;
float m_godrays_opacity;
video::SColor m_godrays_color;
bool m_shadows;
float m_displacement_speed;
@ -570,7 +570,9 @@ public:
unsigned int getNumberOfStartPositions() const
{ return m_start_transforms.size(); }
// ------------------------------------------------------------------------
WeatherType getWeatherType () const { return m_weather_type; }
bool getWeatherLightning() {return m_weather_lightning;}
// ------------------------------------------------------------------------
std::string getWeatherSound() {return m_weather_sound;}
// ------------------------------------------------------------------------
ParticleKind* getSkyParticles () { return m_sky_particles; }
// ------------------------------------------------------------------------
@ -622,6 +624,9 @@ public:
bool hasLensFlare() const { return m_lensflare; }
bool hasGodRays() const { return m_godrays; }
core::vector3df getGodRaysPosition() const { return m_godrays_position; }
float getGodRaysOpacity() const { return m_godrays_opacity; }
video::SColor getGodRaysColor() const { return m_godrays_color; }
bool hasShadows() const { return m_shadows; }
void addNode(scene::ISceneNode* node) { m_all_nodes.push_back(node); }

View File

@ -103,9 +103,6 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
bool lod_instance = false;
xml_node.get("lod_instance", &lod_instance);
bool instancing = false;
xml_node.get("instancing", &instancing);
m_soccer_ball = false;
xml_node.get("soccer_ball", &m_soccer_ball);
@ -159,14 +156,7 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
{
scene::ISceneNode *glownode = NULL;
if (instancing)
{
m_type = "lod";
TrackObjectPresentationInstancing* instancing_node =
new TrackObjectPresentationInstancing(xml_node, parent, model_def_loader);
m_presentation = instancing_node;
}
else if (lod_instance)
if (lod_instance)
{
m_type = "lod";
TrackObjectPresentationLOD* lod_node =

View File

@ -28,7 +28,6 @@
#include "graphics/particle_emitter.hpp"
#include "graphics/particle_kind_manager.hpp"
#include "graphics/stkmeshscenenode.hpp"
#include "graphics/stkinstancedscenenode.hpp"
#include "io/file_manager.hpp"
#include "io/xml_node.hpp"
#include "input/device_manager.hpp"
@ -168,59 +167,6 @@ TrackObjectPresentationLOD::~TrackObjectPresentationLOD()
// ----------------------------------------------------------------------------
TrackObjectPresentationInstancing::TrackObjectPresentationInstancing(const XMLNode& xml_node,
scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader) : TrackObjectPresentationSceneNode(xml_node)
{
m_instancing_group = NULL;
m_fallback_scene_node = NULL;
std::string instancing_model;
xml_node.get("instancing_model", &instancing_model);
m_node = irr_driver->getSceneManager()->addEmptySceneNode(parent);
m_node->setPosition(m_init_xyz);
m_node->setRotation(m_init_hpr);
m_node->setScale(m_init_scale);
m_node->updateAbsolutePosition();
if (irr_driver->isGLSL())
{
m_instancing_group = model_def_loader.instanciate(m_node->getAbsolutePosition(),
m_node->getAbsoluteTransformation().getRotationDegrees(), m_node->getAbsoluteTransformation().getScale(),
instancing_model);
}
else
{
scene::IMesh* mesh = model_def_loader.getFirstMeshFor(instancing_model);
scene::IMeshSceneNode* node = irr_driver->addMesh(mesh, m_node);
node->grab();
irr_driver->grabAllTextures(mesh);
mesh->grab();
World::getWorld()->getTrack()->addNode(node);
m_fallback_scene_node = node;
}
}
TrackObjectPresentationInstancing::~TrackObjectPresentationInstancing()
{
if (m_instancing_group != NULL)
m_instancing_group->instanceDrop();
if (m_fallback_scene_node != NULL)
{
scene::IMesh* mesh = m_fallback_scene_node->getMesh();
irr_driver->dropAllTextures(mesh);
mesh->drop();
if (mesh->getReferenceCount() == 1)
irr_driver->removeMeshFromCache(mesh);
m_fallback_scene_node->drop();
}
}
// ----------------------------------------------------------------------------
TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node,
bool enabled, scene::ISceneNode* parent) :
TrackObjectPresentationSceneNode(xml_node)

View File

@ -167,20 +167,6 @@ public:
virtual ~TrackObjectPresentationLOD();
};
class TrackObjectPresentationInstancing : public TrackObjectPresentationSceneNode
{
STKInstancedSceneNode* m_instancing_group;
scene::IMeshSceneNode* m_fallback_scene_node;
public:
TrackObjectPresentationInstancing(const XMLNode& xml_node,
scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader);
virtual ~TrackObjectPresentationInstancing();
STKInstancedSceneNode* getInstancingGroup() { return m_instancing_group; }
};
/**
* \ingroup tracks
* A track object representation that consists of a mesh scene node.

View File

@ -33,6 +33,7 @@ static const char* GPU_Phase[Q_LAST] =
{
"Solid Pass 1",
"Shadows",
"RSM",
"RH",
"GI",
"Env Map",
@ -352,26 +353,27 @@ void Profiler::draw()
}
}
// GPU profiler
QueryPerf hovered_gpu_marker = Q_LAST;
long hovered_gpu_marker_elapsed = 0;
int gpu_y = int(y_offset + nb_thread_infos*line_height + line_height/2);
float total = 0;
for (unsigned i = 0; i < Q_LAST; i++)
{
total += irr_driver->getGPUTimer(i).elapsedTimeus();
}
static video::SColor colors[] = {
video::SColor(255, 255, 0, 0),
video::SColor(255, 0, 255, 0),
video::SColor(255, 0, 0, 255),
video::SColor(255, 255, 255, 0),
video::SColor(255, 255, 0, 255),
video::SColor(255, 0, 255, 255)
};
if (hovered_markers.size() == 0)
{
int gpu_y = int(y_offset + nb_thread_infos*line_height + line_height/2);
float total = 0;
for (unsigned i = 0; i < Q_LAST; i++)
{
total += irr_driver->getGPUTimer(i).elapsedTimeus();
}
static video::SColor colors[] = {
video::SColor(255, 255, 0, 0),
video::SColor(255, 0, 255, 0),
video::SColor(255, 0, 0, 255),
video::SColor(255, 255, 255, 0),
video::SColor(255, 255, 0, 255),
video::SColor(255, 0, 255, 255)
};
float curr_val = 0;
for (unsigned i = 0; i < Q_LAST; i++)
{
@ -421,7 +423,7 @@ void Profiler::draw()
// Draw the hovered markers' names
gui::ScalableFont* font = GUIEngine::getFont();
if(font)
if (font)
{
core::stringw text;
while(!hovered_markers.empty())

View File

@ -11,3 +11,7 @@
# define round(x) (floorf(x + 0.5))
#endif
#ifdef __MINGW32__
#include <cmath>
using std::isnan;
#endif