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,10 +15,10 @@ 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),
# which also needs an absolute path :(
@ -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()
@ -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()
@ -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)
elseif(WIN32)
if(MSVC)
add_definitions("/DWIIUSE_STATIC")
else()
add_definitions("-DWIIUSE_STATIC")
endif()
if(WIIUSE_BUILD)
target_link_libraries(supertuxkart wiiuse)
else()
@ -302,7 +322,7 @@ 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
@ -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

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

@ -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

View File

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

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")

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,8 +664,17 @@ void VAOManager::regenerateBuffer(enum VTXTYPE tp)
glDeleteBuffers(1, &vbo[tp]);
glGenBuffers(1, &vbo[tp]);
glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]);
#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]);
glGenBuffers(1, &ibo[tp]);
@ -727,14 +757,12 @@ 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,30 +779,66 @@ 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)));
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);
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;
mesh.VAOType = mb->getVertexType();
}
else
{
fillLocalBuffer(mesh, mb);
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
glBindVertexArray(0);
}
}
}
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;
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);
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);
@ -293,3 +295,47 @@ bool isObject(video::E_MATERIAL_TYPE type)
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));
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,47 +264,11 @@ 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));
@ -278,7 +282,55 @@ 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)
{
irr_driver->IncreaseObjectCount();
GLMesh &mesh = GLmeshes[i];
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
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);
}
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);
@ -289,9 +341,6 @@ void STKMeshSceneNode::render()
return;
}
return;
}
if (irr_driver->getPhase() == GLOW_PASS)
{
glUseProgram(MeshShader::ColorizeShader::getInstance()->Program);
@ -300,12 +349,15 @@ void STKMeshSceneNode::render()
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
if (!mb)
continue;
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);
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,61 +18,48 @@
#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");
}
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_thunder_sound != NULL)
sfx_manager->deleteSFX(m_thunder_sound);
if (m_lightning && 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)
{
@ -81,29 +68,30 @@ void Rain::update(float 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)
if (m_weather_sound)
{
// m_node->setCamera(camera);
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"));
@ -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
//-----------------------------------------------------------------------------
@ -377,6 +383,9 @@ World::~World()
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];
@ -926,6 +935,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);
PROFILER_POP_CPU_MARKER();

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"
@ -162,6 +163,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. */
virtual bool isRaceOver() = 0;
@ -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
//-----------------------------------------------------------------------------
@ -62,7 +64,9 @@ void WorldStatus::reset()
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
//-----------------------------------------------------------------------------
@ -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,57 +162,82 @@ 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)
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++)
{
World::getWorld()->getKart(i)->startEngineSFX();
}
break;
case READY_PHASE:
if (m_auxiliary_timer > 1.0)
{
if (m_play_racestart_sounds) m_prestart_sound->play();
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)
{
// set phase is over, go to the next one
m_phase = GO_PHASE;
if (m_play_racestart_sounds) m_start_sound->play();
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
{
@ -212,12 +250,18 @@ 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;
}
m_auxiliary_timer += dt;
break;
case RACE_PHASE:
@ -234,6 +278,7 @@ void WorldStatus::update(const float dt)
m_phase = RESULT_DISPLAY_PHASE;
terminateRace();
}
break;
}
case RESULT_DISPLAY_PHASE:
@ -291,10 +336,13 @@ void WorldStatus::setTime(const float time)
void WorldStatus::pause(Phase 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,6 +117,9 @@ ClientNetworkManager::ClientNetworkManager()
ClientNetworkManager::~ClientNetworkManager()
{
// On windows in release mode there is no console, and the
// thread is not created.
if(m_thread_keyboard)
pthread_cancel(*m_thread_keyboard);
}
@ -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());
}
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,10 +353,9 @@ void Profiler::draw()
}
}
// GPU profiler
QueryPerf hovered_gpu_marker = Q_LAST;
long hovered_gpu_marker_elapsed = 0;
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++)
@ -372,6 +372,8 @@ void Profiler::draw()
video::SColor(255, 0, 255, 255)
};
if (hovered_markers.size() == 0)
{
float curr_val = 0;
for (unsigned i = 0; i < Q_LAST; i++)
{

View File

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