Merge remote-tracking branch 'remotes/upstrem/master' into hd-textures-option

Conflicts:
	src/graphics/glwrap.cpp
This commit is contained in:
Guillaume P 2014-05-08 18:40:14 +02:00
commit deb74f4a00
44 changed files with 959 additions and 960 deletions

View File

@ -316,13 +316,13 @@ install(FILES data/supertuxkart_32.png data/supertuxkart_128.png DESTINATION sha
install(FILES data/supertuxkart.appdata DESTINATION share/appdata) install(FILES data/supertuxkart.appdata DESTINATION share/appdata)
# ==== Checking if data folder exists ==== # ==== Checking if data folder exists ====
if(NOT IS_DIRECTORY ../data) if(NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data)
message( FATAL_ERROR "${CMAKE_CURRENT_SOURCE_DIR}/data folder doesn't exist" ) message( FATAL_ERROR "${CMAKE_CURRENT_SOURCE_DIR}/data folder doesn't exist" )
endif() endif()
# ==== Checking if stk-assets folder exists ==== # ==== Checking if stk-assets folder exists ====
if(CHECK_ASSETS) if(CHECK_ASSETS)
if(NOT IS_DIRECTORY ../../stk-assets) if(NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../stk-assets)
set (CUR_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set (CUR_DIR ${CMAKE_CURRENT_SOURCE_DIR})
get_filename_component(PARENT_DIR ${CUR_DIR} PATH) get_filename_component(PARENT_DIR ${CUR_DIR} PATH)
message( FATAL_ERROR "${PARENT_DIR}/stk-assets folder doesn't exist. " message( FATAL_ERROR "${PARENT_DIR}/stk-assets folder doesn't exist. "

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -69,10 +69,10 @@ void main()
col += texture2D(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.4); col += texture2D(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(0.0, 0.4) * offset) * blur * 0.4); col += texture2D(tex, uv + (vec2(0.0, 0.4) * offset) * blur * 0.4);
col.rgb = col.rgb / 41.0; col = vec4(col.rgb / 41.0, col.a);
depth = clamp((FragPos.z/280), 0., 1.); depth = clamp((FragPos.z/280), 0., 1.);
depth = (1 - depth); depth = (1 - depth);
vec3 final = colOriginal.rgb * depth + col.rgb * (1 - depth); vec3 final = colOriginal.rgb * depth + col.rgb * (1 - depth);
/* /*
FragColor.xyz = vec3(depth); FragColor.xyz = vec3(depth);

View File

@ -1,3 +1,12 @@
layout (std140) uniform MatrixesData
{
mat4 ViewMatrix;
mat4 ProjectionMatrix;
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
};
in vec3 Origin; in vec3 Origin;
in vec3 Orientation; in vec3 Orientation;
in vec3 Scale; in vec3 Scale;
@ -5,7 +14,12 @@ in vec3 Scale;
in vec3 Position; in vec3 Position;
in vec2 Texcoord; in vec2 Texcoord;
#ifdef VSLayer
out vec2 uv;
#else
out vec2 tc; out vec2 tc;
out int layerId;
#endif
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
@ -13,6 +27,13 @@ mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
void main(void) void main(void)
{ {
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale); mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
gl_Position = ModelMatrix * vec4(Position, 1.); #ifdef VSLayer
gl_Layer = gl_InstanceID & 3;
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.);
uv = Texcoord;
#else
layerId = gl_InstanceID & 3;
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.);
tc = Texcoord; tc = Texcoord;
#endif
} }

View File

@ -45,7 +45,10 @@ void main()
vec3 light_pos = pseudocenter.xyz; vec3 light_pos = pseudocenter.xyz;
vec3 light_col = col.xyz; vec3 light_col = col.xyz;
float d = distance(light_pos, xpos.xyz); float d = distance(light_pos, xpos.xyz);
float att = energy * 200. / (1. + 33. * d + 33. * d * d); float att = energy * 20. / (1. + d * d);
float max_d = 5. * energy;
att *= (max_d - d) / max_d;
if (att <= 0.) discard;
// Light Direction // Light Direction
vec3 L = -normalize(xpos.xyz - light_pos); vec3 L = -normalize(xpos.xyz - light_pos);

View File

@ -18,35 +18,105 @@ in vec3 Position;
in float Energy; in float Energy;
in vec3 Color; in vec3 Color;
in vec2 Corner;
flat out vec3 center; flat out vec3 center;
flat out float energy; flat out float energy;
flat out vec3 col; flat out vec3 col;
const float zNear = 1.; const float zNear = 1.;
void main(void) // Code borrowed from https://software.intel.com/en-us/articles/deferred-rendering-for-current-and-future-rendering-pipelines
// Maths explanations are found here http://www.gamasutra.com/view/feature/131351/the_mechanics_of_robust_stencil_.php?page=6
vec2 UpdateClipRegionRoot(float nc, /* Tangent plane x/y normal coordinate (view space) */
float lc, /* Light x/y coordinate (view space) */
float lz, /* Light z coordinate (view space) */
float lightRadius,
float cameraScale /* Project scale for coordinate (_11 or _22 for x/y respectively) */)
{ {
// Beyond that value, light is too attenuated float nz = (lightRadius - nc * lc) / lz;
float r = 100 * Energy; float pz = (lc * lc + lz * lz - lightRadius * lightRadius) /
center = Position; (lz - (nz / nc) * lc);
energy = Energy;
vec4 Center = ViewMatrix * vec4(Position, 1.); if (pz > 0.) {
vec4 ProjectedCornerPosition = ProjectionMatrix * (Center + r * vec4(Corner, 0., 0.)); float c = -nz * cameraScale / nc;
float adjustedDepth = ProjectedCornerPosition.z; if (nc > 0.) // Left side boundary
if (Center.z > zNear) // Light is in front of the cam return vec2(c, 1.);
{ else // Right side boundary
adjustedDepth = max(Center.z - r, zNear); return vec2(-1., c);
} }
else if (Center.z + r > zNear) // Light is behind the cam but in range return vec2(-1., 1.);
{ }
adjustedDepth = zNear;
vec2 UpdateClipRegion(float lc, /* Light x/y coordinate (view space) */
float lz, /* Light z coordinate (view space) */
float lightRadius,
float cameraScale /* Project scale for coordinate (_11 or _22 for x/y respectively) */)
{
float rSq = lightRadius * lightRadius;
float lcSqPluslzSq = lc * lc + lz * lz;
float d = rSq * lc * lc - lcSqPluslzSq * (rSq - lz * lz);
// The camera is inside lignt bounding sphere, quad fits whole screen
if (d <= 0.)
return vec2(-1., 1.);
float a = lightRadius * lc;
float b = sqrt(d);
float nx0 = (a + b) / lcSqPluslzSq;
float nx1 = (a - b) / lcSqPluslzSq;
vec2 clip0 = UpdateClipRegionRoot(nx0, lc, lz, lightRadius, cameraScale);
vec2 clip1 = UpdateClipRegionRoot(nx1, lc, lz, lightRadius, cameraScale);
return vec2(max(clip0.x, clip1.x), min(clip0.y, clip1.y));
}
// Returns bounding box [min.x, max.x, min.y, max.y] in clip [-1, 1] space.
vec4 ComputeClipRegion(vec3 lightPosView, float lightRadius)
{
if (lightPosView.z + lightRadius >= zNear) {
vec2 clipX = UpdateClipRegion(lightPosView.x, lightPosView.z, lightRadius, ProjectionMatrix[0][0]);
vec2 clipY = UpdateClipRegion(lightPosView.y, lightPosView.z, lightRadius, ProjectionMatrix[1][1]);
return vec4(clipX, clipY);
} }
ProjectedCornerPosition /= ProjectedCornerPosition.w; return vec4(0.);
ProjectedCornerPosition.zw = (ProjectionMatrix * vec4(0., 0., adjustedDepth, 1.)).zw; }
ProjectedCornerPosition.xy *= ProjectedCornerPosition.w;
col = Color;
gl_Position = ProjectedCornerPosition; void main(void)
{
float radius = 5. * Energy;
vec4 Center = ViewMatrix * vec4(Position, 1.);
Center /= Center.w;
vec2 ProjectedCornerPosition;
vec4 clip = ComputeClipRegion(Center.xyz, radius);
switch (gl_VertexID)
{
case 0:
ProjectedCornerPosition = clip.xz;
break;
case 1:
ProjectedCornerPosition = clip.xw;
break;
case 2:
ProjectedCornerPosition = clip.yz;
break;
case 3:
ProjectedCornerPosition = clip.yw;
break;
}
// Work out nearest depth for quad Z
// Clamp to near plane in case this light intersects the near plane... don't want our quad to be clipped
float quadDepth = max(zNear, Center.z - radius);
// Project quad depth into clip space
vec4 quadClip = ProjectionMatrix * vec4(0., 0., quadDepth, 1.0f);
gl_Position = vec4(ProjectedCornerPosition, quadClip.z / quadClip.w, 1.);
col = Color;
center = Position;
energy = Energy;
} }

View File

@ -1,43 +1,19 @@
layout (std140) uniform MatrixesData
{
mat4 ViewMatrix;
mat4 ProjectionMatrix;
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
};
#if __VERSION__ >= 400
layout(triangles, invocations=4) in;
#else
layout(triangles) in; layout(triangles) in;
#endif layout(triangle_strip, max_vertices=3) out;
layout(triangle_strip, max_vertices=12) out;
in vec2 tc[3]; in vec2 tc[3];
in int layerId[3];
out vec2 uv; out vec2 uv;
void emitToLayer(int layerId) void main(void)
{ {
gl_Layer = layerId; gl_Layer = layerId[0];
for(int i=0; i<3; i++) for(int i=0; i<3; i++)
{ {
uv = tc[i]; uv = tc[i];
gl_Position = ShadowViewProjMatrixes[layerId] * gl_in[i].gl_Position; gl_Position = gl_in[i].gl_Position;
EmitVertex(); EmitVertex();
} }
EndPrimitive(); EndPrimitive();
} }
void main(void)
{
#if __VERSION__ >= 400
emitToLayer(gl_InvocationID);
#else
for (int j = 0; j<4; j++)
{
emitToLayer(j);
}
#endif
}

View File

@ -1,12 +1,33 @@
layout (std140) uniform MatrixesData
{
mat4 ViewMatrix;
mat4 ProjectionMatrix;
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
};
uniform mat4 ModelMatrix; uniform mat4 ModelMatrix;
in vec3 Position; in vec3 Position;
in vec2 Texcoord; in vec2 Texcoord;
#ifdef VSLayer
out vec2 uv;
#else
out vec2 tc; out vec2 tc;
out int layerId;
#endif
void main(void) void main(void)
{ {
#ifdef VSLayer
gl_Layer = gl_InstanceID & 3;
uv = Texcoord;
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.);
#else
layerId = gl_InstanceID & 3;
tc = Texcoord; tc = Texcoord;
gl_Position = ModelMatrix * vec4(Position, 1.); gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.);
#endif
} }

View File

@ -15,6 +15,7 @@ uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix; uniform mat4 ProjectionMatrix;
uniform mat4 InverseViewMatrix; uniform mat4 InverseViewMatrix;
uniform mat4 InverseProjectionMatrix; uniform mat4 InverseProjectionMatrix;
uniform mat4 ShadowViewProjMatrixes[4];
#else #else
layout (std140) uniform MatrixesData layout (std140) uniform MatrixesData
{ {

View File

@ -10,6 +10,7 @@ uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix; uniform mat4 ProjectionMatrix;
uniform mat4 InverseViewMatrix; uniform mat4 InverseViewMatrix;
uniform mat4 InverseProjectionMatrix; uniform mat4 InverseProjectionMatrix;
uniform mat4 ShadowViewProjMatrixes[4];
#else #else
layout (std140) uniform MatrixesData layout (std140) uniform MatrixesData
{ {

View File

@ -47,9 +47,6 @@ private:
* one time only (which might get triggered more than once). */ * one time only (which might get triggered more than once). */
enum AnimTimeType { ATT_CYCLIC, ATT_CYCLIC_ONCE } m_anim_type; enum AnimTimeType { ATT_CYCLIC, ATT_CYCLIC_ONCE } m_anim_type;
/** True if the animation is currently playing. */
bool m_playing;
/** The current time used in the IPOs. */ /** The current time used in the IPOs. */
float m_current_time; float m_current_time;
@ -66,6 +63,9 @@ protected:
/** All IPOs for this animation. */ /** All IPOs for this animation. */
PtrVector<Ipo> m_all_ipos; PtrVector<Ipo> m_all_ipos;
/** True if the animation is currently playing. */
bool m_playing;
public: public:
AnimationBase(const XMLNode &node); AnimationBase(const XMLNode &node);
AnimationBase(Ipo *ipo); AnimationBase(Ipo *ipo);

View File

@ -81,6 +81,8 @@ void ThreeDAnimation::update(float dt)
//m_node->setPosition(xyz.toIrrVector()); //m_node->setPosition(xyz.toIrrVector());
//m_node->setScale(scale.toIrrVector()); //m_node->setScale(scale.toIrrVector());
if (!m_playing) return;
// Note that the rotation order of irrlicht is different from the one // Note that the rotation order of irrlicht is different from the one
// in blender. So in order to reproduce the blender IPO rotations // in blender. So in order to reproduce the blender IPO rotations
// correctly, we have to get the rotations around each axis and combine // correctly, we have to get the rotations around each axis and combine

View File

@ -3,6 +3,7 @@
#include <fstream> #include <fstream>
#include <string> #include <string>
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "utils/profiler.hpp"
#ifdef _IRR_WINDOWS_API_ #ifdef _IRR_WINDOWS_API_
#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast<const char*>(X)) #define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast<const char*>(X))
@ -240,6 +241,8 @@ GLuint LoadShader(const char * file, unsigned type)
Code += "//" + std::string(file) + "\n"; Code += "//" + std::string(file) + "\n";
if (UserConfigParams::m_ubo_disabled) if (UserConfigParams::m_ubo_disabled)
Code += "#define UBO_DISABLED\n"; Code += "#define UBO_DISABLED\n";
if (irr_driver->hasVSLayerExtension())
Code += "#define VSLayer\n";
if (Stream.is_open()) if (Stream.is_open())
{ {
std::string Line = ""; std::string Line = "";
@ -307,6 +310,11 @@ GLuint getDepthTexture(irr::video::ITexture *tex)
} }
std::set<irr::video::ITexture *> AlreadyTransformedTexture; std::set<irr::video::ITexture *> AlreadyTransformedTexture;
void resetTextureTable()
{
AlreadyTransformedTexture.clear();
}
void compressTexture(irr::video::ITexture *tex, bool srgb) void compressTexture(irr::video::ITexture *tex, bool srgb)
{ {
if (AlreadyTransformedTexture.find(tex) != AlreadyTransformedTexture.end()) if (AlreadyTransformedTexture.find(tex) != AlreadyTransformedTexture.end())
@ -461,6 +469,42 @@ void blitFBO(GLuint Src, GLuint Dst, size_t width, size_t height)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
} }
ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer)
{
if (!UserConfigParams::m_profiler_enabled) return;
if (profiler.isFrozen()) return;
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver();
if (!timer.initialised)
{
gl_driver->extGlGenQueries(1, &timer.query);
timer.initialised = true;
}
gl_driver->extGlBeginQuery(GL_TIME_ELAPSED, timer.query);
}
ScopedGPUTimer::~ScopedGPUTimer()
{
if (!UserConfigParams::m_profiler_enabled) return;
if (profiler.isFrozen()) return;
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver();
gl_driver->extGlEndQuery(GL_TIME_ELAPSED);
}
GPUTimer::GPUTimer() : initialised(false)
{
}
unsigned GPUTimer::elapsedTimeus()
{
if (!initialised)
return 0;
GLuint result;
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver();
gl_driver->extGlGetQueryObjectuiv(query, GL_QUERY_RESULT, &result);
return result / 1000;
}
static void drawTexColoredQuad(const video::ITexture *texture, const video::SColor *col, float width, float height, static void drawTexColoredQuad(const video::ITexture *texture, const video::SColor *col, float width, float height,
float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y, float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y,
float tex_width, float tex_height) float tex_width, float tex_height)

View File

@ -155,12 +155,32 @@ GLint LoadProgram(Types ... args)
return ProgramID; return ProgramID;
} }
class GPUTimer;
class ScopedGPUTimer
{
public:
ScopedGPUTimer(GPUTimer &);
~ScopedGPUTimer();
};
class GPUTimer
{
friend class ScopedGPUTimer;
GLuint query;
bool initialised;
public:
GPUTimer();
unsigned elapsedTimeus();
};
// core::rect<s32> needs these includes // core::rect<s32> needs these includes
#include <rect.h> #include <rect.h>
#include "utils/vec3.hpp" #include "utils/vec3.hpp"
GLuint getTextureGLuint(irr::video::ITexture *tex); GLuint getTextureGLuint(irr::video::ITexture *tex);
GLuint getDepthTexture(irr::video::ITexture *tex); GLuint getDepthTexture(irr::video::ITexture *tex);
void resetTextureTable();
void compressTexture(irr::video::ITexture *tex, bool srgb); void compressTexture(irr::video::ITexture *tex, bool srgb);
bool loadCompressedTexture(const std::string& compressed_tex); bool loadCompressedTexture(const std::string& compressed_tex);
void saveCompressedTexture(const std::string& compressed_tex); void saveCompressedTexture(const std::string& compressed_tex);

View File

@ -87,6 +87,8 @@ using namespace irr;
/** singleton */ /** singleton */
IrrDriver *irr_driver = NULL; IrrDriver *irr_driver = NULL;
GPUTimer m_perf_query[Q_LAST];
const int MIN_SUPPORTED_HEIGHT = 600; const int MIN_SUPPORTED_HEIGHT = 600;
const int MIN_SUPPORTED_WIDTH = 800; const int MIN_SUPPORTED_WIDTH = 800;
@ -168,6 +170,11 @@ core::array<video::IRenderTarget> &IrrDriver::getMainSetup()
return m_mrt; return m_mrt;
} }
GPUTimer &IrrDriver::getGPUTimer(unsigned i)
{
return m_perf_query[i];
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#if defined(__linux__) && !defined(ANDROID) #if defined(__linux__) && !defined(ANDROID)
@ -434,6 +441,14 @@ void IrrDriver::initDevice()
Log::info("IrrDriver", "OPENGL VERSION IS %d.%d", GLMajorVersion, GLMinorVersion); Log::info("IrrDriver", "OPENGL VERSION IS %d.%d", GLMajorVersion, GLMinorVersion);
m_glsl = (GLMajorVersion > 3 || (GLMajorVersion == 3 && GLMinorVersion >= 1)); m_glsl = (GLMajorVersion > 3 || (GLMajorVersion == 3 && GLMinorVersion >= 1));
// Parse extensions
hasVSLayer = false;
const GLubyte *extensions = glGetString(GL_EXTENSIONS);
if (extensions && strstr((const char*)extensions, "GL_AMD_vertex_shader_layer") != NULL)
hasVSLayer = true;
// This remaps the window, so it has to be done before the clear to avoid flicker // This remaps the window, so it has to be done before the clear to avoid flicker
m_device->setResizable(false); m_device->setResizable(false);
@ -463,7 +478,6 @@ void IrrDriver::initDevice()
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver(); irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
gl_driver->extGlGenQueries(1, &m_lensflare_query); gl_driver->extGlGenQueries(1, &m_lensflare_query);
gl_driver->extGlGenQueries(Q_LAST, m_perf_query);
m_query_issued = false; m_query_issued = false;
scene::IMesh * const sphere = m_scene_manager->getGeometryCreator()->createSphereMesh(1, 16, 16); scene::IMesh * const sphere = m_scene_manager->getGeometryCreator()->createSphereMesh(1, 16, 16);
@ -1896,14 +1910,21 @@ void IrrDriver::update(float dt)
World *world = World::getWorld(); World *world = World::getWorld();
if (GUIEngine::getCurrentScreen() != NULL && if (GUIEngine::getCurrentScreen() != NULL &&
GUIEngine::getCurrentScreen()->needs3D()) GUIEngine::getCurrentScreen()->needs3D() &&
world != NULL)
{ {
//printf("Screen that needs 3D\n"); //printf("Screen that needs 3D\n");
m_video_driver->beginScene(/*backBuffer clear*/true, /*zBuffer*/true, //m_video_driver->beginScene(/*backBuffer clear*/true, /*zBuffer*/true,
video::SColor(0,0,0,255)); // video::SColor(0,0,0,255));
m_scene_manager->drawAll(); //m_scene_manager->drawAll();
if (m_glsl)
renderGLSL(dt);
else
renderFixed(dt);
GUIEngine::render(dt); GUIEngine::render(dt);
m_video_driver->endScene(); //m_video_driver->endScene();
return; return;
} }
else if (!world) else if (!world)

View File

@ -92,6 +92,7 @@ class IrrDriver : public IEventReceiver, public NoCopy
{ {
private: private:
int GLMajorVersion, GLMinorVersion; int GLMajorVersion, GLMinorVersion;
bool hasVSLayer;
/** The irrlicht device. */ /** The irrlicht device. */
IrrlichtDevice *m_device; IrrlichtDevice *m_device;
/** Irrlicht scene manager. */ /** Irrlicht scene manager. */
@ -173,6 +174,11 @@ public:
return 120; return 120;
} }
bool hasVSLayerExtension() const
{
return hasVSLayer;
}
float getExposure() const float getExposure() const
{ {
return m_exposure; return m_exposure;
@ -222,7 +228,6 @@ private:
unsigned object_count[PASS_COUNT]; unsigned object_count[PASS_COUNT];
u32 m_renderpass; u32 m_renderpass;
u32 m_lensflare_query; u32 m_lensflare_query;
u32 m_perf_query[Q_LAST];
bool m_query_issued; bool m_query_issued;
class STKMeshSceneNode *m_sun_interposer; class STKMeshSceneNode *m_sun_interposer;
scene::CLensFlareSceneNode *m_lensflare; scene::CLensFlareSceneNode *m_lensflare;
@ -261,22 +266,13 @@ private:
void renderSolidSecondPass(); void renderSolidSecondPass();
void renderTransparent(); void renderTransparent();
void renderParticles(); void renderParticles();
void computeCameraMatrix(scene::ICameraSceneNode * const camnode, void computeSunVisibility();
Camera * const camera); void renderScene(scene::ICameraSceneNode * const camnode, std::vector<GlowData>& glows, float dt, bool hasShadows);
void renderShadows(//ShadowImportanceProvider * const sicb, void computeCameraMatrix(scene::ICameraSceneNode * const camnode);
scene::ICameraSceneNode * const camnode, void renderShadows();
//video::SOverrideMaterial &overridemat, void renderGlow(std::vector<GlowData>& glows);
Camera * const camera); void renderLights(float dt);
void renderGlow(video::SOverrideMaterial &overridemat, void renderDisplacement();
std::vector<GlowData>& glows,
const core::aabbox3df& cambox,
int cam);
void renderLights(const core::aabbox3df& cambox,
scene::ICameraSceneNode * const camnode,
video::SOverrideMaterial &overridemat,
int cam, float dt);
void renderDisplacement(video::SOverrideMaterial &overridemat,
int cam);
void doScreenShot(); void doScreenShot();
public: public:
IrrDriver(); IrrDriver();
@ -284,7 +280,7 @@ public:
void initDevice(); void initDevice();
void reset(); void reset();
void generateSkyboxCubemap(); void generateSkyboxCubemap();
void renderSkybox(); void renderSkybox(const scene::ICameraSceneNode *camera);
void setPhase(STKRenderingPass); void setPhase(STKRenderingPass);
STKRenderingPass getPhase() const; STKRenderingPass getPhase() const;
const std::vector<core::matrix4> &getShadowViewProj() const const std::vector<core::matrix4> &getShadowViewProj() const
@ -373,6 +369,7 @@ public:
void setTextureErrorMessage(const std::string &error, void setTextureErrorMessage(const std::string &error,
const std::string &detail=""); const std::string &detail="");
void unsetTextureErrorMessage(); void unsetTextureErrorMessage();
class GPUTimer &getGPUTimer(unsigned);
void draw2dTriangle(const core::vector2df &a, const core::vector2df &b, void draw2dTriangle(const core::vector2df &a, const core::vector2df &b,
const core::vector2df &c, const core::vector2df &c,

View File

@ -111,9 +111,9 @@ void MaterialManager::setAllMaterialFlags(video::ITexture* t,
mb->getMaterial().ColorMaterial = video::ECM_DIFFUSE_AND_AMBIENT; mb->getMaterial().ColorMaterial = video::ECM_DIFFUSE_AND_AMBIENT;
if (World::getWorld() != NULL && World::getWorld()->getTrack() != NULL) if (World::getWorld() != NULL)
{ {
mb->getMaterial().FogEnable = World::getWorld()->getTrack()->isFogEnabled(); mb->getMaterial().FogEnable = World::getWorld()->isFogEnabled();
} }

View File

@ -665,7 +665,7 @@ void PostProcessing::render()
// Grab the sky // Grab the sky
glBindFramebuffer(GL_FRAMEBUFFER, out_fbo); glBindFramebuffer(GL_FRAMEBUFFER, out_fbo);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
irr_driver->renderSkybox(); // irr_driver->renderSkybox();
// Set the sun's color // Set the sun's color
const SColor col = World::getWorld()->getTrack()->getSunColor(); const SColor col = World::getWorld()->getTrack()->getSunColor();

View File

@ -140,146 +140,7 @@ void IrrDriver::renderGLSL(float dt)
camera->activate(); camera->activate();
rg->preRenderCallback(camera); // adjusts start referee rg->preRenderCallback(camera); // adjusts start referee
const u32 bgnodes = m_background.size(); renderScene(camnode, glows, dt, track->hasShadows());
/* if (bgnodes)
{
// If there are background nodes (3d skybox), draw them now.
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false);
m_renderpass = scene::ESNRP_SKY_BOX;
m_scene_manager->drawAll(m_renderpass);
const video::SOverrideMaterial prev = overridemat;
overridemat.Enabled = 1;
overridemat.EnableFlags = video::EMF_MATERIAL_TYPE;
overridemat.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
for (i = 0; i < bgnodes; i++)
{
m_background[i]->setPosition(camnode->getPosition() * 0.97f);
m_background[i]->updateAbsolutePosition();
m_background[i]->render();
}
overridemat = prev;
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, true);
}*/
// Get Projection and view matrix
computeCameraMatrix(camnode, camera);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
// Fire up the MRT
PROFILER_PUSH_CPU_MARKER("- Solid Pass 1", 0xFF, 0x00, 0x00);
renderSolidFirstPass();
PROFILER_POP_CPU_MARKER();
// Todo : reenable glow and shadows
//ShadowImportanceProvider * const sicb = (ShadowImportanceProvider *)
// irr_driver->getCallback(ES_SHADOW_IMPORTANCE);
//sicb->updateIPVMatrix();
// Used to cull glowing items & lights
const core::aabbox3df cambox = camnode->getViewFrustum()->getBoundingBox();
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
// Shadows
if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights &&
UserConfigParams::m_shadows && track->hasShadows())
{
renderShadows(camnode, camera);
}
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00);
// Lights
renderLights(cambox, camnode, overridemat, cam, dt);
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Solid Pass 2", 0x00, 0x00, 0xFF);
if (!UserConfigParams::m_dynamic_lights)
{
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
else
{
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_COLORS));
}
renderSolidSecondPass();
PROFILER_POP_CPU_MARKER();
if (UserConfigParams::m_dynamic_lights && World::getWorld()->getTrack()->isFogEnabled())
{
PROFILER_PUSH_CPU_MARKER("- Fog", 0xFF, 0x00, 0x00);
m_post_processing->renderFog();
PROFILER_POP_CPU_MARKER();
}
PROFILER_PUSH_CPU_MARKER("- Skybox", 0xFF, 0x00, 0xFF);
renderSkybox();
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0xFF, 0x00);
// Render anything glowing.
if (!m_mipviz && !m_wireframe && UserConfigParams::m_glow)
{
irr_driver->setPhase(GLOW_PASS);
renderGlow(overridemat, glows, cambox, cam);
} // end glow
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Lensflare/godray", 0x00, 0xFF, 0xFF);
// Is the lens flare enabled & visible? Check last frame's query.
const bool hasflare = World::getWorld()->getTrack()->hasLensFlare();
const bool hasgodrays = World::getWorld()->getTrack()->hasGodRays();
if (UserConfigParams::m_light_shaft && hasgodrays)//hasflare || hasgodrays)
{
GLuint res = 0;
if (m_query_issued)
gl_driver->extGlGetQueryObjectuiv(m_lensflare_query, GL_QUERY_RESULT, &res);
m_post_processing->setSunPixels(res);
// Prepare the query for the next frame.
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
gl_driver->extGlBeginQuery(GL_SAMPLES_PASSED_ARB, m_lensflare_query);
m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID);
m_scene_manager->drawAll(scene::ESNRP_CAMERA);
irr_driver->setPhase(GLOW_PASS);
m_sun_interposer->render();
gl_driver->extGlEndQuery(GL_SAMPLES_PASSED_ARB);
m_query_issued = true;
m_lensflare->setStrength(res / 4000.0f);
if (hasflare)
m_lensflare->OnRegisterSceneNode();
// Make sure the color mask is reset
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
PROFILER_POP_CPU_MARKER();
// We need to re-render camera due to the per-cam-node hack.
PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00);
renderTransparent();
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00);
renderParticles();
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Displacement", 0x00, 0x00, 0xFF);
// Handle displacing nodes, if any
const u32 displacingcount = m_displacing.size();
if (displacingcount)
{
renderDisplacement(overridemat, cam);
}
PROFILER_POP_CPU_MARKER();
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
@ -298,14 +159,7 @@ void IrrDriver::renderGLSL(float dt)
else else
glDisable(GL_FRAMEBUFFER_SRGB); glDisable(GL_FRAMEBUFFER_SRGB);
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
GLuint perf_query_res[Q_LAST];
for (unsigned i = 0; i < Q_LAST; i++)
{
gl_driver->extGlGetQueryObjectuiv(m_perf_query[i], GL_QUERY_RESULT, &perf_query_res[i]);
Log::info("GPU Perf", "Phase %d : %d us\n", i, perf_query_res[i] / 1000);
}
glBindVertexArray(0); glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@ -351,6 +205,83 @@ void IrrDriver::renderGLSL(float dt)
getPostProcessing()->update(dt); getPostProcessing()->update(dt);
} }
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector<GlowData>& glows, float dt, bool hasShadow)
{
computeCameraMatrix(camnode);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
PROFILER_PUSH_CPU_MARKER("- Solid Pass 1", 0xFF, 0x00, 0x00);
renderSolidFirstPass();
PROFILER_POP_CPU_MARKER();
const core::aabbox3df cambox = camnode->getViewFrustum()->getBoundingBox();
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
// Shadows
if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights &&
UserConfigParams::m_shadows && hasShadow)
{
renderShadows();
}
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00);
// Lights
renderLights(dt);
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Solid Pass 2", 0x00, 0x00, 0xFF);
if (!UserConfigParams::m_dynamic_lights)
{
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
else
{
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_COLORS));
}
renderSolidSecondPass();
PROFILER_POP_CPU_MARKER();
if (UserConfigParams::m_dynamic_lights && World::getWorld()->isFogEnabled())
{
PROFILER_PUSH_CPU_MARKER("- Fog", 0xFF, 0x00, 0x00);
m_post_processing->renderFog();
PROFILER_POP_CPU_MARKER();
}
PROFILER_PUSH_CPU_MARKER("- Skybox", 0xFF, 0x00, 0xFF);
renderSkybox(camnode);
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0xFF, 0x00);
// Render anything glowing.
if (!m_mipviz && !m_wireframe && UserConfigParams::m_glow)
{
irr_driver->setPhase(GLOW_PASS);
renderGlow(glows);
} // end glow
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Lensflare/godray", 0x00, 0xFF, 0xFF);
computeSunVisibility();
PROFILER_POP_CPU_MARKER();
// We need to re-render camera due to the per-cam-node hack.
PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00);
renderTransparent();
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00);
renderParticles();
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Displacement", 0x00, 0x00, 0xFF);
renderDisplacement();
PROFILER_POP_CPU_MARKER();
}
// -------------------------------------------- // --------------------------------------------
void IrrDriver::renderFixed(float dt) void IrrDriver::renderFixed(float dt)
@ -427,6 +358,39 @@ void IrrDriver::renderFixed(float dt)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void IrrDriver::computeSunVisibility()
{
// Is the lens flare enabled & visible? Check last frame's query.
const bool hasflare = World::getWorld()->getTrack()->hasLensFlare();
const bool hasgodrays = World::getWorld()->getTrack()->hasGodRays();
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
if (UserConfigParams::m_light_shaft && hasgodrays)//hasflare || hasgodrays)
{
GLuint res = 0;
if (m_query_issued)
gl_driver->extGlGetQueryObjectuiv(m_lensflare_query, GL_QUERY_RESULT, &res);
m_post_processing->setSunPixels(res);
// Prepare the query for the next frame.
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
gl_driver->extGlBeginQuery(GL_SAMPLES_PASSED_ARB, m_lensflare_query);
m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID);
m_scene_manager->drawAll(scene::ESNRP_CAMERA);
irr_driver->setPhase(GLOW_PASS);
m_sun_interposer->render();
gl_driver->extGlEndQuery(GL_SAMPLES_PASSED_ARB);
m_query_issued = true;
m_lensflare->setStrength(res / 4000.0f);
if (hasflare)
m_lensflare->OnRegisterSceneNode();
// Make sure the color mask is reset
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
}
void IrrDriver::renderSolidFirstPass() void IrrDriver::renderSolidFirstPass()
{ {
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS)); glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS));
@ -444,30 +408,29 @@ void IrrDriver::renderSolidFirstPass()
GroupedFPSM<FPSM_DEFAULT>::reset(); GroupedFPSM<FPSM_DEFAULT>::reset();
GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::reset(); GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::reset();
GroupedFPSM<FPSM_NORMAL_MAP>::reset(); GroupedFPSM<FPSM_NORMAL_MAP>::reset();
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
gl_driver->extGlBeginQuery(GL_TIME_ELAPSED, m_perf_query[Q_SOLID_PASS1]);
m_scene_manager->drawAll(scene::ESNRP_SOLID); m_scene_manager->drawAll(scene::ESNRP_SOLID);
if (!UserConfigParams::m_dynamic_lights) if (!UserConfigParams::m_dynamic_lights)
return; return;
glUseProgram(MeshShader::ObjectPass1Shader::Program);
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT>::MeshSet.size(); ++i)
{ {
drawObjectPass1(*GroupedFPSM<FPSM_DEFAULT>::MeshSet[i], GroupedFPSM<FPSM_DEFAULT>::MVPSet[i], GroupedFPSM<FPSM_DEFAULT>::TIMVSet[i]); ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS1));
glUseProgram(MeshShader::ObjectPass1Shader::Program);
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT>::MeshSet.size(); ++i)
{
drawObjectPass1(*GroupedFPSM<FPSM_DEFAULT>::MeshSet[i], GroupedFPSM<FPSM_DEFAULT>::MVPSet[i], GroupedFPSM<FPSM_DEFAULT>::TIMVSet[i]);
}
glUseProgram(MeshShader::ObjectRefPass1Shader::Program);
for (unsigned i = 0; i < GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet.size(); ++i)
{
drawObjectRefPass1(*GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::TIMVSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix);
}
glUseProgram(MeshShader::NormalMapShader::Program);
for (unsigned i = 0; i < GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet.size(); ++i)
{
drawNormalPass(*GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::MVPSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::TIMVSet[i]);
}
} }
glUseProgram(MeshShader::ObjectRefPass1Shader::Program);
for (unsigned i = 0; i < GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet.size(); ++i)
{
drawObjectRefPass1(*GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::TIMVSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix);
}
glUseProgram(MeshShader::NormalMapShader::Program);
for (unsigned i = 0; i < GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet.size(); ++i)
{
drawNormalPass(*GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::MVPSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::TIMVSet[i]);
}
gl_driver->extGlEndQuery(GL_TIME_ELAPSED);
} }
void IrrDriver::renderSolidSecondPass() void IrrDriver::renderSolidSecondPass()
@ -500,42 +463,45 @@ void IrrDriver::renderSolidSecondPass()
setTexture(0, m_rtts->getRenderTarget(RTT_TMP1), GL_NEAREST, GL_NEAREST); setTexture(0, m_rtts->getRenderTarget(RTT_TMP1), GL_NEAREST, GL_NEAREST);
setTexture(1, m_rtts->getRenderTarget(RTT_TMP2), GL_NEAREST, GL_NEAREST); setTexture(1, m_rtts->getRenderTarget(RTT_TMP2), GL_NEAREST, GL_NEAREST);
setTexture(2, m_rtts->getRenderTarget(RTT_SSAO), GL_NEAREST, GL_NEAREST); setTexture(2, m_rtts->getRenderTarget(RTT_SSAO), GL_NEAREST, GL_NEAREST);
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
gl_driver->extGlBeginQuery(GL_TIME_ELAPSED, m_perf_query[Q_SOLID_PASS2]);
m_scene_manager->drawAll(scene::ESNRP_SOLID);
glUseProgram(MeshShader::ObjectPass2Shader::Program); {
for (unsigned i = 0; i < GroupedSM<SM_DEFAULT>::MeshSet.size(); i++)
drawObjectPass2(*GroupedSM<SM_DEFAULT>::MeshSet[i], GroupedSM<SM_DEFAULT>::MVPSet[i], GroupedSM<SM_DEFAULT>::MeshSet[i]->TextureMatrix);
glUseProgram(MeshShader::ObjectRefPass2Shader::Program); ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS2));
for (unsigned i = 0; i < GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet.size(); i++)
drawObjectRefPass2(*GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet[i], GroupedSM<SM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix);
glUseProgram(MeshShader::ObjectRimLimitShader::Program); m_scene_manager->drawAll(scene::ESNRP_SOLID);
for (unsigned i = 0; i < GroupedSM<SM_RIMLIT>::MeshSet.size(); i++)
drawObjectRimLimit(*GroupedSM<SM_RIMLIT>::MeshSet[i], GroupedSM<SM_RIMLIT>::MVPSet[i], GroupedSM<SM_RIMLIT>::TIMVSet[i], GroupedSM<SM_RIMLIT>::MeshSet[i]->TextureMatrix);
glUseProgram(MeshShader::SphereMapShader::Program); glUseProgram(MeshShader::ObjectPass2Shader::Program);
for (unsigned i = 0; i < GroupedSM<SM_SPHEREMAP>::MeshSet.size(); i++) for (unsigned i = 0; i < GroupedSM<SM_DEFAULT>::MeshSet.size(); i++)
drawSphereMap(*GroupedSM<SM_SPHEREMAP>::MeshSet[i], GroupedSM<SM_SPHEREMAP>::MVPSet[i], GroupedSM<SM_SPHEREMAP>::TIMVSet[i]); drawObjectPass2(*GroupedSM<SM_DEFAULT>::MeshSet[i], GroupedSM<SM_DEFAULT>::MVPSet[i], GroupedSM<SM_DEFAULT>::MeshSet[i]->TextureMatrix);
glUseProgram(MeshShader::SplattingShader::Program); glUseProgram(MeshShader::ObjectRefPass2Shader::Program);
for (unsigned i = 0; i < GroupedSM<SM_SPLATTING>::MeshSet.size(); i++) for (unsigned i = 0; i < GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet.size(); i++)
drawSplatting(*GroupedSM<SM_SPLATTING>::MeshSet[i], GroupedSM<SM_SPLATTING>::MVPSet[i]); drawObjectRefPass2(*GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet[i], GroupedSM<SM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix);
glUseProgram(MeshShader::ObjectUnlitShader::Program); glUseProgram(MeshShader::ObjectRimLimitShader::Program);
for (unsigned i = 0; i < GroupedSM<SM_UNLIT>::MeshSet.size(); i++) for (unsigned i = 0; i < GroupedSM<SM_RIMLIT>::MeshSet.size(); i++)
drawObjectUnlit(*GroupedSM<SM_UNLIT>::MeshSet[i], GroupedSM<SM_UNLIT>::MVPSet[i]); drawObjectRimLimit(*GroupedSM<SM_RIMLIT>::MeshSet[i], GroupedSM<SM_RIMLIT>::MVPSet[i], GroupedSM<SM_RIMLIT>::TIMVSet[i], GroupedSM<SM_RIMLIT>::MeshSet[i]->TextureMatrix);
glUseProgram(MeshShader::DetailledObjectPass2Shader::Program); glUseProgram(MeshShader::SphereMapShader::Program);
for (unsigned i = 0; i < GroupedSM<SM_DETAILS>::MeshSet.size(); i++) for (unsigned i = 0; i < GroupedSM<SM_SPHEREMAP>::MeshSet.size(); i++)
drawDetailledObjectPass2(*GroupedSM<SM_DETAILS>::MeshSet[i], GroupedSM<SM_DETAILS>::MVPSet[i]); drawSphereMap(*GroupedSM<SM_SPHEREMAP>::MeshSet[i], GroupedSM<SM_SPHEREMAP>::MVPSet[i], GroupedSM<SM_SPHEREMAP>::TIMVSet[i]);
glUseProgram(MeshShader::UntexturedObjectShader::Program); glUseProgram(MeshShader::SplattingShader::Program);
for (unsigned i = 0; i < GroupedSM<SM_UNTEXTURED>::MeshSet.size(); i++) for (unsigned i = 0; i < GroupedSM<SM_SPLATTING>::MeshSet.size(); i++)
drawUntexturedObject(*GroupedSM<SM_UNTEXTURED>::MeshSet[i], GroupedSM<SM_UNTEXTURED>::MVPSet[i]); drawSplatting(*GroupedSM<SM_SPLATTING>::MeshSet[i], GroupedSM<SM_SPLATTING>::MVPSet[i]);
gl_driver->extGlEndQuery(GL_TIME_ELAPSED);
glUseProgram(MeshShader::ObjectUnlitShader::Program);
for (unsigned i = 0; i < GroupedSM<SM_UNLIT>::MeshSet.size(); i++)
drawObjectUnlit(*GroupedSM<SM_UNLIT>::MeshSet[i], GroupedSM<SM_UNLIT>::MVPSet[i]);
glUseProgram(MeshShader::DetailledObjectPass2Shader::Program);
for (unsigned i = 0; i < GroupedSM<SM_DETAILS>::MeshSet.size(); i++)
drawDetailledObjectPass2(*GroupedSM<SM_DETAILS>::MeshSet[i], GroupedSM<SM_DETAILS>::MVPSet[i]);
glUseProgram(MeshShader::UntexturedObjectShader::Program);
for (unsigned i = 0; i < GroupedSM<SM_UNTEXTURED>::MeshSet.size(); i++)
drawUntexturedObject(*GroupedSM<SM_UNTEXTURED>::MeshSet[i], GroupedSM<SM_UNTEXTURED>::MVPSet[i]);
}
} }
void IrrDriver::renderTransparent() void IrrDriver::renderTransparent()
@ -559,10 +525,12 @@ void IrrDriver::renderParticles()
m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT); m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT);
} }
void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode)
Camera * const camera)
{ {
m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID); m_scene_manager->drawAll(scene::ESNRP_CAMERA);
irr_driver->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION));
irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
irr_driver->genProjViewMatrix();
const Vec3 *vmin, *vmax; const Vec3 *vmin, *vmax;
World::getWorld()->getTrack()->getAABB(&vmin, &vmax); World::getWorld()->getTrack()->getAABB(&vmin, &vmax);
@ -621,17 +589,6 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode,
float up = box.MaxEdge.Y; float up = box.MaxEdge.Y;
float down = box.MinEdge.Y; float down = box.MinEdge.Y;
/* left -= fmodf(left, units_per_w);
right -= fmodf(right, units_per_w);
up -= fmodf(up, units_per_h);
down -= fmodf(down, units_per_h);
z -= fmodf(z, 0.5f);
// FIXME: quick and dirt (and wrong) workaround to avoid division by zero
if (left == right) right += 0.1f;
if (up == down) down += 0.1f;
if (z == 30) z += 0.1f;*/
core::matrix4 tmp_matrix; core::matrix4 tmp_matrix;
tmp_matrix.buildProjectionMatrixOrthoLH(left, right, tmp_matrix.buildProjectionMatrixOrthoLH(left, right,
@ -646,12 +603,7 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode,
assert(sun_ortho_matrix.size() == 4); assert(sun_ortho_matrix.size() == 4);
camnode->setNearValue(oldnear); camnode->setNearValue(oldnear);
camnode->setFarValue(oldfar); camnode->setFarValue(oldfar);
camnode->render(); // camnode->render();
camera->activate();
m_scene_manager->drawAll(scene::ESNRP_CAMERA);
irr_driver->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION));
irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
irr_driver->genProjViewMatrix();
float *tmp = new float[16 * 8]; float *tmp = new float[16 * 8];
@ -668,12 +620,8 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode,
delete tmp; delete tmp;
} }
void IrrDriver::renderShadows(//ShadowImportanceProvider * const sicb, void IrrDriver::renderShadows()
scene::ICameraSceneNode * const camnode,
//video::SOverrideMaterial &overridemat,
Camera * const camera)
{ {
irr_driver->setPhase(SHADOW_PASS); irr_driver->setPhase(SHADOW_PASS);
glDisable(GL_BLEND); glDisable(GL_BLEND);
glEnable(GL_POLYGON_OFFSET_FILL); glEnable(GL_POLYGON_OFFSET_FILL);
@ -684,112 +632,19 @@ void IrrDriver::renderShadows(//ShadowImportanceProvider * const sicb,
glDrawBuffer(GL_NONE); glDrawBuffer(GL_NONE);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO); glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver(); {
gl_driver->extGlBeginQuery(GL_TIME_ELAPSED, m_perf_query[Q_SHADOWS]); ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS));
m_scene_manager->drawAll(scene::ESNRP_SOLID); m_scene_manager->drawAll(scene::ESNRP_SOLID);
gl_driver->extGlEndQuery(GL_TIME_ELAPSED); }
glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_POLYGON_OFFSET_FILL);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
//sun_ortho_matrix *= m_suncam->getViewMatrix();
/* ((SunLightProvider *) m_shaders->m_callbacks[ES_SUNLIGHT])->setShadowMatrix(ortho);
sicb->setShadowMatrix(ortho);
overridemat.Enabled = 0;
// Render the importance map
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLLAPSE), true, true);
m_shadow_importance->render();
CollapseProvider * const colcb = (CollapseProvider *)
m_shaders->
m_callbacks[ES_COLLAPSE];
ScreenQuad sq(m_video_driver);
sq.setMaterialType(m_shaders->getShader(ES_COLLAPSE));
sq.setTexture(m_rtts->getRTT(RTT_COLLAPSE));
sq.getMaterial().setFlag(EMF_BILINEAR_FILTER, false);
const TypeRTT oldh = tick ? RTT_COLLAPSEH : RTT_COLLAPSEH2;
const TypeRTT oldv = tick ? RTT_COLLAPSEV : RTT_COLLAPSEV2;
const TypeRTT curh = tick ? RTT_COLLAPSEH2 : RTT_COLLAPSEH;
const TypeRTT curv = tick ? RTT_COLLAPSEV2 : RTT_COLLAPSEV;
colcb->setResolution(1, m_rtts->getRTT(RTT_WARPV)->getSize().Height);
sq.setTexture(m_rtts->getRTT(oldh), 1);
sq.render(m_rtts->getRTT(RTT_WARPH));
colcb->setResolution(m_rtts->getRTT(RTT_WARPV)->getSize().Height, 1);
sq.setTexture(m_rtts->getRTT(oldv), 1);
sq.render(m_rtts->getRTT(RTT_WARPV));
sq.setTexture(0, 1);
((GaussianBlurProvider *) m_shaders->m_callbacks[ES_GAUSSIAN3H])->setResolution(
m_rtts->getRTT(RTT_WARPV)->getSize().Height,
m_rtts->getRTT(RTT_WARPV)->getSize().Height);
sq.setMaterialType(m_shaders->getShader(ES_GAUSSIAN6H));
sq.setTexture(m_rtts->getRTT(RTT_WARPH));
sq.render(m_rtts->getRTT(curh));
sq.setMaterialType(m_shaders->getShader(ES_GAUSSIAN6V));
sq.setTexture(m_rtts->getRTT(RTT_WARPV));
sq.render(m_rtts->getRTT(curv));*/
// Convert importance maps to warp maps
//
// It should be noted that while they do repeated work
// calculating the min, max, and total, it's several hundred us
// faster to do that than to do it once in a separate shader
// (shader switch overhead, measured).
/*colcb->setResolution(m_rtts->getRTT(RTT_WARPV)->getSize().Height,
m_rtts->getRTT(RTT_WARPV)->getSize().Height);
sq.setMaterialType(m_shaders->getShader(ES_SHADOW_WARPH));
sq.setTexture(m_rtts->getRTT(curh));
sq.render(m_rtts->getRTT(RTT_WARPH));
sq.setMaterialType(m_shaders->getShader(ES_SHADOW_WARPV));
sq.setTexture(m_rtts->getRTT(curv));
sq.render(m_rtts->getRTT(RTT_WARPV));*/
// Actual shadow map
/* overridemat.Material.MaterialType = m_shaders->getShader(ES_SHADOWPASS);
overridemat.EnableFlags = video::EMF_MATERIAL_TYPE | video::EMF_TEXTURE1 |
video::EMF_TEXTURE2;
overridemat.EnablePasses = scene::ESNRP_SOLID;
overridemat.Material.setTexture(1, m_rtts->getRTT(RTT_WARPH));
overridemat.Material.setTexture(2, m_rtts->getRTT(RTT_WARPV));
overridemat.Material.TextureLayer[1].TextureWrapU =
overridemat.Material.TextureLayer[1].TextureWrapV =
overridemat.Material.TextureLayer[2].TextureWrapU =
overridemat.Material.TextureLayer[2].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
overridemat.Material.TextureLayer[1].BilinearFilter =
overridemat.Material.TextureLayer[2].BilinearFilter = true;
overridemat.Material.TextureLayer[1].TrilinearFilter =
overridemat.Material.TextureLayer[2].TrilinearFilter = false;
overridemat.Material.TextureLayer[1].AnisotropicFilter =
overridemat.Material.TextureLayer[2].AnisotropicFilter = 0;
overridemat.Material.Wireframe = 1;
overridemat.Enabled = true;*/
// overridemat.EnablePasses = 0;
// overridemat.Enabled = false;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat, void IrrDriver::renderGlow(std::vector<GlowData>& glows)
std::vector<GlowData>& glows,
const core::aabbox3df& cambox,
int cam)
{ {
m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID); m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID);
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_TMP1_WITH_DS)); glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_TMP1_WITH_DS));
@ -814,10 +669,11 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat,
const GlowData &dat = glows[i]; const GlowData &dat = glows[i];
scene::ISceneNode * const cur = dat.node; scene::ISceneNode * const cur = dat.node;
//TODO : implement culling on gpu
// Quick box-based culling // Quick box-based culling
const core::aabbox3df nodebox = cur->getTransformedBoundingBox(); // const core::aabbox3df nodebox = cur->getTransformedBoundingBox();
if (!nodebox.intersectsWithBox(cambox)) // if (!nodebox.intersectsWithBox(cambox))
continue; // continue;
cb->setColor(dat.r, dat.g, dat.b); cb->setColor(dat.r, dat.g, dat.b);
cur->render(); cur->render();
@ -879,10 +735,7 @@ static void renderPointLights(unsigned count)
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count); glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
} }
void IrrDriver::renderLights(const core::aabbox3df& cambox, void IrrDriver::renderLights(float dt)
scene::ICameraSceneNode * const camnode,
video::SOverrideMaterial &overridemat,
int cam, float dt)
{ {
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++) for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
@ -907,72 +760,75 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
const core::vector3df &campos = const core::vector3df &campos =
irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition(); irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
gl_driver->extGlBeginQuery(GL_TIME_ELAPSED, m_perf_query[Q_LIGHT]);
std::vector<LightNode *> BucketedLN[15];
for (unsigned int i = 0; i < lightcount; i++)
{ {
if (!m_lights[i]->isPointLight()) ScopedGPUTimer Timer(getGPUTimer(Q_LIGHT));
{
m_lights[i]->render();
if (UserConfigParams::m_shadows && World::getWorld()->getTrack()->hasShadows())
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
else
m_post_processing->renderSunlight();
continue;
}
const core::vector3df &lightpos = (m_lights[i]->getAbsolutePosition() - campos);
unsigned idx = (unsigned)(lightpos.getLength() / 10);
if (idx > 14)
idx = 14;
BucketedLN[idx].push_back(m_lights[i]);
}
unsigned lightnum = 0; std::vector<LightNode *> BucketedLN[15];
for (unsigned int i = 0; i < lightcount; i++)
for (unsigned i = 0; i < 15; i++)
{
for (unsigned j = 0; j < BucketedLN[i].size(); j++)
{ {
if (++lightnum >= MAXLIGHT) if (!m_lights[i]->isPointLight())
{ {
LightNode* light_node = BucketedLN[i].at(j); m_lights[i]->render();
light_node->setEnergyMultiplier(0.0f); if (UserConfigParams::m_shadows && World::getWorld()->getTrack()->hasShadows())
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
else
m_post_processing->renderSunlight();
continue;
} }
else const core::vector3df &lightpos = (m_lights[i]->getAbsolutePosition() - campos);
{ unsigned idx = (unsigned)(lightpos.getLength() / 10);
LightNode* light_node = BucketedLN[i].at(j); if (idx > 14)
idx = 14;
BucketedLN[idx].push_back(m_lights[i]);
}
float em = light_node->getEnergyMultiplier(); unsigned lightnum = 0;
if (em < 1.0f)
for (unsigned i = 0; i < 15; i++)
{
for (unsigned j = 0; j < BucketedLN[i].size(); j++)
{
if (++lightnum >= MAXLIGHT)
{ {
light_node->setEnergyMultiplier(std::min(1.0f, em + dt)); LightNode* light_node = BucketedLN[i].at(j);
light_node->setEnergyMultiplier(0.0f);
} }
else
{
LightNode* light_node = BucketedLN[i].at(j);
const core::vector3df &pos = light_node->getAbsolutePosition(); float em = light_node->getEnergyMultiplier();
PointLightsInfo[lightnum].posX = pos.X; if (em < 1.0f)
PointLightsInfo[lightnum].posY = pos.Y; {
PointLightsInfo[lightnum].posZ = pos.Z; light_node->setEnergyMultiplier(std::min(1.0f, em + dt));
}
PointLightsInfo[lightnum].energy = light_node->getEffectiveEnergy(); const core::vector3df &pos = light_node->getAbsolutePosition();
PointLightsInfo[lightnum].posX = pos.X;
PointLightsInfo[lightnum].posY = pos.Y;
PointLightsInfo[lightnum].posZ = pos.Z;
const core::vector3df &col = light_node->getColor(); PointLightsInfo[lightnum].energy = light_node->getEffectiveEnergy();
PointLightsInfo[lightnum].red = col.X;
PointLightsInfo[lightnum].green = col.Y; const core::vector3df &col = light_node->getColor();
PointLightsInfo[lightnum].blue = col.Z; PointLightsInfo[lightnum].red = col.X;
PointLightsInfo[lightnum].green = col.Y;
PointLightsInfo[lightnum].blue = col.Z;
}
}
if (lightnum > MAXLIGHT)
{
irr_driver->setLastLightBucketDistance(i * 10);
break;
} }
} }
if (lightnum > MAXLIGHT)
{ lightnum++;
irr_driver->setLastLightBucketDistance(i * 10);
break; renderPointLights(MIN2(lightnum, MAXLIGHT));
} if (SkyboxCubeMap)
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
} }
lightnum++;
renderPointLights(MIN2(lightnum, MAXLIGHT));
if (SkyboxCubeMap)
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
gl_driver->extGlDrawBuffers(1, bufs); gl_driver->extGlDrawBuffers(1, bufs);
// Handle SSAO // Handle SSAO
if (UserConfigParams::m_ssao) if (UserConfigParams::m_ssao)
@ -987,7 +843,6 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
irr_driver->getFBO(FBO_HALF1), irr_driver->getRenderTargetTexture(RTT_HALF1), UserConfigParams::m_width / 2, UserConfigParams::m_height / 2); irr_driver->getFBO(FBO_HALF1), irr_driver->getRenderTargetTexture(RTT_HALF1), UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
} }
gl_driver->extGlEndQuery(GL_TIME_ELAPSED);
} }
static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z) static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z)
@ -1195,7 +1050,7 @@ static void displayCoeff(float *SHCoeff)
} }
// Only for 9 coefficients // Only for 9 coefficients
static void testSH(char *color[6], size_t width, size_t height, static void testSH(unsigned char *color[6], size_t width, size_t height,
float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff) float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff)
{ {
float *Y00[6]; float *Y00[6];
@ -1376,9 +1231,9 @@ void IrrDriver::generateSkyboxCubemap()
sh_h = MAX2(sh_h, SphericalHarmonicsTextures[i]->getOriginalSize().Height); sh_h = MAX2(sh_h, SphericalHarmonicsTextures[i]->getOriginalSize().Height);
} }
char *sh_rgba[6]; unsigned char *sh_rgba[6];
for (unsigned i = 0; i < 6; i++) for (unsigned i = 0; i < 6; i++)
sh_rgba[i] = new char[sh_w * sh_h * 4]; sh_rgba[i] = new unsigned char[sh_w * sh_h * 4];
for (unsigned i = 0; i < 6; i++) for (unsigned i = 0; i < 6; i++)
{ {
unsigned idx = texture_permutation[i]; unsigned idx = texture_permutation[i];
@ -1408,10 +1263,10 @@ void IrrDriver::generateSkyboxCubemap()
const video::SColorf& ambientf = irr_driver->getSceneManager()->getAmbientLight(); const video::SColorf& ambientf = irr_driver->getSceneManager()->getAmbientLight();
video::SColor ambient = ambientf.toSColor(); video::SColor ambient = ambientf.toSColor();
char *sh_rgba[6]; unsigned char *sh_rgba[6];
for (unsigned i = 0; i < 6; i++) for (unsigned i = 0; i < 6; i++)
{ {
sh_rgba[i] = new char[sh_w * sh_h * 4]; sh_rgba[i] = new unsigned char[sh_w * sh_h * 4];
for (int j = 0; j < sh_w * sh_h * 4; j+=4) for (int j = 0; j < sh_w * sh_h * 4; j+=4)
{ {
@ -1441,11 +1296,10 @@ void IrrDriver::generateSkyboxCubemap()
} }
void IrrDriver::renderSkybox() void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
{ {
if (SkyboxTextures.empty()) return; if (SkyboxTextures.empty()) return;
scene::ICameraSceneNode *camera = m_scene_manager->getActiveCamera();
if (!SkyboxCubeMap) if (!SkyboxCubeMap)
generateSkyboxCubemap(); generateSkyboxCubemap();
glBindVertexArray(MeshShader::SkyboxShader::cubevao); glBindVertexArray(MeshShader::SkyboxShader::cubevao);
@ -1478,8 +1332,7 @@ void IrrDriver::renderSkybox()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat, void IrrDriver::renderDisplacement()
int cam)
{ {
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_TMP4)); glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_TMP4));
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
@ -1502,9 +1355,6 @@ void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat,
for (int i = 0; i < displacingcount; i++) for (int i = 0; i < displacingcount; i++)
{ {
m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID);
m_displacing[i]->render();
m_scene_manager->setCurrentRendertime(scene::ESNRP_TRANSPARENT); m_scene_manager->setCurrentRendertime(scene::ESNRP_TRANSPARENT);
m_displacing[i]->render(); m_displacing[i]->render();
} }

View File

@ -1500,10 +1500,19 @@ namespace MeshShader
attrib_position = -1; attrib_position = -1;
return; return;
} }
Program = LoadProgram( if (irr_driver->hasVSLayerExtension())
GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow.vert").c_str(), {
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), Program = LoadProgram(
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str()); GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str());
}
else
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow.vert").c_str(),
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str());
}
attrib_position = glGetAttribLocation(Program, "Position"); attrib_position = glGetAttribLocation(Program, "Position");
uniform_MM = glGetUniformLocation(Program, "ModelMatrix"); uniform_MM = glGetUniformLocation(Program, "ModelMatrix");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
@ -1530,11 +1539,21 @@ namespace MeshShader
attrib_position = -1; attrib_position = -1;
return; return;
} }
Program = LoadProgram( if (irr_driver->hasVSLayerExtension())
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), {
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(), Program = LoadProgram(
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str()); GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str());
}
else
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(),
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str());
}
attrib_position = glGetAttribLocation(Program, "Position"); attrib_position = glGetAttribLocation(Program, "Position");
attrib_origin = glGetAttribLocation(Program, "Origin"); attrib_origin = glGetAttribLocation(Program, "Origin");
attrib_orientation = glGetAttribLocation(Program, "Orientation"); attrib_orientation = glGetAttribLocation(Program, "Orientation");
@ -1562,10 +1581,19 @@ namespace MeshShader
attrib_texcoord = -1; attrib_texcoord = -1;
return; return;
} }
Program = LoadProgram( if (irr_driver->hasVSLayerExtension())
GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow.vert").c_str(), {
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), Program = LoadProgram(
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str());
}
else
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow.vert").c_str(),
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str());
}
attrib_position = glGetAttribLocation(Program, "Position"); attrib_position = glGetAttribLocation(Program, "Position");
attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
uniform_tex = glGetUniformLocation(Program, "tex"); uniform_tex = glGetUniformLocation(Program, "tex");
@ -1597,11 +1625,21 @@ namespace MeshShader
attrib_texcoord = -1; attrib_texcoord = -1;
return; return;
} }
Program = LoadProgram( if (irr_driver->hasVSLayerExtension())
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), {
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(), Program = LoadProgram(
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str());
}
else
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(),
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str());
}
attrib_position = glGetAttribLocation(Program, "Position"); attrib_position = glGetAttribLocation(Program, "Position");
attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
attrib_origin = glGetAttribLocation(Program, "Origin"); attrib_origin = glGetAttribLocation(Program, "Origin");
@ -1754,7 +1792,6 @@ namespace LightShader
GLuint PointLightShader::attrib_Position; GLuint PointLightShader::attrib_Position;
GLuint PointLightShader::attrib_Color; GLuint PointLightShader::attrib_Color;
GLuint PointLightShader::attrib_Energy; GLuint PointLightShader::attrib_Energy;
GLuint PointLightShader::attrib_Corner;
GLuint PointLightShader::uniform_ntex; GLuint PointLightShader::uniform_ntex;
GLuint PointLightShader::uniform_dtex; GLuint PointLightShader::uniform_dtex;
GLuint PointLightShader::uniform_spec; GLuint PointLightShader::uniform_spec;
@ -1773,7 +1810,6 @@ namespace LightShader
attrib_Position = glGetAttribLocation(Program, "Position"); attrib_Position = glGetAttribLocation(Program, "Position");
attrib_Color = glGetAttribLocation(Program, "Color"); attrib_Color = glGetAttribLocation(Program, "Color");
attrib_Energy = glGetAttribLocation(Program, "Energy"); attrib_Energy = glGetAttribLocation(Program, "Energy");
attrib_Corner = glGetAttribLocation(Program, "Corner");
uniform_ntex = glGetUniformLocation(Program, "ntex"); uniform_ntex = glGetUniformLocation(Program, "ntex");
uniform_dtex = glGetUniformLocation(Program, "dtex"); uniform_dtex = glGetUniformLocation(Program, "dtex");
uniform_spec = glGetUniformLocation(Program, "spec"); uniform_spec = glGetUniformLocation(Program, "spec");
@ -1782,10 +1818,6 @@ namespace LightShader
glGenVertexArrays(1, &vao); glGenVertexArrays(1, &vao);
glBindVertexArray(vao); glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, SharedObject::billboardvbo);
glEnableVertexAttribArray(attrib_Corner);
glVertexAttribPointer(attrib_Corner, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glGenBuffers(1, &vbo); glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, MAXLIGHT * sizeof(PointLightInfo), 0, GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, MAXLIGHT * sizeof(PointLightInfo), 0, GL_DYNAMIC_DRAW);

View File

@ -434,7 +434,6 @@ namespace LightShader
public: public:
static GLuint Program; static GLuint Program;
static GLuint attrib_Position, attrib_Energy, attrib_Color; static GLuint attrib_Position, attrib_Energy, attrib_Color;
static GLuint attrib_Corner;
static GLuint uniform_ntex, uniform_dtex, uniform_spec, uniform_screen; static GLuint uniform_ntex, uniform_dtex, uniform_spec, uniform_screen;
static GLuint vbo; static GLuint vbo;
static GLuint vao; static GLuint vao;

View File

@ -253,7 +253,7 @@ void STKAnimatedMesh::render()
for_in(mesh, TransparentMesh[TM_BUBBLE]) for_in(mesh, TransparentMesh[TM_BUBBLE])
drawBubble(*mesh, ModelViewProjectionMatrix); drawBubble(*mesh, ModelViewProjectionMatrix);
if (World::getWorld()->getTrack()->isFogEnabled()) if (World::getWorld()->isFogEnabled())
{ {
if (!TransparentMesh[TM_DEFAULT].empty() || !TransparentMesh[TM_ADDITIVE].empty()) if (!TransparentMesh[TM_DEFAULT].empty() || !TransparentMesh[TM_ADDITIVE].empty())
glUseProgram(MeshShader::TransparentFogShader::Program); glUseProgram(MeshShader::TransparentFogShader::Program);

View File

@ -56,18 +56,18 @@ void STKInstancedSceneNode::createGLMeshes()
isMaterialInitialized = false; isMaterialInitialized = false;
} }
template<typename T> template<typename T, unsigned divisor>
void setInstanceAttribPointer() void setInstanceAttribPointer()
{ {
glEnableVertexAttribArray(T::attrib_origin); glEnableVertexAttribArray(T::attrib_origin);
glVertexAttribPointer(T::attrib_origin, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0); glVertexAttribPointer(T::attrib_origin, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0);
glVertexAttribDivisor(T::attrib_origin, 1); glVertexAttribDivisor(T::attrib_origin, divisor);
glEnableVertexAttribArray(T::attrib_orientation); glEnableVertexAttribArray(T::attrib_orientation);
glVertexAttribPointer(T::attrib_orientation, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float))); glVertexAttribPointer(T::attrib_orientation, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(T::attrib_orientation, 1); glVertexAttribDivisor(T::attrib_orientation, divisor);
glEnableVertexAttribArray(T::attrib_scale); glEnableVertexAttribArray(T::attrib_scale);
glVertexAttribPointer(T::attrib_scale, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float))); glVertexAttribPointer(T::attrib_scale, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(T::attrib_scale, 1); glVertexAttribDivisor(T::attrib_scale, divisor);
} }
void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat) void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat)
@ -80,12 +80,12 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria
glGenBuffers(1, &instances_vbo); glGenBuffers(1, &instances_vbo);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
setInstanceAttribPointer<MeshShader::InstancedObjectPass1Shader>(); setInstanceAttribPointer<MeshShader::InstancedObjectPass1Shader, 1>();
if (irr_driver->getGLSLVersion() >= 150) if (irr_driver->getGLSLVersion() >= 150)
{ {
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride); mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedShadowShader>(); setInstanceAttribPointer<MeshShader::InstancedShadowShader, 4>();
} }
break; break;
case FPSM_ALPHA_REF_TEXTURE: case FPSM_ALPHA_REF_TEXTURE:
@ -94,12 +94,12 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria
glGenBuffers(1, &instances_vbo); glGenBuffers(1, &instances_vbo);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
setInstanceAttribPointer<MeshShader::InstancedObjectRefPass1Shader>(); setInstanceAttribPointer<MeshShader::InstancedObjectRefPass1Shader, 1>();
if (irr_driver->getGLSLVersion() >= 150) if (irr_driver->getGLSLVersion() >= 150)
{ {
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedRefShadowShader::attrib_position, MeshShader::InstancedRefShadowShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedRefShadowShader::attrib_position, MeshShader::InstancedRefShadowShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedRefShadowShader>(); setInstanceAttribPointer<MeshShader::InstancedRefShadowShader, 4>();
} }
break; break;
case FPSM_GRASS: case FPSM_GRASS:
@ -108,7 +108,7 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria
glGenBuffers(1, &instances_vbo); glGenBuffers(1, &instances_vbo);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
setInstanceAttribPointer<MeshShader::InstancedGrassPass1Shader>(); setInstanceAttribPointer<MeshShader::InstancedGrassPass1Shader, 1>();
break; break;
default: default:
return; return;
@ -122,19 +122,19 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
MeshShader::InstancedObjectPass2Shader::attrib_position, MeshShader::InstancedObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); MeshShader::InstancedObjectPass2Shader::attrib_position, MeshShader::InstancedObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedObjectPass2Shader>(); setInstanceAttribPointer<MeshShader::InstancedObjectPass2Shader, 1>();
break; break;
case SM_ALPHA_REF_TEXTURE: case SM_ALPHA_REF_TEXTURE:
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
MeshShader::InstancedObjectRefPass2Shader::attrib_position, MeshShader::InstancedObjectRefPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); MeshShader::InstancedObjectRefPass2Shader::attrib_position, MeshShader::InstancedObjectRefPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedObjectRefPass2Shader>(); setInstanceAttribPointer<MeshShader::InstancedObjectRefPass2Shader, 1>();
break; break;
case SM_GRASS: case SM_GRASS:
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
MeshShader::InstancedGrassPass2Shader::attrib_position, MeshShader::InstancedGrassPass2Shader::attrib_texcoord, -1, MeshShader::InstancedGrassPass2Shader::attrib_normal, -1, -1, MeshShader::InstancedGrassPass2Shader::attrib_color, mesh.Stride); MeshShader::InstancedGrassPass2Shader::attrib_position, MeshShader::InstancedGrassPass2Shader::attrib_texcoord, -1, MeshShader::InstancedGrassPass2Shader::attrib_normal, -1, -1, MeshShader::InstancedGrassPass2Shader::attrib_color, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedGrassPass2Shader>(); setInstanceAttribPointer<MeshShader::InstancedGrassPass2Shader, 1>();
break; break;
default: default:
return; return;
@ -220,7 +220,7 @@ static void drawShadowDefault(GLMesh &mesh, size_t instance_count)
assert(mesh.vao_shadow_pass); assert(mesh.vao_shadow_pass);
glBindVertexArray(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count); glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count);
} }
static void drawFSPMAlphaRefTexture(GLMesh &mesh, size_t instance_count) static void drawFSPMAlphaRefTexture(GLMesh &mesh, size_t instance_count)

View File

@ -710,7 +710,7 @@ void drawShadowRef(const GLMesh &mesh, const core::matrix4 &ModelMatrix)
assert(mesh.vao_shadow_pass); assert(mesh.vao_shadow_pass);
glBindVertexArray(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass);
glDrawElements(ptype, count, itype, 0); glDrawElementsInstanced(ptype, count, itype, 0, 4);
} }
void drawShadow(const GLMesh &mesh, const core::matrix4 &ModelMatrix) void drawShadow(const GLMesh &mesh, const core::matrix4 &ModelMatrix)
@ -724,7 +724,7 @@ void drawShadow(const GLMesh &mesh, const core::matrix4 &ModelMatrix)
assert(mesh.vao_shadow_pass); assert(mesh.vao_shadow_pass);
glBindVertexArray(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass);
glDrawElements(ptype, count, itype, 0); glDrawElementsInstanced(ptype, count, itype, 0, 4);
} }
bool isObject(video::E_MATERIAL_TYPE type) bool isObject(video::E_MATERIAL_TYPE type)
@ -858,7 +858,7 @@ void initvaostate(GLMesh &mesh, TransparentMaterial TranspMat)
break; break;
case TM_DEFAULT: case TM_DEFAULT:
case TM_ADDITIVE: case TM_ADDITIVE:
if (World::getWorld()->getTrack()->isFogEnabled()) if (World::getWorld()->isFogEnabled())
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
MeshShader::TransparentFogShader::attrib_position, MeshShader::TransparentFogShader::attrib_texcoord, -1, -1, -1, -1, MeshShader::TransparentFogShader::attrib_color, mesh.Stride); MeshShader::TransparentFogShader::attrib_position, MeshShader::TransparentFogShader::attrib_texcoord, -1, -1, -1, -1, MeshShader::TransparentFogShader::attrib_color, mesh.Stride);
else else

View File

@ -501,7 +501,7 @@ void STKMeshSceneNode::render()
for_in(mesh, TransparentMesh[TM_BUBBLE]) for_in(mesh, TransparentMesh[TM_BUBBLE])
drawBubble(*mesh, ModelViewProjectionMatrix); drawBubble(*mesh, ModelViewProjectionMatrix);
if (World::getWorld()->getTrack()->isFogEnabled()) if (World::getWorld() ->isFogEnabled())
{ {
if (!TransparentMesh[TM_DEFAULT].empty() || !TransparentMesh[TM_ADDITIVE].empty()) if (!TransparentMesh[TM_DEFAULT].empty() || !TransparentMesh[TM_ADDITIVE].empty())
glUseProgram(MeshShader::TransparentFogShader::Program); glUseProgram(MeshShader::TransparentFogShader::Program);

View File

@ -45,6 +45,8 @@
#include <string> #include <string>
bool CutsceneWorld::s_use_duration = false;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Constructor. Sets up the clock mode etc. /** Constructor. Sets up the clock mode etc.
*/ */
@ -152,6 +154,9 @@ void CutsceneWorld::init()
} }
} }
if (!s_use_duration)
m_duration = 999999.0f;
if (m_duration <= 0.0f) if (m_duration <= 0.0f)
{ {
Log::error("[CutsceneWorld]", "WARNING: cutscene has no duration"); Log::error("[CutsceneWorld]", "WARNING: cutscene has no duration");
@ -367,6 +372,7 @@ void CutsceneWorld::enterRaceOverState()
if (m_aborted || partId == -1 || partId == (int)m_parts.size() - 1) if (m_aborted || partId == -1 || partId == (int)m_parts.size() - 1)
{ {
// TODO: remove hardcoded knowledge of cutscenes, replace with scripting probably
if (m_parts.size() == 1 && m_parts[0] == "endcutscene") if (m_parts.size() == 1 && m_parts[0] == "endcutscene")
{ {
CreditsScreen* credits = CreditsScreen::getInstance(); CreditsScreen* credits = CreditsScreen::getInstance();
@ -377,6 +383,23 @@ void CutsceneWorld::enterRaceOverState()
StateManager::get()->resetAndSetStack(newStack); StateManager::get()->resetAndSetStack(newStack);
StateManager::get()->pushScreen(credits); StateManager::get()->pushScreen(credits);
} }
// TODO: remove hardcoded knowledge of cutscenes, replace with scripting probably
else if (m_parts.size() == 1 && m_parts[0] == "gpwin")
{
race_manager->exitRace();
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
if (race_manager->raceWasStartedFromOverworld())
OverWorld::enterOverWorld();
}
// TODO: remove hardcoded knowledge of cutscenes, replace with scripting probably
else if (m_parts.size() == 1 && m_parts[0] == "gplose")
{
race_manager->exitRace();
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
if (race_manager->raceWasStartedFromOverworld())
OverWorld::enterOverWorld();
}
// TODO: remove hardcoded knowledge of cutscenes, replace with scripting probably
else if (race_manager->getTrackName() == "introcutscene" || else if (race_manager->getTrackName() == "introcutscene" ||
race_manager->getTrackName() == "introcutscene2") race_manager->getTrackName() == "introcutscene2")
{ {
@ -417,6 +440,9 @@ void CutsceneWorld::enterRaceOverState()
*/ */
bool CutsceneWorld::isRaceOver() bool CutsceneWorld::isRaceOver()
{ {
if (!s_use_duration && !m_aborted)
return false;
return m_time > m_duration; return m_time > m_duration;
} // isRaceOver } // isRaceOver

View File

@ -45,18 +45,15 @@ class CutsceneWorld : public World
double m_duration; double m_duration;
bool m_aborted; bool m_aborted;
// TODO find a better way than static
static bool s_use_duration;
/** monkey tricks to get the animations in sync with irrlicht. we reset the time /** monkey tricks to get the animations in sync with irrlicht. we reset the time
* after all is loaded and it's running withotu delays * after all is loaded and it's running withotu delays
*/ */
bool m_second_reset; bool m_second_reset;
double m_time_at_second_reset; double m_time_at_second_reset;
void abortCutscene()
{
if (m_time < m_duration - 2.0f) m_duration = m_time + 2.0f;
m_aborted = true;
}
std::vector<std::string> m_parts; std::vector<std::string> m_parts;
public: public:
@ -107,6 +104,14 @@ public:
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual void escapePressed() OVERRIDE { abortCutscene(); } virtual void escapePressed() OVERRIDE { abortCutscene(); }
// ------------------------------------------------------------------------
static void setUseDuration(bool use_duration) { s_use_duration = use_duration; }
// ------------------------------------------------------------------------
void abortCutscene()
{
if (m_time < m_duration - 2.0f) m_duration = m_time + 2.0f;
m_aborted = true;
}
}; // CutsceneWorld }; // CutsceneWorld

View File

@ -1180,4 +1180,11 @@ void World::escapePressed()
new RacePausedDialog(0.8f, 0.6f); new RacePausedDialog(0.8f, 0.6f);
} }
//-----------------------------------------------------------------------------
bool World::isFogEnabled() const
{
return m_track != NULL && m_track->isFogEnabled();
}
/* EOF */ /* EOF */

View File

@ -302,6 +302,8 @@ public:
/** Returns a pointer to the track. */ /** Returns a pointer to the track. */
Track *getTrack() const { return m_track; } Track *getTrack() const { return m_track; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool isFogEnabled() const;
// ------------------------------------------------------------------------
/** The code that draws the timer should call this first to know /** The code that draws the timer should call this first to know
* whether the game mode wants a timer drawn. */ * whether the game mode wants a timer drawn. */
virtual bool shouldDrawTimer() const virtual bool shouldDrawTimer() const

View File

@ -685,23 +685,43 @@ void RaceManager::exitRace(bool delete_world)
if (someHumanPlayerWon) if (someHumanPlayerWon)
{ {
StateManager::get()->pushScreen( GrandPrixWin::getInstance() ); if (delete_world) World::deleteWorld();
GrandPrixWin::getInstance()->setKarts(winners); delete_world = false;
StateManager::get()->enterGameState();
race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
race_manager->setNumKarts(0);
race_manager->setNumPlayers(0);
race_manager->setNumLocalPlayers(0);
race_manager->startSingleRace("gpwin", 999, false);
GrandPrixWin* scene = GrandPrixWin::getInstance();
StateManager::get()->pushScreen(scene);
scene->setKarts(winners);
} }
else else
{ {
StateManager::get()->pushScreen( GrandPrixLose::getInstance() ); if (delete_world) World::deleteWorld();
delete_world = false;
StateManager::get()->enterGameState();
race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
race_manager->setNumKarts(0);
race_manager->setNumPlayers(0);
race_manager->setNumLocalPlayers(0);
race_manager->startSingleRace("gplose", 999, false);
GrandPrixLose* scene = GrandPrixLose::getInstance();
StateManager::get()->pushScreen(scene);
if (humanLosers.size() >= 1) if (humanLosers.size() >= 1)
{ {
GrandPrixLose::getInstance()->setKarts( humanLosers ); scene->setKarts(humanLosers);
} }
else else
{ {
std::cerr << "RaceManager::exitRace() : what's going on?? no winners and no losers??\n"; std::cerr << "RaceManager::exitRace() : what's going on?? no winners and no losers??\n";
std::vector<std::string> karts; std::vector<std::string> karts;
karts.push_back(UserConfigParams::m_default_kart); karts.push_back(UserConfigParams::m_default_kart);
GrandPrixLose::getInstance()->setKarts( karts ); scene->setKarts(karts);
} }
} }
} }

View File

@ -31,10 +31,15 @@
#include "items/item_manager.hpp" #include "items/item_manager.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp" #include "karts/kart_properties_manager.hpp"
#include "modes/cutscene_world.hpp"
#include "modes/overworld.hpp" #include "modes/overworld.hpp"
#include "modes/world.hpp"
#include "states_screens/feature_unlocked.hpp" #include "states_screens/feature_unlocked.hpp"
#include "states_screens/main_menu_screen.hpp" #include "states_screens/main_menu_screen.hpp"
#include "states_screens/state_manager.hpp" #include "states_screens/state_manager.hpp"
#include "tracks/track.hpp"
#include "tracks/track_object.hpp"
#include "tracks/track_object_manager.hpp"
#include "utils/translation.hpp" #include "utils/translation.hpp"
#include <ISceneManager.h> #include <ISceneManager.h>
@ -61,10 +66,11 @@ const float CAMERA_START_Z = 5.5f;
const float DISTANCE_BETWEEN_KARTS = 2.0f; const float DISTANCE_BETWEEN_KARTS = 2.0f;
const float KART_SCALE = 0.75f;
const float KART_START_X = -17.0f; const float KART_START_X = -17.0f;
const float KART_END_X = -5.0f; const float KART_END_X = -5.0f;
const float KART_Y = -3.0f; const float KART_Y = 0.0f;
const float KART_Z = 0.0f; const float KART_Z = 0.0f;
@ -76,22 +82,11 @@ DEFINE_SCREEN_SINGLETON( GrandPrixLose );
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
GrandPrixLose::GrandPrixLose() : Screen("grand_prix_lose.stkgui") GrandPrixLose::GrandPrixLose() : Screen("grand_prix_lose.stkgui", false /* pause race */)
{ {
setNeeds3D(true); setNeeds3D(true);
m_throttle_FPS = false; m_throttle_FPS = false;
try
{
std::string path = file_manager->getAsset(FileManager::MUSIC, "lose_theme.music");
m_music = music_manager->getMusicInformation(path);
}
catch (std::exception& e)
{
fprintf(stderr, "[GrandPrixLose] WARNING: exception caught when trying to load music: %s\n", e.what());
m_music = NULL;
}
} // GrandPrixLose } // GrandPrixLose
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
@ -108,61 +103,17 @@ void GrandPrixLose::loadedFromFile()
void GrandPrixLose::init() void GrandPrixLose::init()
{ {
std::vector<std::string> parts;
parts.push_back("gplose");
((CutsceneWorld*)World::getWorld())->setParts(parts);
CutsceneWorld::setUseDuration(false);
Screen::init(); Screen::init();
World::getWorld()->setPhase(WorldStatus::RACE_PHASE);
m_phase = 1; m_phase = 1;
m_sky_angle = 0.0f;
m_global_time = 0.0f; m_global_time = 0.0f;
video::ITexture *t = irr_driver->getTexture(FileManager::TEXTURE, "clouds.png");
m_sky = irr_driver->addSkyDome(t,
16 /* hori_res */, 16 /* vert_res */,
1.0f /* texture_percent */, 2.0f /* sphere_percent */);
m_camera = irr_driver->addCameraSceneNode();
m_camera_x = CAMERA_START_X;
m_camera_y = CAMERA_START_Y;
m_camera_z = CAMERA_START_Z;
m_camera->setPosition( core::vector3df(m_camera_x, m_camera_y, m_camera_z) );
m_camera->setUpVector( core::vector3df(0.0, 1.0, 0.0) );
irr_driver->getSceneManager()->setActiveCamera(m_camera);
m_camera_target_x = 0.0f;
m_camera_target_z = -2.0f;
m_camera->setTarget( core::vector3df(m_camera_target_x, -2.0f, m_camera_target_z) );
m_camera->setFOV( DEGREE_TO_RAD*50.0f );
m_camera->updateAbsolutePosition();
scene::IAnimatedMesh* model_garage_door = irr_driver->getAnimatedMesh( file_manager->getAsset(FileManager::MODEL,"gplose_door.b3d") );
assert(model_garage_door!= NULL);
m_garage_door = irr_driver->addAnimatedMesh(model_garage_door);
#ifdef DEBUG
m_garage_door->setName("garage-door");
#endif
m_garage_door->setPosition( core::vector3df(2, INITIAL_Y, 0) );
m_garage_door->setAnimationSpeed(0);
scene::IMesh* model_garage = irr_driver->getMesh( file_manager->getAsset(FileManager::MODEL,"gplose.b3d") );
assert(model_garage!= NULL);
m_garage = irr_driver->addMesh(model_garage);
#ifdef DEBUG
m_garage->setName("garage");
#endif
m_garage->setPosition( core::vector3df(2, INITIAL_Y, 0) );
scene::ISceneManager* sceneManager = irr_driver->getSceneManager();
sceneManager->setAmbientLight(video::SColor(255, 120, 120, 120));
const core::vector3df &sun_pos = core::vector3df( 0, 200, 100.0f );
m_light = irr_driver->addLight(sun_pos, 300.0f, 1, 1, 1);
if (!irr_driver->isGLSL())
{
scene::ILightSceneNode *lnode = (scene::ILightSceneNode *) m_light;
lnode->getLightData().DiffuseColor = irr::video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
lnode->getLightData().SpecularColor = irr::video::SColorf(1.0f, 0.0f, 0.0f, 0.0f);
}
} // init } // init
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
@ -170,32 +121,17 @@ void GrandPrixLose::init()
void GrandPrixLose::tearDown() void GrandPrixLose::tearDown()
{ {
Screen::tearDown(); Screen::tearDown();
irr_driver->removeNode(m_sky); ((CutsceneWorld*)World::getWorld())->abortCutscene();
m_sky = NULL;
irr_driver->removeCameraSceneNode(m_camera); for (unsigned int i=0; i<m_all_kart_models.size(); i++)
m_camera = NULL;
irr_driver->removeNode(m_light);
m_light = NULL;
irr_driver->removeNode(m_garage);
irr_driver->removeNode(m_garage_door);
m_garage = NULL;
for(unsigned int i=0; i<m_all_kart_models.size(); i++)
delete m_all_kart_models[i]; delete m_all_kart_models[i];
m_all_kart_models.clear(); m_all_kart_models.clear();
for (int n=0; n<MAX_KART_COUNT; n++) m_kart_node[0] = NULL;
{ m_kart_node[1] = NULL;
if (m_kart_node[n] != NULL) m_kart_node[2] = NULL;
{ m_kart_node[3] = NULL;
irr_driver->removeNode(m_kart_node[n]);
}
}
} // tearDown } // tearDown
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
@ -204,54 +140,25 @@ void GrandPrixLose::onUpdate(float dt)
{ {
m_global_time += dt; m_global_time += dt;
m_sky_angle += dt*2;
if (m_sky_angle > 360) m_sky_angle -= 360;
m_sky->setRotation( core::vector3df(0, m_sky_angle, 0) );
const int lastFrame = m_garage_door->getEndFrame();
if (m_global_time < GARAGE_DOOR_OPEN_TIME)
{
m_garage_door->setCurrentFrame( (m_global_time/GARAGE_DOOR_OPEN_TIME)*lastFrame );
}
else if (m_global_time > DURATION - GARAGE_DOOR_OPEN_TIME)
{
m_garage_door->setCurrentFrame( (1.0f - ((m_global_time -
(DURATION - GARAGE_DOOR_OPEN_TIME))/GARAGE_DOOR_OPEN_TIME))
*lastFrame );
}
//else if (m_global_time < DURATION)
//{
// m_garage_door->setCurrentFrame( lastFrame );
//}
const float kartProgression = m_global_time/(DURATION - 6.0f); const float kartProgression = m_global_time/(DURATION - 6.0f);
if (kartProgression <= 1.0f) if (kartProgression <= 1.0f)
{ {
m_kart_x = KART_START_X + (KART_END_X - KART_START_X)*kartProgression; m_kart_x = KART_START_X + (KART_END_X - KART_START_X)*kartProgression;
core::vector3df kart_rot(0.0f, 90.0f, 0.0f);
core::vector3df kart_scale(KART_SCALE, KART_SCALE, KART_SCALE);
for (int n=0; n<MAX_KART_COUNT; n++) for (int n=0; n<MAX_KART_COUNT; n++)
{ {
if (m_kart_node[n] != NULL) if (m_kart_node[n] != NULL)
{ {
m_kart_node[n]->setPosition( core::vector3df(m_kart_x + n*DISTANCE_BETWEEN_KARTS, core::vector3df kart_pos(m_kart_x + n*DISTANCE_BETWEEN_KARTS,
m_kart_y, m_kart_y,
m_kart_z) ); m_kart_z);
m_kart_node[n]->move(kart_pos, kart_rot, kart_scale, false);
} }
} }
} }
const float progression = m_global_time / DURATION;
if (progression <= 1.5f)
{
m_camera_x = CAMERA_START_X + (CAMERA_END_X - CAMERA_START_X)*progression;
m_camera_y = CAMERA_START_Y + (CAMERA_END_Y - CAMERA_START_Y)*progression;
m_camera_z = CAMERA_START_Z + (CAMERA_END_Z - CAMERA_START_Z)*progression;
}
m_camera->setPosition( core::vector3df(m_camera_x, m_camera_y, m_camera_z) );
m_camera->setUpVector( core::vector3df(0.0, 1.0, 0.0) );
m_camera->updateAbsolutePosition();
// ---- title // ---- title
const int w = irr_driver->getFrameSize().Width; const int w = irr_driver->getFrameSize().Width;
const int h = irr_driver->getFrameSize().Height; const int h = irr_driver->getFrameSize().Height;
@ -311,7 +218,7 @@ void GrandPrixLose::eventCallback(GUIEngine::Widget* widget,
void GrandPrixLose::setKarts(std::vector<std::string> ident_arg) void GrandPrixLose::setKarts(std::vector<std::string> ident_arg)
{ {
scene::ISceneNode* kart_main_node = NULL; TrackObjectManager* tobjman = World::getWorld()->getTrack()->getTrackObjectManager();
assert(ident_arg.size() > 0); assert(ident_arg.size() > 0);
if ((int)ident_arg.size() > MAX_KART_COUNT) if ((int)ident_arg.size() > MAX_KART_COUNT)
@ -324,6 +231,10 @@ void GrandPrixLose::setKarts(std::vector<std::string> ident_arg)
m_kart_node[2] = NULL; m_kart_node[2] = NULL;
m_kart_node[3] = NULL; m_kart_node[3] = NULL;
m_kart_x = KART_START_X;
m_kart_y = KART_Y;
m_kart_z = KART_Z;
const int count = ident_arg.size(); const int count = ident_arg.size();
for (int n=0; n<count; n++) for (int n=0; n<count; n++)
{ {
@ -332,59 +243,29 @@ void GrandPrixLose::setKarts(std::vector<std::string> ident_arg)
{ {
KartModel* kart_model = kart->getKartModelCopy(); KartModel* kart_model = kart->getKartModelCopy();
m_all_kart_models.push_back(kart_model); m_all_kart_models.push_back(kart_model);
m_kart_x = KART_START_X; scene::ISceneNode* kart_main_node = kart_model->attachModel(false);
m_kart_y = KART_Y;
m_kart_z = KART_Z;
kart_main_node = kart_model->attachModel(false); core::vector3df kart_pos(m_kart_x + n*DISTANCE_BETWEEN_KARTS,
kart_main_node->setPosition( core::vector3df(m_kart_x, m_kart_y, m_kart_z) ); m_kart_y,
//kart_main_node->setScale( core::vector3df(0.4f, 0.4f, 0.4f) ); m_kart_z);
kart_main_node->updateAbsolutePosition(); core::vector3df kart_rot(0, 90.0f, 0);
kart_main_node->setRotation(vector3df(0, 90, 0)); core::vector3df kart_scale(KART_SCALE, KART_SCALE, KART_SCALE);
float susp[4]={0,0,0,0};
kart_model->update(0.0f, 0.0f, 0.0f, susp, 0.0f); //FIXME: it's not ideal that both the track object and the presentation know the initial coordinates of the object
TrackObjectPresentationSceneNode* presentation = new TrackObjectPresentationSceneNode(
kart_main_node, kart_pos, kart_rot, kart_scale);
TrackObject* tobj = new TrackObject(kart_pos, kart_rot, kart_scale,
"ghost", presentation, false /* isDynamic */, NULL /* physics settings */);
tobjman->insertObject(tobj);
m_kart_node[n] = tobj;
} }
else else
{ {
fprintf(stderr, "[GrandPrixLose] WARNING: could not find a kart named '%s'\n", ident_arg[n].c_str()); fprintf(stderr, "[GrandPrixLose] WARNING: could not find a kart named '%s'\n", ident_arg[n].c_str());
m_kart_node[n] = NULL;
}// if kart !=NULL }// if kart !=NULL
m_kart_node[n] = kart_main_node;
} }
/*
const int w = UserConfigParams::m_width;
const int h = UserConfigParams::m_height;
switch (count)
{
case 1:
m_viewport[0] = core::recti(0, 0, w, h);
break;
case 2:
m_viewport[0] = core::recti(0, 0, w, h/2);
m_viewport[1] = core::recti(0, h/2, w, h);
break;
case 3:
m_viewport[0] = core::recti(0, 0, w/2, h/2);
m_viewport[1] = core::recti(w/2, 0, 2, h/2);
m_viewport[2] = core::recti(0, h/2, w, h);
break;
case 4:
m_viewport[0] = core::recti(0, 0, w/2, h/2);
m_viewport[1] = core::recti(w/2, 0, 2, h/2);
m_viewport[2] = core::recti(0, h/2, w/2, h);
m_viewport[3] = core::recti(w/2, h/2, w, h);
break;
default:
assert(false);
}
*/
} // setKarts } // setKarts
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------

View File

@ -27,6 +27,7 @@
namespace irr { namespace scene { class ISceneNode; class ICameraSceneNode; class ILightSceneNode; class IMeshSceneNode; } } namespace irr { namespace scene { class ISceneNode; class ICameraSceneNode; class ILightSceneNode; class IMeshSceneNode; } }
class KartProperties; class KartProperties;
class TrackObject;
/** /**
* \brief Screen shown at the end of a Grand Prix * \brief Screen shown at the end of a Grand Prix
@ -38,22 +39,10 @@ class GrandPrixLose : public GUIEngine::Screen, public GUIEngine::ScreenSingleto
GrandPrixLose(); GrandPrixLose();
/** sky angle, 0-360 */
float m_sky_angle;
/** Global evolution of time */ /** Global evolution of time */
float m_global_time; float m_global_time;
irr::scene::IMeshSceneNode* m_garage; TrackObject* m_kart_node[4];
irr::scene::IAnimatedMeshSceneNode* m_garage_door;
irr::scene::ISceneNode* m_kart_node[4];
irr::scene::ISceneNode* m_sky;
irr::scene::ICameraSceneNode* m_camera;
irr::scene::ISceneNode* m_light;
/** A copy of the kart model for each kart used. */ /** A copy of the kart model for each kart used. */
std::vector<KartModel*> m_all_kart_models; std::vector<KartModel*> m_all_kart_models;
@ -62,13 +51,6 @@ class GrandPrixLose : public GUIEngine::Screen, public GUIEngine::ScreenSingleto
float m_kart_x, m_kart_y, m_kart_z; float m_kart_x, m_kart_y, m_kart_z;
float m_camera_x, m_camera_y, m_camera_z;
float m_camera_target_x, m_camera_target_z;
MusicInformation* m_music;
//irr::core::recti m_viewport[4];
public: public:
/** \brief implement callback from parent class GUIEngine::Screen */ /** \brief implement callback from parent class GUIEngine::Screen */
@ -89,9 +71,6 @@ public:
/** \brief set which karts lost this GP */ /** \brief set which karts lost this GP */
void setKarts(std::vector<std::string> ident); void setKarts(std::vector<std::string> ident);
virtual MusicInformation* getMusic() const OVERRIDE { return m_music; }
}; };
#endif #endif

View File

@ -33,8 +33,13 @@
#include "items/item_manager.hpp" #include "items/item_manager.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp" #include "karts/kart_properties_manager.hpp"
#include "modes/cutscene_world.hpp"
#include "modes/world.hpp"
#include "states_screens/feature_unlocked.hpp" #include "states_screens/feature_unlocked.hpp"
#include "states_screens/state_manager.hpp" #include "states_screens/state_manager.hpp"
#include "tracks/track.hpp"
#include "tracks/track_object.hpp"
#include "tracks/track_object_manager.hpp"
#include "utils/translation.hpp" #include "utils/translation.hpp"
#include <IGUIEnvironment.h> #include <IGUIEnvironment.h>
@ -48,56 +53,54 @@ using namespace irr::core;
using namespace irr::gui; using namespace irr::gui;
using namespace irr::video; using namespace irr::video;
const float KARTS_DELTA_Y = 0.03f; const float KARTS_X = -0.62f;
const float INITIAL_Y = -3.0f; const float KARTS_DELTA_X = 0.815f;
const float INITIAL_PODIUM_Y = -3.6f; const float KARTS_DELTA_Y = -0.55f;
const float KARTS_DEST_Z = 1.2f;
const float INITIAL_Y = 0.0f;
const float INITIAL_PODIUM_Y = -0.89f;
const float PODIUM_HEIGHT[3] = { 0.325f, 0.5f, 0.15f }; const float PODIUM_HEIGHT[3] = { 0.325f, 0.5f, 0.15f };
DEFINE_SCREEN_SINGLETON( GrandPrixWin ); DEFINE_SCREEN_SINGLETON( GrandPrixWin );
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
GrandPrixWin::GrandPrixWin() : Screen("grand_prix_win.stkgui") GrandPrixWin::GrandPrixWin() : Screen("grand_prix_win.stkgui", false /* pause race */)
{ {
setNeeds3D(true); setNeeds3D(true);
m_throttle_FPS = false; m_throttle_FPS = false;
try m_kart_node[0] = NULL;
{ m_kart_node[1] = NULL;
std::string path = file_manager->getAsset(FileManager::MUSIC,"win_theme.music"); m_kart_node[2] = NULL;
m_music = music_manager->getMusicInformation(path);
} m_podium_steps[0] = NULL;
catch (std::exception& e) m_podium_steps[1] = NULL;
{ m_podium_steps[2] = NULL;
fprintf(stderr, "[GrandPrixWin] WARNING: exception caught when trying to load music: %s\n", e.what());
m_music = NULL;
}
} // GrandPrixWin } // GrandPrixWin
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
void GrandPrixWin::loadedFromFile() void GrandPrixWin::loadedFromFile()
{ {
m_kart_node[0] = NULL;
m_kart_node[1] = NULL;
m_kart_node[2] = NULL;
m_podium_x[0] = 1.4f;
m_podium_z[0] = 0.0f;
m_podium_x[1] = 2.2f;
m_podium_z[1] = 0.5f;
m_podium_x[2] = 3.0f;
m_podium_z[2] = 0.0f;
} // loadedFromFile } // loadedFromFile
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
void GrandPrixWin::init() void GrandPrixWin::init()
{ {
std::vector<std::string> parts;
parts.push_back("gpwin");
((CutsceneWorld*)World::getWorld())->setParts(parts);
CutsceneWorld::setUseDuration(false);
Screen::init(); Screen::init();
World::getWorld()->setPhase(WorldStatus::RACE_PHASE);
if (PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges().size() > 0) if (PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges().size() > 0)
{ {
const core::dimension2d<u32>& frame_size = GUIEngine::getDriver()->getCurrentRenderTargetSize(); const core::dimension2d<u32>& frame_size = GUIEngine::getDriver()->getCurrentRenderTargetSize();
@ -140,8 +143,6 @@ void GrandPrixWin::init()
m_unlocked_label->m_w = message_width; m_unlocked_label->m_w = message_width;
m_unlocked_label->m_h = label_height; m_unlocked_label->m_h = label_height;
m_unlocked_label->setText(message, false); m_unlocked_label->setText(message, false);
//const irr::video::SColor orange(255, 255, 126, 21);
//unlocked_label->setColor(orange);
m_unlocked_label->add(); m_unlocked_label->add();
manualAddWidget(m_unlocked_label); manualAddWidget(m_unlocked_label);
@ -151,77 +152,8 @@ void GrandPrixWin::init()
m_unlocked_label = NULL; m_unlocked_label = NULL;
} }
m_phase = 1;
m_sky_angle = 0.0f;
m_global_time = 0.0f; m_global_time = 0.0f;
m_phase = 1;
video::ITexture *t = irr_driver->getTexture(FileManager::TEXTURE,
"clouds.png ");
m_sky = irr_driver->addSkyDome(t,
16 /* hori_res */, 16 /* vert_res */,
1.0f /* texture_percent */,
2.0f /* sphere_percent */);
m_camera = irr_driver->addCameraSceneNode();
m_camera_x = 3.0f;
m_camera_y = 0.0f;
m_camera_z = -5.0f;
m_camera->setPosition( core::vector3df(m_camera_x, m_camera_y, m_camera_z) );
m_camera->setUpVector( core::vector3df(0.0, 1.0, 0.0) );
irr_driver->getSceneManager()->setActiveCamera(m_camera);
m_camera_target_x = 1.5f;
m_camera_target_z = 0.0f;
m_camera->setTarget( core::vector3df(m_camera_target_x, -2.0f, m_camera_target_z) );
m_camera->setFOV( DEGREE_TO_RAD*50.0f );
m_camera->updateAbsolutePosition();
scene::IMesh* model_village = irr_driver->getMesh( file_manager->getAsset(FileManager::MODEL,"village.b3d") );
assert(model_village != NULL);
m_village = irr_driver->addMesh(model_village);
#ifdef DEBUG
m_village->setName("village");
#endif
m_village->setPosition( core::vector3df(2, INITIAL_Y, 0) );
scene::IMesh* podium_model = irr_driver->getMesh( file_manager->getAsset(FileManager::MODEL,"wood_podium.b3d") );
assert(podium_model != NULL);
m_podium_step[0] = irr_driver->addMesh(podium_model);
#ifdef DEBUG
m_podium_step[0]->setName("Podium 0");
#endif
m_podium_step[0]->setPosition( core::vector3df(m_podium_x[0], INITIAL_PODIUM_Y, m_podium_z[0]) );
m_podium_step[1] = irr_driver->addMesh(podium_model);
#ifdef DEBUG
m_podium_step[1]->setName("Podium 1");
#endif
m_podium_step[1]->setPosition( core::vector3df(m_podium_x[1], INITIAL_PODIUM_Y, m_podium_z[1]) );
m_podium_step[2] = irr_driver->addMesh(podium_model);
#ifdef DEBUG
m_podium_step[2]->setName("Podium 2");
#endif
m_podium_step[2]->setPosition( core::vector3df(m_podium_x[2], INITIAL_PODIUM_Y, m_podium_z[2]) );
scene::ISceneManager* sceneManager = irr_driver->getSceneManager();
sceneManager->setAmbientLight(video::SColor(255, 95, 95, 95));
const core::vector3df &sun_pos = core::vector3df( 0, 200, 100.0f );
m_light = irr_driver->addLight(sun_pos, 300.0f, 0.25f, 0.25f, 0.25f);
m_finish_sound = sfx_manager->quickSound("gp_end");
if (!irr_driver->isGLSL())
{
scene::ILightSceneNode *lnode = (scene::ILightSceneNode *) m_light;
lnode->getLightData().DiffuseColor = irr::video::SColorf(0.25f, 0.25f, 0.25f, 1.0f);
lnode->getLightData().AmbientColor = irr::video::SColorf(0.25f, 0.25f, 0.25f, 1.0f);
lnode->getLightData().SpecularColor = irr::video::SColorf(0.0f, 0.0f, 0.0f, 1.0f);
}
sfx_manager->quickSound("gp_end"); sfx_manager->quickSound("gp_end");
} // init } // init
@ -231,26 +163,9 @@ void GrandPrixWin::init()
void GrandPrixWin::tearDown() void GrandPrixWin::tearDown()
{ {
Screen::tearDown(); Screen::tearDown();
irr_driver->removeNode(m_sky); ((CutsceneWorld*)World::getWorld())->abortCutscene();
m_sky = NULL;
irr_driver->removeCameraSceneNode(m_camera); for (unsigned int i = 0; i<m_all_kart_models.size(); i++)
m_camera = NULL;
irr_driver->removeNode(m_light);
m_light = NULL;
irr_driver->removeNode(m_village);
m_village = NULL;
for (int n=0; n<3; n++)
{
irr_driver->removeNode(m_podium_step[n]);
m_podium_step[n] = NULL;
if (m_kart_node[n] != NULL) irr_driver->removeNode(m_kart_node[n]);
m_kart_node[n] = NULL;
}
for(unsigned int i=0; i<m_all_kart_models.size(); i++)
delete m_all_kart_models[i]; delete m_all_kart_models[i];
m_all_kart_models.clear(); m_all_kart_models.clear();
@ -260,12 +175,14 @@ void GrandPrixWin::tearDown()
delete m_unlocked_label; delete m_unlocked_label;
m_unlocked_label = NULL; m_unlocked_label = NULL;
} }
if (m_finish_sound != NULL && m_kart_node[0] = NULL;
m_finish_sound->getStatus() == SFXManager::SFX_PLAYING) m_kart_node[1] = NULL;
{ m_kart_node[2] = NULL;
m_finish_sound->stop();
} m_podium_steps[0] = NULL;
m_podium_steps[1] = NULL;
m_podium_steps[2] = NULL;
} // tearDown } // tearDown
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
@ -274,11 +191,6 @@ void GrandPrixWin::onUpdate(float dt)
{ {
m_global_time += dt; m_global_time += dt;
m_sky_angle += dt*2;
if (m_sky_angle > 360) m_sky_angle -= 360;
m_sky->setRotation( core::vector3df(0, m_sky_angle, 0) );
// ---- karts move // ---- karts move
if (m_phase == 1) if (m_phase == 1)
{ {
@ -290,24 +202,27 @@ void GrandPrixWin::onUpdate(float dt)
if (m_kart_node[k] != NULL) if (m_kart_node[k] != NULL)
{ {
if (fabsf(m_kart_z[k] - m_podium_z[k]) > dt) if (fabsf(m_kart_z[k] - KARTS_DEST_Z) > dt)
{ {
if (m_kart_z[k] < m_podium_z[k] - dt) if (m_kart_z[k] < KARTS_DEST_Z - dt)
{ {
m_kart_z[k] += dt; m_kart_z[k] += dt;
} }
else if (m_kart_z[k] > m_podium_z[k] + dt) else if (m_kart_z[k] > KARTS_DEST_Z + dt)
{ {
m_kart_z[k] -= dt; m_kart_z[k] -= dt;
} }
else else
{ {
m_kart_z[k] = m_podium_z[k]; m_kart_z[k] = KARTS_DEST_Z;
} }
karts_not_yet_done++; karts_not_yet_done++;
} }
m_kart_node[k]->setPosition( core::vector3df(m_kart_x[k], m_kart_y[k], m_kart_z[k]) ); core::vector3df kart_pos(m_kart_x[k], m_kart_y[k], m_kart_z[k]);
core::vector3df kart_rot(0, m_kart_rotation[k], 0);
core::vector3df kart_scale(0.5f, 0.5f, 0.5f);
m_kart_node[k]->move(kart_pos, kart_rot, kart_scale, false);
} }
} // end for } // end for
@ -328,8 +243,16 @@ void GrandPrixWin::onUpdate(float dt)
if (m_kart_rotation[k] < 180.f) if (m_kart_rotation[k] < 180.f)
{ {
m_kart_rotation[k] += 25.0f*dt; m_kart_rotation[k] += 25.0f*dt;
m_kart_node[k]->setRotation( core::vector3df(0, m_kart_rotation[k], 0) );
m_podium_step[k]->setRotation( core::vector3df(0, m_kart_rotation[k], 0) ); core::vector3df kart_pos(m_kart_x[k], m_kart_y[k], m_kart_z[k]);
core::vector3df kart_rot(0, m_kart_rotation[k], 0);
core::vector3df kart_scale(0.5f, 0.5f, 0.5f);
m_kart_node[k]->move(kart_pos, kart_rot, kart_scale, false);
core::vector3df podium_pos = m_podium_steps[k]->getInitXYZ();
core::vector3df podium_rot(0, m_kart_rotation[k], 0);
m_podium_steps[k]->move(podium_pos, podium_rot, core::vector3df(1.0f, 1.0f, 1.0f), false);
karts_not_yet_done++; karts_not_yet_done++;
} }
} }
@ -349,38 +272,22 @@ void GrandPrixWin::onUpdate(float dt)
if (m_kart_y[k] < y_target + KARTS_DELTA_Y) if (m_kart_y[k] < y_target + KARTS_DELTA_Y)
{ {
m_kart_y[k] += dt*(PODIUM_HEIGHT[k]); m_kart_y[k] += dt*(PODIUM_HEIGHT[k]);
m_kart_node[k]->setPosition( core::vector3df(m_kart_x[k], m_kart_y[k], m_kart_z[k]) ); core::vector3df kart_pos(m_kart_x[k], m_kart_y[k], m_kart_z[k]);
m_podium_step[k]->setPosition( core::vector3df(m_podium_x[k], core::vector3df kart_rot(0, m_kart_rotation[k], 0);
INITIAL_PODIUM_Y - (INITIAL_Y - m_kart_y[k]) - KARTS_DELTA_Y, core::vector3df kart_scale(0.5f, 0.5f, 0.5f);
m_podium_z[k]) ); m_kart_node[k]->move(kart_pos, kart_rot, kart_scale, false);
core::vector3df podium_pos = m_podium_steps[k]->getInitXYZ();
core::vector3df podium_rot(0, m_kart_rotation[k], 0);
podium_pos.Y = INITIAL_PODIUM_Y - (INITIAL_Y - m_kart_y[k]) - KARTS_DELTA_Y;
m_podium_steps[k]->move(podium_pos, podium_rot, core::vector3df(1.0f, 1.0f, 1.0f), false);
} }
} }
} // end for } // end for
} }
if (m_phase > 1)
{
//m_camera_x = 3.0f;
if (m_camera_z < -2.0f) m_camera_z += dt*0.2f;
if (m_camera_x < m_podium_x[1] - dt*0.1f) m_camera_x += dt*0.1f;
else if (m_camera_x > m_podium_x[1] + dt*0.1f) m_camera_x -= dt*0.1f;
else m_camera_x = m_podium_x[1];
if (m_camera_target_x < m_podium_x[1]) m_camera_target_x += dt*0.1f;
if (m_camera_y > -1.8f) m_camera_y -= dt*0.1f;
m_camera->setTarget( core::vector3df(m_camera_target_x, -2.0f, m_camera_target_z) );
m_camera->setPosition( core::vector3df(m_camera_x, m_camera_y, m_camera_z) );
m_camera->setUpVector( core::vector3df(0.0, 1.0, 0.0) );
m_camera->updateAbsolutePosition();
}
// ---- title // ---- title
static const int w = irr_driver->getFrameSize().Width; static const int w = irr_driver->getFrameSize().Width;
@ -413,8 +320,7 @@ void GrandPrixWin::eventCallback(GUIEngine::Widget* widget,
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges(); PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
PlayerManager::getCurrentPlayer()->clearUnlocked(); PlayerManager::getCurrentPlayer()->clearUnlocked();
FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene::getInstance();
FeatureUnlockedCutScene::getInstance();
assert(unlocked.size() > 0); assert(unlocked.size() > 0);
scene->addTrophy(race_manager->getDifficulty()); scene->addTrophy(race_manager->getDifficulty());
@ -434,47 +340,67 @@ void GrandPrixWin::eventCallback(GUIEngine::Widget* widget,
void GrandPrixWin::setKarts(const std::string idents_arg[3]) void GrandPrixWin::setKarts(const std::string idents_arg[3])
{ {
TrackObjectManager* tobjman = World::getWorld()->getTrack()->getTrackObjectManager();
// reorder in "podium order" (i.e. second player to the left, first player in the middle, last at the right) // reorder in "podium order" (i.e. second player to the left, first player in the middle, last at the right)
std::string idents[3]; std::string idents[3];
idents[0] = idents_arg[1]; idents[0] = idents_arg[1];
idents[1] = idents_arg[0]; idents[1] = idents_arg[0];
idents[2] = idents_arg[2]; idents[2] = idents_arg[2];
for (int n=0; n<3; n++) for (int i = 0; i < 3; i++)
{ {
if (idents[n].size() == 0) continue; const KartProperties* kp = kart_properties_manager->getKart(idents[i]);
if (kp == NULL) continue;
scene::ISceneNode* kart_main_node = NULL; KartModel* kart_model = kp->getKartModelCopy();
m_all_kart_models.push_back(kart_model);
scene::ISceneNode* kart_main_node = kart_model->attachModel(false);
const KartProperties* kp = kart_properties_manager->getKart(idents[n]); m_kart_x[i] = KARTS_X + i*KARTS_DELTA_X;
if (kp != NULL) m_kart_y[i] = INITIAL_Y + KARTS_DELTA_Y;
m_kart_z[i] = -4; // to 1.2
m_kart_rotation[i] = 0.0f;
core::vector3df kart_pos(m_kart_x[i], m_kart_y[i], m_kart_z[i]);
core::vector3df kart_rot(0, 0, 0);
core::vector3df kart_scale(0.5, 0.5, 0.5);
//FIXME: it's not ideal that both the track object and the presentation know the initial coordinates of the object
TrackObjectPresentationSceneNode* presentation = new TrackObjectPresentationSceneNode(
kart_main_node, kart_pos, kart_rot, kart_scale);
TrackObject* tobj = new TrackObject(kart_pos, kart_rot, kart_scale,
"ghost", presentation, false /* isDynamic */, NULL /* physics settings */);
tobjman->insertObject(tobj);
m_kart_node[i] = tobj;
}
TrackObject* currObj;
PtrVector<TrackObject>& objects = tobjman->getObjects();
for_in(currObj, objects)
{
TrackObjectPresentationMesh* meshPresentation = currObj->getPresentation<TrackObjectPresentationMesh>();
if (meshPresentation != NULL)
{ {
KartModel *kart_model = kp->getKartModelCopy(); if (meshPresentation->getModelFile() == "gpwin_podium1.b3d")
m_all_kart_models.push_back(kart_model); {
kart_main_node = kart_model->attachModel(false); m_podium_steps[0] = currObj;
}
m_kart_x[n] = m_podium_x[n]; else if (meshPresentation->getModelFile() == "gpwin_podium2.b3d")
m_kart_y[n] = INITIAL_Y + KARTS_DELTA_Y; {
m_kart_z[n] = -4; m_podium_steps[1] = currObj;
m_kart_rotation[n] = 0.0f; }
else if (meshPresentation->getModelFile() == "gpwin_podium3.b3d")
assert(kart_main_node != NULL); {
kart_main_node->setPosition( core::vector3df(m_kart_x[n], m_podium_steps[2] = currObj;
m_kart_y[n], }
m_kart_z[n]) );
kart_main_node->setScale( core::vector3df(0.4f, 0.4f, 0.4f) );
float susp[4]={0,0,0,0};
kart_model->update(0.0f, 0.0f, 0.0f, susp, 0.0f);
}
else
{
std::cerr << "[GrandPrixWin] WARNING : kart '" << idents[n] << "' not found!\n";
} }
}
m_kart_node[n] = kart_main_node; assert(m_podium_steps[0] != NULL);
} // end for assert(m_podium_steps[1] != NULL);
assert(m_podium_steps[2] != NULL);
assert(m_kart_node[0] != NULL || m_kart_node[1] != NULL || m_kart_node[2] != NULL);
} // setKarts } // setKarts
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------

View File

@ -26,6 +26,7 @@
namespace irr { namespace scene { class ISceneNode; class ICameraSceneNode; class ILightSceneNode; class IMeshSceneNode; } } namespace irr { namespace scene { class ISceneNode; class ICameraSceneNode; class ILightSceneNode; class IMeshSceneNode; } }
namespace GUIEngine { class LabelWidget; } namespace GUIEngine { class LabelWidget; }
class KartProperties; class KartProperties;
class TrackObject;
/** /**
* \brief Screen shown at the end of a Grand Prix * \brief Screen shown at the end of a Grand Prix
@ -37,39 +38,27 @@ class GrandPrixWin : public GUIEngine::Screen, public GUIEngine::ScreenSingleton
GrandPrixWin(); GrandPrixWin();
/** sky angle, 0-360 */
float m_sky_angle;
/** Global evolution of time */ /** Global evolution of time */
double m_global_time; double m_global_time;
irr::scene::IMeshSceneNode* m_village; TrackObject* m_podium_steps[3];
irr::scene::IMeshSceneNode* m_podium_step[3]; TrackObject* m_kart_node[3];
irr::scene::ISceneNode* m_kart_node[3];
//irr::scene::IMeshSceneNode* m_podium_step[3];
//irr::scene::ISceneNode* m_kart_node[3];
/** A copy of the kart model for each kart used. */ /** A copy of the kart model for each kart used. */
std::vector<KartModel*> m_all_kart_models; std::vector<KartModel*> m_all_kart_models;
irr::scene::ISceneNode* m_sky;
irr::scene::ICameraSceneNode* m_camera;
irr::scene::ISceneNode* m_light;
GUIEngine::LabelWidget* m_unlocked_label; GUIEngine::LabelWidget* m_unlocked_label;
int m_phase; int m_phase;
float m_kart_x[3], m_kart_y[3], m_kart_z[3]; float m_kart_x[3], m_kart_y[3], m_kart_z[3];
float m_podium_x[3], m_podium_z[3]; //float m_podium_x[3], m_podium_z[3];
float m_kart_rotation[3]; float m_kart_rotation[3];
float m_camera_x, m_camera_y, m_camera_z;
float m_camera_target_x, m_camera_target_z;
MusicInformation* m_music;
SFXBase* m_finish_sound;
public: public:
/** \brief implement callback from parent class GUIEngine::Screen */ /** \brief implement callback from parent class GUIEngine::Screen */
@ -90,8 +79,6 @@ public:
/** \pre must be called after pushing the screen, but before onUpdate had the chance to be invoked */ /** \pre must be called after pushing the screen, but before onUpdate had the chance to be invoked */
void setKarts(const std::string idents[3]); void setKarts(const std::string idents[3]);
virtual MusicInformation* getMusic() const OVERRIDE { return m_music; }
}; };
#endif #endif

View File

@ -233,17 +233,50 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
if (selection == "options") if (selection == "options")
{ {
// The DEBUG item // The DEBUG item
// GP WIN
/*
StateManager::get()->enterGameState();
race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
race_manager->setNumKarts(0);
race_manager->setNumPlayers(0);
race_manager->setNumLocalPlayers(0);
race_manager->startSingleRace("gpwin", 999, false);
GrandPrixWin* scene = GrandPrixWin::getInstance();
StateManager::get()->pushScreen(scene);
const std::string winners[] = { "elephpant", "nolok", "pidgin" };
scene->setKarts(winners);
*/
// GP Lose
StateManager::get()->enterGameState();
race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
race_manager->setNumKarts(0);
race_manager->setNumPlayers(0);
race_manager->setNumLocalPlayers(0);
race_manager->startSingleRace("gplose", 999, false);
GrandPrixLose* scene = GrandPrixLose::getInstance();
StateManager::get()->pushScreen(scene);
std::vector<std::string> losers;
losers.push_back("nolok");
losers.push_back("elephpant");
//losers.push_back("wilber");
//losers.push_back("tux");
scene->setKarts(losers);
/*
// FEATURE UNLOCKED
FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene* scene =
FeatureUnlockedCutScene::getInstance(); FeatureUnlockedCutScene::getInstance();
scene->addTrophy(RaceManager::DIFFICULTY_EASY); scene->addTrophy(RaceManager::DIFFICULTY_EASY);
StateManager::get()->pushScreen(scene); StateManager::get()->pushScreen(scene);
/*
static int i = 1; static int i = 1;
i++; i++;
if (i % 4 == 0) if (i % 2 == 0)
{ {
// the passed kart will not be modified, that's why I allow myself // the passed kart will not be modified, that's why I allow myself
// to use const_cast // to use const_cast
@ -255,7 +288,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
); );
StateManager::get()->pushScreen(scene); StateManager::get()->pushScreen(scene);
} }
else if (i % 4 == 1) else if (i % 2 == 1)
{ {
std::vector<video::ITexture*> textures; std::vector<video::ITexture*> textures;
textures.push_back(irr_driver->getTexture( textures.push_back(irr_driver->getTexture(
@ -274,23 +307,6 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
scene->addUnlockedPictures(textures, 1.0, 0.75, L"You did it"); scene->addUnlockedPictures(textures, 1.0, 0.75, L"You did it");
StateManager::get()->pushScreen(scene); StateManager::get()->pushScreen(scene);
}
else if (i % 4 == 2)
{
GrandPrixWin* scene = GrandPrixWin::getInstance();
const std::string winners[] = { "elephpant", "nolok", "pidgin" };
StateManager::get()->pushScreen(scene);
scene->setKarts( winners );
}
else
{
GrandPrixLose* scene = GrandPrixLose::getInstance();
StateManager::get()->pushScreen(scene);
std::vector<std::string> losers;
losers.push_back("nolok");
losers.push_back("elephpant");
losers.push_back("wilber");
scene->setKarts( losers );
} }
*/ */
} }

View File

@ -28,6 +28,7 @@
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "graphics/camera.hpp" #include "graphics/camera.hpp"
#include "graphics/CBatchingMesh.hpp" #include "graphics/CBatchingMesh.hpp"
#include "graphics/glwrap.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/lod_node.hpp" #include "graphics/lod_node.hpp"
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
@ -206,6 +207,8 @@ void Track::cleanup()
ItemManager::destroy(); ItemManager::destroy();
ParticleKindManager::get()->cleanUpTrackSpecificGfx(); ParticleKindManager::get()->cleanUpTrackSpecificGfx();
// Clear remainder of transformed textures
resetTextureTable();
for(unsigned int i=0; i<m_animated_textures.size(); i++) for(unsigned int i=0; i<m_animated_textures.size(); i++)
{ {

View File

@ -202,6 +202,7 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node
std::string model_name; std::string model_name;
xml_node.get("model", &model_name ); xml_node.get("model", &model_name );
m_model_file = model_name;
m_is_in_skybox = false; m_is_in_skybox = false;
std::string render_pass; std::string render_pass;
xml_node.get("renderpass", &render_pass); xml_node.get("renderpass", &render_pass);
@ -250,6 +251,22 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node
init(&xml_node, parent, enabled); init(&xml_node, parent, enabled);
} }
TrackObjectPresentationMesh::TrackObjectPresentationMesh(
scene::IAnimatedMesh* model, const core::vector3df& xyz,
const core::vector3df& hpr, const core::vector3df& scale) :
TrackObjectPresentationSceneNode(xyz, hpr, scale)
{
m_is_looped = false;
m_mesh = NULL;
m_node = NULL;
bool animated = (UserConfigParams::m_graphical_effects ||
World::getWorld()->getIdent() == IDENT_CUTSCENE);
m_mesh = model;
init(NULL, NULL, true);
}
TrackObjectPresentationMesh::TrackObjectPresentationMesh( TrackObjectPresentationMesh::TrackObjectPresentationMesh(
const std::string& model_file, const core::vector3df& xyz, const std::string& model_file, const core::vector3df& xyz,
const core::vector3df& hpr, const core::vector3df& scale) : const core::vector3df& hpr, const core::vector3df& scale) :
@ -262,6 +279,8 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(
bool animated = (UserConfigParams::m_graphical_effects || bool animated = (UserConfigParams::m_graphical_effects ||
World::getWorld()->getIdent() == IDENT_CUTSCENE); World::getWorld()->getIdent() == IDENT_CUTSCENE);
m_model_file = model_file;
if (file_manager->fileExists(model_file)) if (file_manager->fileExists(model_file))
{ {
if (animated) if (animated)
@ -374,10 +393,9 @@ void TrackObjectPresentationMesh::reset()
a_node->OnAnimate(0); a_node->OnAnimate(0);
a_node->OnAnimate(0); a_node->OnAnimate(0);
if(m_is_looped) // irrlicht's "setFrameLoop" is a misnomer, it just sets the first and
{ // last frame, even if looping is disabled
a_node->setFrameLoop(m_frame_start, m_frame_end); a_node->setFrameLoop(m_frame_start, m_frame_end);
}
} }
} }

View File

@ -116,6 +116,16 @@ public:
m_node = NULL; m_node = NULL;
} }
TrackObjectPresentationSceneNode(
scene::ISceneNode* node,
const core::vector3df& xyz,
const core::vector3df& hpr,
const core::vector3df& scale) :
TrackObjectPresentation(xyz, hpr, scale)
{
m_node = node;
}
virtual const core::vector3df& getPosition() const OVERRIDE; virtual const core::vector3df& getPosition() const OVERRIDE;
virtual const core::vector3df getAbsolutePosition() const OVERRIDE; virtual const core::vector3df getAbsolutePosition() const OVERRIDE;
virtual const core::vector3df& getRotation() const OVERRIDE; virtual const core::vector3df& getRotation() const OVERRIDE;
@ -193,6 +203,8 @@ private:
/** End frame of the animation to be played. */ /** End frame of the animation to be played. */
unsigned int m_frame_end; unsigned int m_frame_end;
std::string m_model_file;
void init(const XMLNode* xml_node, scene::ISceneNode* parent, bool enabled); void init(const XMLNode* xml_node, scene::ISceneNode* parent, bool enabled);
public: public:
@ -201,10 +213,15 @@ public:
TrackObjectPresentationMesh( TrackObjectPresentationMesh(
const std::string& model_file, const core::vector3df& xyz, const std::string& model_file, const core::vector3df& xyz,
const core::vector3df& hpr, const core::vector3df& scale); const core::vector3df& hpr, const core::vector3df& scale);
TrackObjectPresentationMesh(
scene::IAnimatedMesh* mesh, const core::vector3df& xyz,
const core::vector3df& hpr, const core::vector3df& scale);
virtual ~TrackObjectPresentationMesh(); virtual ~TrackObjectPresentationMesh();
virtual void reset() OVERRIDE; virtual void reset() OVERRIDE;
const std::string& getModelFile() const { return m_model_file; }
}; };
/** /**

View File

@ -37,6 +37,7 @@ Profiler profiler;
#define LINE_HEIGHT 0.030f // height of a line representing a thread #define LINE_HEIGHT 0.030f // height of a line representing a thread
#define MARKERS_NAMES_POS core::rect<s32>(50,100,150,200) #define MARKERS_NAMES_POS core::rect<s32>(50,100,150,200)
#define GPU_MARKERS_NAMES_POS core::rect<s32>(50,165,150,250)
#define TIME_DRAWN_MS 30.0f // the width of the profiler corresponds to TIME_DRAWN_MS milliseconds #define TIME_DRAWN_MS 30.0f // the width of the profiler corresponds to TIME_DRAWN_MS milliseconds
@ -315,6 +316,48 @@ void Profiler::draw()
} }
} }
QueryPerf hovered_gpu_marker = Q_LAST;
long hovered_gpu_marker_elapsed = 0;
if (hovered_markers.size() == 0)
{
int gpu_y = y_offset + nb_thread_infos*line_height + line_height/2;
float total = 0;
for (unsigned i = 0; i < Q_LAST; i++)
{
total += irr_driver->getGPUTimer(i).elapsedTimeus();
}
static video::SColor colors[] = {
video::SColor(255, 255, 0, 0),
video::SColor(255, 0, 255, 0),
video::SColor(255, 0, 0, 255),
video::SColor(255, 255, 255, 0),
video::SColor(255, 255, 0, 255),
video::SColor(255, 0, 255, 255)
};
float curr_val = 0;
for (unsigned i = 0; i < Q_LAST; i++)
{
//Log::info("GPU Perf", "Phase %d : %d us\n", i, irr_driver->getGPUTimer(i).elapsedTimeus());
float elapsed = irr_driver->getGPUTimer(i).elapsedTimeus();
core::rect<s32> pos((s32)(x_offset + (curr_val / total)*profiler_width),
(s32)(y_offset + gpu_y),
(s32)(x_offset + ((curr_val + elapsed) / total)*profiler_width),
(s32)(y_offset + gpu_y + line_height));
curr_val += elapsed;
GL32_draw2DRectangle(colors[i % 6], pos);
if (pos.isPointInside(mouse_pos))
{
hovered_gpu_marker = (QueryPerf)i;
hovered_gpu_marker_elapsed = irr_driver->getGPUTimer(i).elapsedTimeus();
}
}
}
// Draw the end of the frame // Draw the end of the frame
{ {
s32 x_sync = (s32)(x_offset + factor*m_time_between_sync); s32 x_sync = (s32)(x_offset + factor*m_time_between_sync);
@ -343,6 +386,13 @@ void Profiler::draw()
hovered_markers.pop(); hovered_markers.pop();
} }
font->draw(text, MARKERS_NAMES_POS, video::SColor(0xFF, 0xFF, 0x00, 0x00)); font->draw(text, MARKERS_NAMES_POS, video::SColor(0xFF, 0xFF, 0x00, 0x00));
if (hovered_gpu_marker != Q_LAST)
{
std::ostringstream oss;
oss << "GPU marker " << hovered_gpu_marker << " : " << hovered_gpu_marker_elapsed << " us";
font->draw(oss.str().c_str(), GPU_MARKERS_NAMES_POS, video::SColor(0xFF, 0xFF, 0x00, 0x00));
}
} }
if (m_capture_report) if (m_capture_report)
@ -397,6 +447,6 @@ void Profiler::drawBackground()
(int)((1.0-MARGIN_X) * screen_size.Width), (int)((1.0-MARGIN_X) * screen_size.Width),
(int)((MARGIN_Y + 1.75f*LINE_HEIGHT) * screen_size.Height)); (int)((MARGIN_Y + 1.75f*LINE_HEIGHT) * screen_size.Height));
video::SColor color(0xFF, 0xFF, 0xFF, 0xFF); video::SColor color(0x88, 0xFF, 0xFF, 0xFF);
GL32_draw2DRectangle(color, background_rect); GL32_draw2DRectangle(color, background_rect);
} }

View File

@ -164,11 +164,15 @@ public:
bool getCaptureReport() const { return m_capture_report; } bool getCaptureReport() const { return m_capture_report; }
void setCaptureReport(bool captureReport); void setCaptureReport(bool captureReport);
bool isFrozen() const { return m_freeze_state == FROZEN; }
protected: protected:
// TODO: detect on which thread this is called to support multithreading // TODO: detect on which thread this is called to support multithreading
ThreadInfo& getThreadInfo() { return m_thread_infos[0]; } ThreadInfo& getThreadInfo() { return m_thread_infos[0]; }
void drawBackground(); void drawBackground();
}; };
#endif // PROFILER_HPP #endif // PROFILER_HPP