Merge branch 'master' of github.com:supertuxkart/stk-code
This commit is contained in:
commit
4f266639aa
@ -1,11 +1,13 @@
|
||||
#version 330 compatibility
|
||||
#version 330
|
||||
uniform sampler2D tex;
|
||||
uniform vec3 col;
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 res = texture(tex, gl_TexCoord[0].xy);
|
||||
vec4 res = texture(tex, uv);
|
||||
|
||||
// Keep the sun fully bright, but fade the sky
|
||||
float mul = distance(res.xyz, col);
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 compatibility
|
||||
#version 330
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 sunpos;
|
||||
|
||||
@ -6,14 +6,15 @@ uniform vec2 sunpos;
|
||||
|
||||
const float decaystep = 0.88;
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texc = gl_TexCoord[0].xy;
|
||||
vec2 texc = uv;
|
||||
vec2 tosun = sunpos - texc;
|
||||
|
||||
if (dot(tosun, tosun) > 0.49) discard;
|
||||
// if (dot(tosun, tosun) > 0.49) discard;
|
||||
|
||||
vec2 dist = tosun * 1.0/(float(SAMPLES) * 1.12);
|
||||
|
||||
|
@ -17,11 +17,11 @@
|
||||
|
||||
|
||||
// motion_blur.frag
|
||||
#version 330
|
||||
|
||||
// The actual boost amount (which linearly scales the blur to be shown).
|
||||
// should be in the range [0.0, 1.0], though a larger value might make
|
||||
// the blurring too string. Atm we are using [0, 0.5].
|
||||
#version 330 compatibility
|
||||
uniform float boost_amount;
|
||||
|
||||
// The color buffer to use.
|
||||
@ -41,6 +41,7 @@ uniform float mask_radius;
|
||||
// Maximum height of texture used
|
||||
uniform float max_tex_height;
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
// Number of samples used for blurring
|
||||
@ -48,7 +49,7 @@ out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texcoords = gl_TexCoord[0].st;
|
||||
vec2 texcoords = uv;
|
||||
|
||||
// Sample the color buffer
|
||||
vec3 color = texture(color_buffer, texcoords).rgb;
|
||||
|
@ -64,6 +64,7 @@ src/graphics/stars.cpp
|
||||
src/graphics/stkanimatedmesh.cpp
|
||||
src/graphics/stkbillboard.cpp
|
||||
src/graphics/stkmesh.cpp
|
||||
src/graphics/stkmeshscenenode.cpp
|
||||
src/graphics/sun.cpp
|
||||
src/graphics/water.cpp
|
||||
src/graphics/wind.cpp
|
||||
@ -395,6 +396,7 @@ src/graphics/stars.hpp
|
||||
src/graphics/stkanimatedmesh.hpp
|
||||
src/graphics/stkbillboard.hpp
|
||||
src/graphics/stkmesh.hpp
|
||||
src/graphics/stkmeshscenenode.hpp
|
||||
src/graphics/sun.hpp
|
||||
src/graphics/water.hpp
|
||||
src/graphics/wind.hpp
|
||||
|
@ -229,12 +229,22 @@ public:
|
||||
m_maxheight[who] = height;
|
||||
}
|
||||
|
||||
float getMaxHeight(u32 who) const
|
||||
{
|
||||
return m_maxheight[who];
|
||||
}
|
||||
|
||||
void setBoostTime(u32 who, float time)
|
||||
{
|
||||
assert(who < MAX_PLAYER_COUNT);
|
||||
m_boost_time[who] = time;
|
||||
}
|
||||
|
||||
float getBoostTime(u32 who) const
|
||||
{
|
||||
return m_boost_time[who];
|
||||
}
|
||||
|
||||
void setCenter(u32 who, float X, float Y)
|
||||
{
|
||||
assert(who < MAX_PLAYER_COUNT);
|
||||
@ -242,6 +252,11 @@ public:
|
||||
m_center[who].Y = Y;
|
||||
}
|
||||
|
||||
core::vector2df getCenter(u32 who) const
|
||||
{
|
||||
return core::vector2df(m_center[who].X, m_center[who].Y);
|
||||
}
|
||||
|
||||
void setDirection(u32 who, float X, float Y)
|
||||
{
|
||||
assert(who < MAX_PLAYER_COUNT);
|
||||
@ -249,6 +264,11 @@ public:
|
||||
m_direction[who].Y = Y;
|
||||
}
|
||||
|
||||
core::vector2df getDirection(u32 who) const
|
||||
{
|
||||
return core::vector2df(m_direction[who].X, m_direction[who].Y);
|
||||
}
|
||||
|
||||
void setCurrentCamera(u32 who)
|
||||
{
|
||||
m_current_camera = who;
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "graphics/shadow_importance.hpp"
|
||||
#include "graphics/stkanimatedmesh.hpp"
|
||||
#include "graphics/stkbillboard.hpp"
|
||||
#include "graphics/stkmesh.hpp"
|
||||
#include "graphics/stkmeshscenenode.hpp"
|
||||
#include "graphics/sun.hpp"
|
||||
#include "graphics/rtts.hpp"
|
||||
#include "graphics/water.hpp"
|
||||
@ -459,9 +459,10 @@ void IrrDriver::initDevice()
|
||||
|
||||
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
|
||||
gl_driver->extGlGenQueries(1, &m_lensflare_query);
|
||||
m_query_issued = false;
|
||||
|
||||
scene::IMesh * const sphere = m_scene_manager->getGeometryCreator()->createSphereMesh(1, 16, 16);
|
||||
m_sun_interposer = m_scene_manager->addMeshSceneNode(sphere);
|
||||
m_sun_interposer = new STKMeshSceneNode(sphere, m_scene_manager->getRootSceneNode(), NULL, -1);
|
||||
m_sun_interposer->grab();
|
||||
m_sun_interposer->setParent(NULL);
|
||||
m_sun_interposer->setScale(core::vector3df(20));
|
||||
@ -469,7 +470,7 @@ void IrrDriver::initDevice()
|
||||
m_sun_interposer->getMaterial(0).Lighting = false;
|
||||
m_sun_interposer->getMaterial(0).ColorMask = video::ECP_NONE;
|
||||
m_sun_interposer->getMaterial(0).ZWriteEnable = false;
|
||||
m_sun_interposer->getMaterial(0).MaterialType = m_shaders->getShader(ES_PASSFAR);
|
||||
m_sun_interposer->getMaterial(0).MaterialType = m_shaders->getShader(ES_OBJECTPASS);
|
||||
|
||||
sphere->drop();
|
||||
|
||||
@ -937,7 +938,7 @@ scene::IMeshSceneNode *IrrDriver::addMesh(scene::IMesh *mesh,
|
||||
if (!parent)
|
||||
parent = m_scene_manager->getRootSceneNode();
|
||||
|
||||
scene::IMeshSceneNode* node = new STKMesh(mesh, parent, m_scene_manager, -1);
|
||||
scene::IMeshSceneNode* node = new STKMeshSceneNode(mesh, parent, m_scene_manager, -1);
|
||||
node->drop();
|
||||
|
||||
return node;
|
||||
|
@ -171,7 +171,8 @@ private:
|
||||
unsigned object_count[PASS_COUNT];
|
||||
u32 m_renderpass;
|
||||
u32 m_lensflare_query;
|
||||
scene::IMeshSceneNode *m_sun_interposer;
|
||||
bool m_query_issued;
|
||||
class STKMeshSceneNode *m_sun_interposer;
|
||||
scene::CLensFlareSceneNode *m_lensflare;
|
||||
scene::ICameraSceneNode *m_suncam;
|
||||
|
||||
@ -212,7 +213,6 @@ private:
|
||||
std::vector<GlowData>& glows,
|
||||
const core::aabbox3df& cambox,
|
||||
int cam);
|
||||
void renderSkybox();
|
||||
void renderLights(const core::aabbox3df& cambox,
|
||||
scene::ICameraSceneNode * const camnode,
|
||||
video::SOverrideMaterial &overridemat,
|
||||
@ -225,6 +225,7 @@ public:
|
||||
~IrrDriver();
|
||||
void initDevice();
|
||||
void reset();
|
||||
void renderSkybox();
|
||||
void setPhase(STKRenderingPass);
|
||||
STKRenderingPass getPhase() const;
|
||||
const std::vector<core::matrix4> &getShadowViewProj() const
|
||||
@ -495,7 +496,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
void clearLights();
|
||||
// ------------------------------------------------------------------------
|
||||
scene::IMeshSceneNode *getSunInterposer() { return m_sun_interposer; }
|
||||
class STKMeshSceneNode *getSunInterposer() { return m_sun_interposer; }
|
||||
// ------------------------------------------------------------------------
|
||||
void setViewMatrix(core::matrix4 matrix) { m_ViewMatrix = matrix; matrix.getInverse(m_InvViewMatrix); }
|
||||
const core::matrix4 &getViewMatrix() const { return m_ViewMatrix; }
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/mlaa_areamap.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/stkmeshscenenode.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/kart_model.hpp"
|
||||
@ -578,6 +579,75 @@ void PostProcessing::renderFog(const core::matrix4 &ipvmat)
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void PostProcessing::renderMotionBlur(unsigned cam, ITexture *in, ITexture *out)
|
||||
{
|
||||
|
||||
MotionBlurProvider * const cb = (MotionBlurProvider *)irr_driver->
|
||||
getCallback(ES_MOTIONBLUR);
|
||||
|
||||
scene::ICameraSceneNode * const camnode =
|
||||
Camera::getCamera(cam)->getCameraSceneNode();
|
||||
// Calculate the kart's Y position on screen
|
||||
const core::vector3df pos =
|
||||
Camera::getCamera(cam)->getKart()->getNode()->getPosition();
|
||||
float ndc[4];
|
||||
core::matrix4 trans = camnode->getProjectionMatrix();
|
||||
trans *= camnode->getViewMatrix();
|
||||
|
||||
trans.transformVect(ndc, pos);
|
||||
const float karty = (ndc[1] / ndc[3]) * 0.5f + 0.5f;
|
||||
setMotionBlurCenterY(cam, karty);
|
||||
|
||||
irr_driver->getVideoDriver()->setRenderTarget(out, true, false);
|
||||
|
||||
glUseProgram(FullScreenShader::MotionBlurShader::Program);
|
||||
glBindVertexArray(FullScreenShader::MotionBlurShader::vao);
|
||||
|
||||
setTexture(0, getTextureGLuint(in), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::MotionBlurShader::setUniforms(cb->getBoostTime(cam), cb->getCenter(cam), cb->getDirection(cam), 0.15, cb->getMaxHeight(cam) * 0.7, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
static void renderGodFade(GLuint tex, const SColor &col)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glUseProgram(FullScreenShader::GodFadeShader::Program);
|
||||
glBindVertexArray(FullScreenShader::GodFadeShader::vao);
|
||||
setTexture(0, tex, GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::GodFadeShader::setUniforms(col, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
static void renderGodRay(GLuint tex, const core::vector2df &sunpos)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glUseProgram(FullScreenShader::GodRayShader::Program);
|
||||
glBindVertexArray(FullScreenShader::GodRayShader::vao);
|
||||
setTexture(0, tex, GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::GodRayShader::setUniforms(sunpos, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Render the post-processed scene */
|
||||
void PostProcessing::render()
|
||||
@ -653,9 +723,6 @@ void PostProcessing::render()
|
||||
// Additively blend on top of tmp1
|
||||
drv->setRenderTarget(out, false, false);
|
||||
renderBloomBlend(irr_driver->getRTT(RTT_EIGHTH1));
|
||||
m_material.MaterialType = irr_driver->getShader(ES_RAIN);
|
||||
drv->setMaterial(m_material);
|
||||
static_cast<irr::video::COpenGLDriver*>(drv)->setRenderStates3DMode();
|
||||
} // end if bloom
|
||||
|
||||
in = irr_driver->getRTT(RTT_TMP1);
|
||||
@ -664,33 +731,33 @@ void PostProcessing::render()
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00);
|
||||
if (World::getWorld()->getTrack()->hasGodRays() && m_sunpixels > 30) // god rays
|
||||
if (m_sunpixels > 30)//World::getWorld()->getTrack()->hasGodRays() && ) // god rays
|
||||
{
|
||||
// Grab the sky
|
||||
drv->setRenderTarget(out, true, false);
|
||||
irr_driver->getSceneManager()->drawAll(ESNRP_SKY_BOX);
|
||||
// irr_driver->getSceneManager()->drawAll(ESNRP_SKY_BOX);
|
||||
irr_driver->renderSkybox();
|
||||
|
||||
// Set the sun's color
|
||||
ColorizeProvider * const colcb = (ColorizeProvider *) irr_driver->getCallback(ES_COLORIZE);
|
||||
const SColor col = World::getWorld()->getTrack()->getSunColor();
|
||||
colcb->setColor(col.getRed() / 255.0f, col.getGreen() / 255.0f, col.getBlue() / 255.0f);
|
||||
ColorizeProvider * const colcb = (ColorizeProvider *) irr_driver->getCallback(ES_COLORIZE);
|
||||
colcb->setColor(col.getRed() / 255.0f, col.getGreen() / 255.0f, col.getBlue() / 255.0f);
|
||||
|
||||
// The sun interposer
|
||||
IMeshSceneNode * const sun = irr_driver->getSunInterposer();
|
||||
sun->getMaterial(0).ColorMask = ECP_ALL;
|
||||
STKMeshSceneNode *sun = irr_driver->getSunInterposer();
|
||||
/* sun->getMaterial(0).ColorMask = ECP_ALL;
|
||||
irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID);*/
|
||||
irr_driver->getSceneManager()->drawAll(ESNRP_CAMERA);
|
||||
irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID);
|
||||
|
||||
irr_driver->setPhase(GLOW_PASS);
|
||||
sun->render();
|
||||
|
||||
sun->getMaterial(0).ColorMask = ECP_NONE;
|
||||
//sun->getMaterial(0).ColorMask = ECP_NONE;
|
||||
|
||||
// Fade to quarter
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GODFADE);
|
||||
m_material.setTexture(0, out);
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), false, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), false, false);
|
||||
renderGodFade(getTextureGLuint(out), col);
|
||||
|
||||
|
||||
// Blur
|
||||
renderGaussian3Blur(irr_driver->getRTT(RTT_QUARTER1),
|
||||
@ -698,6 +765,8 @@ void PostProcessing::render()
|
||||
4.f / UserConfigParams::m_width,
|
||||
4.f / UserConfigParams::m_height);
|
||||
|
||||
|
||||
|
||||
// Calculate the sun's position in texcoords
|
||||
const core::vector3df pos = sun->getPosition();
|
||||
float ndc[4];
|
||||
@ -712,63 +781,33 @@ void PostProcessing::render()
|
||||
const float sunx = ((ndc[0] / ndc[3]) * 0.5f + 0.5f) * texw;
|
||||
const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh;
|
||||
|
||||
((GodRayProvider *) irr_driver->getCallback(ES_GODRAY))->
|
||||
setSunPosition(sunx, suny);
|
||||
// ((GodRayProvider *) irr_driver->getCallback(ES_GODRAY))->
|
||||
// setSunPosition(sunx, suny);
|
||||
|
||||
// Rays please
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GODRAY);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
renderGodRay(getTextureGLuint(irr_driver->getRTT(RTT_QUARTER1)), core::vector2df(sunx, suny));
|
||||
|
||||
// Blur
|
||||
{
|
||||
gacb->setResolution(UserConfigParams::m_width / 4,
|
||||
UserConfigParams::m_height / 4);
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), true, false);
|
||||
renderGaussian3Blur(irr_driver->getRTT(RTT_QUARTER2),
|
||||
irr_driver->getRTT(RTT_QUARTER1),
|
||||
4.f / UserConfigParams::m_width,
|
||||
4.f / UserConfigParams::m_height);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
// Blend
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), false, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
}
|
||||
|
||||
// Overlay
|
||||
m_material.MaterialType = EMT_TRANSPARENT_ADD_COLOR;
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2));
|
||||
drv->setRenderTarget(in, false, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
renderPassThrough(irr_driver->getRTT(RTT_QUARTER2));
|
||||
}
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
if (UserConfigParams::m_motionblur && m_any_boost) // motion blur
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Motion blur", 0xFF, 0x00, 0x00);
|
||||
// Calculate the kart's Y position on screen
|
||||
const core::vector3df pos =
|
||||
Camera::getCamera(cam)->getKart()->getNode()->getPosition();
|
||||
float ndc[4];
|
||||
core::matrix4 trans = camnode->getProjectionMatrix();
|
||||
trans *= camnode->getViewMatrix();
|
||||
|
||||
trans.transformVect(ndc, pos);
|
||||
const float karty = (ndc[1] / ndc[3]) * 0.5f + 0.5f;
|
||||
setMotionBlurCenterY(cam, karty);
|
||||
|
||||
|
||||
m_material.MaterialType = irr_driver->getShader(ES_MOTIONBLUR);
|
||||
m_material.setTexture(0, in);
|
||||
drv->setRenderTarget(out, true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
renderMotionBlur(cam, in, out);
|
||||
ITexture *tmp = in;
|
||||
in = out;
|
||||
out = tmp;
|
||||
@ -787,6 +826,10 @@ void PostProcessing::render()
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
m_material.MaterialType = irr_driver->getShader(ES_RAIN);
|
||||
drv->setMaterial(m_material);
|
||||
static_cast<irr::video::COpenGLDriver*>(drv)->setRenderStates3DMode();
|
||||
|
||||
if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter.
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00);
|
||||
@ -852,7 +895,7 @@ void PostProcessing::render()
|
||||
if (irr_driver->getNormals())
|
||||
renderPassThrough(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH));
|
||||
else if (irr_driver->getSSAOViz())
|
||||
renderPassThrough(irr_driver->getRTT(RTT_SSAO));
|
||||
renderPassThrough(irr_driver->getRTT(RTT_TMP3));
|
||||
else
|
||||
renderColorLevel(in);
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ public:
|
||||
void renderPassThrough(video::ITexture *tex);
|
||||
void renderPassThrough(unsigned tex);
|
||||
|
||||
void renderMotionBlur(unsigned cam, video::ITexture *in, video::ITexture *out);
|
||||
void renderGlow(video::ITexture *tex);
|
||||
|
||||
/** Render the post-processed scene */
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "graphics/screenquad.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/shadow_importance.hpp"
|
||||
#include "graphics/stkmeshscenenode.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "items/item.hpp"
|
||||
@ -269,20 +270,24 @@ void IrrDriver::renderGLSL(float dt)
|
||||
// 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 (hasflare || hasgodrays)
|
||||
if (true)//hasflare || hasgodrays)
|
||||
{
|
||||
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
|
||||
|
||||
GLuint res;
|
||||
gl_driver->extGlGetQueryObjectuiv(m_lensflare_query, GL_QUERY_RESULT, &res);
|
||||
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);
|
||||
|
||||
|
@ -238,6 +238,9 @@ void Shaders::loadShaders()
|
||||
FullScreenShader::SSAOShader::init();
|
||||
FullScreenShader::SunLightShader::init();
|
||||
FullScreenShader::ShadowedSunLightShader::init();
|
||||
FullScreenShader::MotionBlurShader::init();
|
||||
FullScreenShader::GodFadeShader::init();
|
||||
FullScreenShader::GodRayShader::init();
|
||||
MeshShader::ColorizeShader::init();
|
||||
MeshShader::NormalMapShader::init();
|
||||
MeshShader::ObjectPass1Shader::init();
|
||||
@ -1692,6 +1695,75 @@ namespace FullScreenShader
|
||||
glUniformMatrix4fv(uniform_ipvmat, 1, GL_FALSE, ipvmat.pointer());
|
||||
glUniform1i(uniform_tex, TU_ntex);
|
||||
}
|
||||
|
||||
GLuint MotionBlurShader::Program;
|
||||
GLuint MotionBlurShader::uniform_boost_amount;
|
||||
GLuint MotionBlurShader::uniform_center;
|
||||
GLuint MotionBlurShader::uniform_color_buffer;
|
||||
GLuint MotionBlurShader::uniform_direction;
|
||||
GLuint MotionBlurShader::uniform_mask_radius;
|
||||
GLuint MotionBlurShader::uniform_max_tex_height;
|
||||
GLuint MotionBlurShader::vao;
|
||||
|
||||
void MotionBlurShader::init()
|
||||
{
|
||||
Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/motion_blur.frag").c_str());
|
||||
uniform_boost_amount = glGetUniformLocation(Program, "boost_amount");
|
||||
uniform_center = glGetUniformLocation(Program, "center");
|
||||
uniform_color_buffer = glGetUniformLocation(Program, "color_buffer");
|
||||
uniform_direction = glGetUniformLocation(Program, "direction");
|
||||
uniform_mask_radius = glGetUniformLocation(Program, "mask_radius");
|
||||
uniform_max_tex_height = glGetUniformLocation(Program, "max_tex_height");
|
||||
vao = createVAO(Program);
|
||||
}
|
||||
|
||||
void MotionBlurShader::setUniforms(float boost_amount, const core::vector2df ¢er, const core::vector2df &direction, float mask_radius, float max_tex_height, unsigned TU_cb)
|
||||
{
|
||||
glUniform1f(uniform_boost_amount, boost_amount);
|
||||
glUniform2f(uniform_center, center.X, center.Y);
|
||||
glUniform2f(uniform_direction, direction.X, direction.Y);
|
||||
glUniform1f(uniform_mask_radius, mask_radius);
|
||||
glUniform1f(uniform_max_tex_height, max_tex_height);
|
||||
glUniform1i(uniform_color_buffer, TU_cb);
|
||||
}
|
||||
|
||||
GLuint GodFadeShader::Program;
|
||||
GLuint GodFadeShader::uniform_tex;
|
||||
GLuint GodFadeShader::uniform_col;
|
||||
GLuint GodFadeShader::vao;
|
||||
|
||||
void GodFadeShader::init()
|
||||
{
|
||||
Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/godfade.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
uniform_col = glGetUniformLocation(Program, "col");
|
||||
vao = createVAO(Program);
|
||||
}
|
||||
|
||||
void GodFadeShader::setUniforms(const SColor &col, unsigned TU_tex)
|
||||
{
|
||||
glUniform3f(uniform_col, col.getRed() / 255., col.getGreen() / 255., col.getBlue() / 255.);
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
}
|
||||
|
||||
GLuint GodRayShader::Program;
|
||||
GLuint GodRayShader::uniform_tex;
|
||||
GLuint GodRayShader::uniform_sunpos;
|
||||
GLuint GodRayShader::vao;
|
||||
|
||||
void GodRayShader::init()
|
||||
{
|
||||
Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/godray.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
uniform_sunpos = glGetUniformLocation(Program, "sunpos");
|
||||
vao = createVAO(Program);
|
||||
}
|
||||
|
||||
void GodRayShader::setUniforms(const core::vector2df &sunpos, unsigned TU_tex)
|
||||
{
|
||||
glUniform2f(uniform_sunpos, sunpos.X, sunpos.Y);
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
}
|
||||
}
|
||||
|
||||
namespace UIShader
|
||||
|
@ -523,6 +523,39 @@ public:
|
||||
static void setUniforms(const core::matrix4 &ipvmat, float fogmax, float startH, float endH, float start, float end, const core::vector3df &col, unsigned TU_ntex);
|
||||
};
|
||||
|
||||
class MotionBlurShader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_boost_amount, uniform_color_buffer, uniform_center, uniform_direction, uniform_mask_radius, uniform_max_tex_height;
|
||||
static GLuint vao;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(float boost_amount, const core::vector2df ¢er, const core::vector2df &direction, float mask_radius, float max_tex_height, unsigned TU_cb);
|
||||
};
|
||||
|
||||
class GodFadeShader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_tex, uniform_col;
|
||||
static GLuint vao;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const video::SColor &col, unsigned TU_tex);
|
||||
};
|
||||
|
||||
class GodRayShader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_tex, uniform_sunpos;
|
||||
static GLuint vao;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::vector2df &sunpos, unsigned TU_tex);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace UIShader
|
||||
|
@ -76,24 +76,6 @@ void STKAnimatedMesh::drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
isObjectPass(video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
if (type == irr_driver->getShader(ES_OBJECTPASS))
|
||||
return true;
|
||||
if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
return true;
|
||||
if (type == irr_driver->getShader(ES_OBJECTPASS_RIMLIT))
|
||||
return true;
|
||||
if (type == irr_driver->getShader(ES_OBJECT_UNLIT))
|
||||
return true;
|
||||
if (type == video::EMT_ONETEXTURE_BLEND)
|
||||
return true;
|
||||
if (type == video::EMT_TRANSPARENT_ADD_COLOR)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void STKAnimatedMesh::drawShadow(const GLMesh &mesh)
|
||||
{
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
@ -156,7 +138,7 @@ void STKAnimatedMesh::render()
|
||||
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
|
||||
else if (Mesh->getMeshType() == scene::EAMT_SKINNED)
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((scene::SSkinMeshBuffer*)mb)->Transformation);
|
||||
if (isObjectPass(material.MaterialType))
|
||||
if (isObject(material.MaterialType))
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
initvaostate(GLmeshes[i], material.MaterialType, false);
|
||||
|
@ -144,56 +144,6 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
|
||||
return result;
|
||||
}
|
||||
|
||||
STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position,
|
||||
const irr::core::vector3df& rotation,
|
||||
const irr::core::vector3df& scale) :
|
||||
CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
|
||||
{
|
||||
createGLMeshes();
|
||||
}
|
||||
|
||||
void STKMesh::createGLMeshes()
|
||||
{
|
||||
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
GLmeshes.push_back(allocateMeshBuffer(mb));
|
||||
}
|
||||
}
|
||||
|
||||
void STKMesh::cleanGLMeshes()
|
||||
{
|
||||
for (u32 i = 0; i < GLmeshes.size(); ++i)
|
||||
{
|
||||
GLMesh mesh = GLmeshes[i];
|
||||
if (!mesh.vertex_buffer)
|
||||
continue;
|
||||
if (mesh.vao_first_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_first_pass));
|
||||
if (mesh.vao_second_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_second_pass));
|
||||
if (mesh.vao_glow_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_glow_pass));
|
||||
if (mesh.vao_displace_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_displace_pass));
|
||||
glDeleteBuffers(1, &(mesh.vertex_buffer));
|
||||
glDeleteBuffers(1, &(mesh.index_buffer));
|
||||
}
|
||||
GLmeshes.clear();
|
||||
}
|
||||
|
||||
void STKMesh::setMesh(irr::scene::IMesh* mesh)
|
||||
{
|
||||
CMeshSceneNode::setMesh(mesh);
|
||||
cleanGLMeshes();
|
||||
createGLMeshes();
|
||||
}
|
||||
|
||||
STKMesh::~STKMesh()
|
||||
{
|
||||
cleanGLMeshes();
|
||||
}
|
||||
|
||||
void computeMVP(core::matrix4 &ModelViewProjectionMatrix)
|
||||
{
|
||||
@ -241,22 +191,6 @@ void drawObjectRefPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProje
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
static
|
||||
core::vector3df getWind()
|
||||
{
|
||||
const core::vector3df pos = irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD).getTranslation();
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
GrassShaderProvider *gsp = (GrassShaderProvider *)irr_driver->getCallback(ES_GRASS);
|
||||
float m_speed = gsp->getSpeed(), m_amplitude = gsp->getAmplitude();
|
||||
|
||||
float strength = (pos.X + pos.Y + pos.Z) * 1.2f + time * m_speed;
|
||||
strength = noise2d(strength / 10.0f) * m_amplitude * 5;
|
||||
// * 5 is to work with the existing amplitude values.
|
||||
|
||||
// Pre-multiply on the cpu
|
||||
return irr_driver->getWind() * strength;
|
||||
}
|
||||
|
||||
void drawGrassPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, core::vector3df windDir)
|
||||
{
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
@ -707,142 +641,7 @@ void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatr
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
}
|
||||
|
||||
void STKMesh::drawGlow(const GLMesh &mesh)
|
||||
{
|
||||
ColorizeProvider * const cb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE);
|
||||
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
glUseProgram(MeshShader::ColorizeShader::Program);
|
||||
MeshShader::ColorizeShader::setUniforms(ModelViewProjectionMatrix, cb->getRed(), cb->getGreen(), cb->getBlue());
|
||||
|
||||
glBindVertexArray(mesh.vao_glow_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
}
|
||||
|
||||
void STKMesh::drawDisplace(const GLMesh &mesh)
|
||||
{
|
||||
DisplaceProvider * const cb = (DisplaceProvider *)irr_driver->getCallback(ES_DISPLACE);
|
||||
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
core::matrix4 ModelViewMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
|
||||
ModelViewMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
||||
setTexture(0, getTextureGLuint(irr_driver->getTexture(FileManager::TEXTURE, "displace.png")), GL_LINEAR, GL_LINEAR, true);
|
||||
glUseProgram(MeshShader::DisplaceShader::Program);
|
||||
MeshShader::DisplaceShader::setUniforms(ModelViewProjectionMatrix, ModelViewMatrix, cb->getDirX(), cb->getDirY(), cb->getDir2X(), cb->getDir2Y(), 0);
|
||||
|
||||
glBindVertexArray(mesh.vao_displace_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
}
|
||||
|
||||
void STKMesh::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
assert(irr_driver->getPhase() == TRANSPARENT_PASS);
|
||||
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
|
||||
if (type == irr_driver->getShader(ES_BUBBLES))
|
||||
drawBubble(mesh, ModelViewProjectionMatrix);
|
||||
else if (World::getWorld()->getTrack()->isFogEnabled())
|
||||
drawTransparentFogObject(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
else
|
||||
drawTransparentObject(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
return;
|
||||
}
|
||||
|
||||
void STKMesh::drawShadow(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
|
||||
std::vector<core::matrix4> ShadowMVP(irr_driver->getShadowViewProj());
|
||||
for (unsigned i = 0; i < ShadowMVP.size(); i++)
|
||||
ShadowMVP[i] *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
||||
|
||||
if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
{
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
glUseProgram(MeshShader::RefShadowShader::Program);
|
||||
MeshShader::RefShadowShader::setUniforms(ShadowMVP, 0);
|
||||
}
|
||||
/* else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
|
||||
{
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
glUseProgram(MeshShader::GrassShadowShader::Program);
|
||||
MeshShader::GrassShadowShader::setUniforms(ShadowMVP, windDir, 0);
|
||||
}*/
|
||||
else
|
||||
{
|
||||
glUseProgram(MeshShader::ShadowShader::Program);
|
||||
MeshShader::ShadowShader::setUniforms(ShadowMVP);
|
||||
}
|
||||
glBindVertexArray(mesh.vao_shadow_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
}
|
||||
|
||||
void STKMesh::drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
switch (irr_driver->getPhase())
|
||||
{
|
||||
case SOLID_NORMAL_AND_DEPTH_PASS:
|
||||
{
|
||||
windDir = getWind();
|
||||
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
computeTIMV(TransposeInverseModelView);
|
||||
|
||||
if (type == irr_driver->getShader(ES_NORMAL_MAP))
|
||||
drawNormalPass(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
drawObjectRefPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
|
||||
drawGrassPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, windDir);
|
||||
else
|
||||
drawObjectPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
break;
|
||||
}
|
||||
case SOLID_LIT_PASS:
|
||||
{
|
||||
if (type == irr_driver->getShader(ES_SPHERE_MAP))
|
||||
drawSphereMap(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
else if (type == irr_driver->getShader(ES_SPLATTING))
|
||||
drawSplatting(mesh, ModelViewProjectionMatrix);
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
drawObjectRefPass2(mesh, ModelViewProjectionMatrix);
|
||||
else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
|
||||
drawGrassPass2(mesh, ModelViewProjectionMatrix, windDir);
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_RIMLIT))
|
||||
drawObjectRimLimit(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
else if (type == irr_driver->getShader(ES_OBJECT_UNLIT))
|
||||
drawObjectUnlit(mesh, ModelViewProjectionMatrix);
|
||||
else if (mesh.textures[1] && type != irr_driver->getShader(ES_NORMAL_MAP))
|
||||
drawDetailledObjectPass2(mesh, ModelViewProjectionMatrix);
|
||||
else if (!mesh.textures[0])
|
||||
drawUntexturedObject(mesh, ModelViewProjectionMatrix);
|
||||
else if (!TextureMatrix.isIdentity())
|
||||
drawMovingTexture(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
else
|
||||
drawObjectPass2(mesh, ModelViewProjectionMatrix);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
assert(0 && "wrong pass");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool isObject(video::E_MATERIAL_TYPE type)
|
||||
bool isObject(video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
if (type == irr_driver->getShader(ES_OBJECTPASS))
|
||||
return true;
|
||||
@ -1003,69 +802,3 @@ void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type, bool MovingTexture)
|
||||
}
|
||||
}
|
||||
|
||||
void STKMesh::render()
|
||||
{
|
||||
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||
|
||||
if (!Mesh || !driver)
|
||||
return;
|
||||
|
||||
bool isTransparentPass =
|
||||
SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
|
||||
|
||||
++PassCount;
|
||||
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
Box = Mesh->getBoundingBox();
|
||||
|
||||
for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (mb)
|
||||
{
|
||||
TextureMatrix = getMaterial(i).getTextureMatrix(0);
|
||||
const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
|
||||
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType);
|
||||
bool transparent = (rnd && rnd->isTransparent());
|
||||
|
||||
if (isTransparentPass != transparent)
|
||||
continue;
|
||||
if (irr_driver->getPhase() == DISPLACEMENT_PASS)
|
||||
{
|
||||
initvaostate(GLmeshes[i], material.MaterialType, false);
|
||||
drawDisplace(GLmeshes[i]);
|
||||
continue;
|
||||
}
|
||||
if (!isObject(material.MaterialType))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::warn("material", "Unhandled (static) material type : %d", material.MaterialType);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
// only render transparent buffer if this is the transparent render pass
|
||||
// and solid only in solid pass
|
||||
if (irr_driver->getPhase() == GLOW_PASS)
|
||||
{
|
||||
initvaostate(GLmeshes[i], material.MaterialType, TextureMatrix.isIdentity());
|
||||
drawGlow(GLmeshes[i]);
|
||||
}
|
||||
else if (irr_driver->getPhase() == SHADOW_PASS)
|
||||
{
|
||||
initvaostate(GLmeshes[i], material.MaterialType, TextureMatrix.isIdentity());
|
||||
drawShadow(GLmeshes[i], material.MaterialType);
|
||||
}
|
||||
else
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
initvaostate(GLmeshes[i], material.MaterialType, TextureMatrix.isIdentity());
|
||||
if (transparent)
|
||||
drawTransparent(GLmeshes[i], material.MaterialType);
|
||||
else
|
||||
drawSolid(GLmeshes[i], material.MaterialType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb);
|
||||
void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type, bool moving_texture);
|
||||
void computeMVP(core::matrix4 &ModelViewProjectionMatrix);
|
||||
void computeTIMV(core::matrix4 &TransposeInverseModelView);
|
||||
bool isObject(video::E_MATERIAL_TYPE type);
|
||||
|
||||
// Pass 1 shader (ie shaders that outputs normals and depth)
|
||||
void drawObjectPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView);
|
||||
@ -52,30 +53,4 @@ void drawTransparentObject(const GLMesh &mesh, const core::matrix4 &ModelViewPro
|
||||
void drawTransparentFogObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix);
|
||||
void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix);
|
||||
|
||||
class STKMesh : public irr::scene::CMeshSceneNode
|
||||
{
|
||||
protected:
|
||||
std::vector<GLMesh> GLmeshes;
|
||||
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix;
|
||||
core::vector3df windDir;
|
||||
void drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
void drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
|
||||
// Misc passes shaders (glow, displace...)
|
||||
void drawGlow(const GLMesh &mesh);
|
||||
void drawDisplace(const GLMesh &mesh);
|
||||
void drawShadow(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
void createGLMeshes();
|
||||
void cleanGLMeshes();
|
||||
public:
|
||||
STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position = irr::core::vector3df(0,0,0),
|
||||
const irr::core::vector3df& rotation = irr::core::vector3df(0,0,0),
|
||||
const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f));
|
||||
virtual void render();
|
||||
virtual void setMesh(irr::scene::IMesh* mesh);
|
||||
void MovingTexture(unsigned, unsigned);
|
||||
~STKMesh();
|
||||
};
|
||||
|
||||
#endif // STKMESH_H
|
||||
#endif // STKMESH_H
|
280
src/graphics/stkmeshscenenode.cpp
Normal file
280
src/graphics/stkmeshscenenode.cpp
Normal file
@ -0,0 +1,280 @@
|
||||
#include "stkmeshscenenode.hpp"
|
||||
#include "stkmesh.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include <ISceneManager.h>
|
||||
#include <IMaterialRenderer.h>
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/callbacks.hpp"
|
||||
#include "utils/helpers.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
#include "modes/world.hpp"
|
||||
|
||||
static
|
||||
core::vector3df getWind()
|
||||
{
|
||||
const core::vector3df pos = irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD).getTranslation();
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
GrassShaderProvider *gsp = (GrassShaderProvider *)irr_driver->getCallback(ES_GRASS);
|
||||
float m_speed = gsp->getSpeed(), m_amplitude = gsp->getAmplitude();
|
||||
|
||||
float strength = (pos.X + pos.Y + pos.Z) * 1.2f + time * m_speed;
|
||||
strength = noise2d(strength / 10.0f) * m_amplitude * 5;
|
||||
// * 5 is to work with the existing amplitude values.
|
||||
|
||||
// Pre-multiply on the cpu
|
||||
return irr_driver->getWind() * strength;
|
||||
}
|
||||
|
||||
STKMeshSceneNode::STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position,
|
||||
const irr::core::vector3df& rotation,
|
||||
const irr::core::vector3df& scale) :
|
||||
CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
|
||||
{
|
||||
createGLMeshes();
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::createGLMeshes()
|
||||
{
|
||||
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
GLmeshes.push_back(allocateMeshBuffer(mb));
|
||||
}
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::cleanGLMeshes()
|
||||
{
|
||||
for (u32 i = 0; i < GLmeshes.size(); ++i)
|
||||
{
|
||||
GLMesh mesh = GLmeshes[i];
|
||||
if (!mesh.vertex_buffer)
|
||||
continue;
|
||||
if (mesh.vao_first_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_first_pass));
|
||||
if (mesh.vao_second_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_second_pass));
|
||||
if (mesh.vao_glow_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_glow_pass));
|
||||
if (mesh.vao_displace_pass)
|
||||
glDeleteVertexArrays(1, &(mesh.vao_displace_pass));
|
||||
glDeleteBuffers(1, &(mesh.vertex_buffer));
|
||||
glDeleteBuffers(1, &(mesh.index_buffer));
|
||||
}
|
||||
GLmeshes.clear();
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::setMesh(irr::scene::IMesh* mesh)
|
||||
{
|
||||
CMeshSceneNode::setMesh(mesh);
|
||||
cleanGLMeshes();
|
||||
createGLMeshes();
|
||||
}
|
||||
|
||||
STKMeshSceneNode::~STKMeshSceneNode()
|
||||
{
|
||||
cleanGLMeshes();
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::drawGlow(const GLMesh &mesh)
|
||||
{
|
||||
ColorizeProvider * const cb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE);
|
||||
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
glUseProgram(MeshShader::ColorizeShader::Program);
|
||||
MeshShader::ColorizeShader::setUniforms(ModelViewProjectionMatrix, cb->getRed(), cb->getGreen(), cb->getBlue());
|
||||
|
||||
glBindVertexArray(mesh.vao_glow_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::drawDisplace(const GLMesh &mesh)
|
||||
{
|
||||
DisplaceProvider * const cb = (DisplaceProvider *)irr_driver->getCallback(ES_DISPLACE);
|
||||
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
core::matrix4 ModelViewMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
|
||||
ModelViewMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
||||
setTexture(0, getTextureGLuint(irr_driver->getTexture(FileManager::TEXTURE, "displace.png")), GL_LINEAR, GL_LINEAR, true);
|
||||
glUseProgram(MeshShader::DisplaceShader::Program);
|
||||
MeshShader::DisplaceShader::setUniforms(ModelViewProjectionMatrix, ModelViewMatrix, cb->getDirX(), cb->getDirY(), cb->getDir2X(), cb->getDir2Y(), 0);
|
||||
|
||||
glBindVertexArray(mesh.vao_displace_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
assert(irr_driver->getPhase() == TRANSPARENT_PASS);
|
||||
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
|
||||
if (type == irr_driver->getShader(ES_BUBBLES))
|
||||
drawBubble(mesh, ModelViewProjectionMatrix);
|
||||
else if (World::getWorld()->getTrack()->isFogEnabled())
|
||||
drawTransparentFogObject(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
else
|
||||
drawTransparentObject(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
return;
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::drawShadow(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
|
||||
std::vector<core::matrix4> ShadowMVP(irr_driver->getShadowViewProj());
|
||||
for (unsigned i = 0; i < ShadowMVP.size(); i++)
|
||||
ShadowMVP[i] *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
||||
|
||||
if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
{
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
glUseProgram(MeshShader::RefShadowShader::Program);
|
||||
MeshShader::RefShadowShader::setUniforms(ShadowMVP, 0);
|
||||
}
|
||||
/* else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
|
||||
{
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
glUseProgram(MeshShader::GrassShadowShader::Program);
|
||||
MeshShader::GrassShadowShader::setUniforms(ShadowMVP, windDir, 0);
|
||||
}*/
|
||||
else
|
||||
{
|
||||
glUseProgram(MeshShader::ShadowShader::Program);
|
||||
MeshShader::ShadowShader::setUniforms(ShadowMVP);
|
||||
}
|
||||
glBindVertexArray(mesh.vao_shadow_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
switch (irr_driver->getPhase())
|
||||
{
|
||||
case SOLID_NORMAL_AND_DEPTH_PASS:
|
||||
{
|
||||
windDir = getWind();
|
||||
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
computeTIMV(TransposeInverseModelView);
|
||||
|
||||
if (type == irr_driver->getShader(ES_NORMAL_MAP))
|
||||
drawNormalPass(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
drawObjectRefPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
|
||||
drawGrassPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, windDir);
|
||||
else
|
||||
drawObjectPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
break;
|
||||
}
|
||||
case SOLID_LIT_PASS:
|
||||
{
|
||||
if (type == irr_driver->getShader(ES_SPHERE_MAP))
|
||||
drawSphereMap(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
else if (type == irr_driver->getShader(ES_SPLATTING))
|
||||
drawSplatting(mesh, ModelViewProjectionMatrix);
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
drawObjectRefPass2(mesh, ModelViewProjectionMatrix);
|
||||
else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
|
||||
drawGrassPass2(mesh, ModelViewProjectionMatrix, windDir);
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_RIMLIT))
|
||||
drawObjectRimLimit(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
else if (type == irr_driver->getShader(ES_OBJECT_UNLIT))
|
||||
drawObjectUnlit(mesh, ModelViewProjectionMatrix);
|
||||
else if (mesh.textures[1] && type != irr_driver->getShader(ES_NORMAL_MAP))
|
||||
drawDetailledObjectPass2(mesh, ModelViewProjectionMatrix);
|
||||
else if (!mesh.textures[0])
|
||||
drawUntexturedObject(mesh, ModelViewProjectionMatrix);
|
||||
else if (!TextureMatrix.isIdentity())
|
||||
drawMovingTexture(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
else
|
||||
drawObjectPass2(mesh, ModelViewProjectionMatrix);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
assert(0 && "wrong pass");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::render()
|
||||
{
|
||||
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||
|
||||
if (!Mesh || !driver)
|
||||
return;
|
||||
|
||||
bool isTransparentPass =
|
||||
SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
|
||||
|
||||
++PassCount;
|
||||
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
Box = Mesh->getBoundingBox();
|
||||
|
||||
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (mb)
|
||||
{
|
||||
TextureMatrix = getMaterial(i).getTextureMatrix(0);
|
||||
const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
|
||||
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType);
|
||||
bool transparent = (rnd && rnd->isTransparent());
|
||||
|
||||
if (isTransparentPass != transparent)
|
||||
continue;
|
||||
if (irr_driver->getPhase() == DISPLACEMENT_PASS)
|
||||
{
|
||||
initvaostate(GLmeshes[i], material.MaterialType, false);
|
||||
drawDisplace(GLmeshes[i]);
|
||||
continue;
|
||||
}
|
||||
if (!isObject(material.MaterialType))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::warn("material", "Unhandled (static) material type : %d", material.MaterialType);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
// only render transparent buffer if this is the transparent render pass
|
||||
// and solid only in solid pass
|
||||
if (irr_driver->getPhase() == GLOW_PASS)
|
||||
{
|
||||
initvaostate(GLmeshes[i], material.MaterialType, TextureMatrix.isIdentity());
|
||||
drawGlow(GLmeshes[i]);
|
||||
}
|
||||
else if (irr_driver->getPhase() == SHADOW_PASS)
|
||||
{
|
||||
initvaostate(GLmeshes[i], material.MaterialType, TextureMatrix.isIdentity());
|
||||
drawShadow(GLmeshes[i], material.MaterialType);
|
||||
}
|
||||
else
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
initvaostate(GLmeshes[i], material.MaterialType, TextureMatrix.isIdentity());
|
||||
if (transparent)
|
||||
drawTransparent(GLmeshes[i], material.MaterialType);
|
||||
else
|
||||
drawSolid(GLmeshes[i], material.MaterialType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
32
src/graphics/stkmeshscenenode.hpp
Normal file
32
src/graphics/stkmeshscenenode.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef STKMESHSCENENODE_H
|
||||
#define STKMESHSCENENODE_H
|
||||
|
||||
#include "stkmesh.hpp"
|
||||
|
||||
class STKMeshSceneNode : public irr::scene::CMeshSceneNode
|
||||
{
|
||||
protected:
|
||||
std::vector<GLMesh> GLmeshes;
|
||||
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix;
|
||||
core::vector3df windDir;
|
||||
void drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
void drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
|
||||
// Misc passes shaders (glow, displace...)
|
||||
void drawGlow(const GLMesh &mesh);
|
||||
void drawDisplace(const GLMesh &mesh);
|
||||
void drawShadow(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
void createGLMeshes();
|
||||
void cleanGLMeshes();
|
||||
public:
|
||||
STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position = irr::core::vector3df(0, 0, 0),
|
||||
const irr::core::vector3df& rotation = irr::core::vector3df(0, 0, 0),
|
||||
const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f));
|
||||
virtual void render();
|
||||
virtual void setMesh(irr::scene::IMesh* mesh);
|
||||
void MovingTexture(unsigned, unsigned);
|
||||
~STKMeshSceneNode();
|
||||
};
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user