Merge branch 'master' into konstin-m_random_gp
Conflicts: src/states_screens/dialogs/gp_info_dialog.cpp
This commit is contained in:
commit
f24e53538c
@ -42,14 +42,6 @@ void main()
|
||||
// Fade according to distance to cam
|
||||
float fade = 1.0 - smoothstep(1.0, 100.0, camdist);
|
||||
|
||||
// Fade according to distance from the edges
|
||||
const float mindist = 0.1;
|
||||
fade *= smoothstep(0.0, mindist, uv_bis.x) * smoothstep(0.0, mindist, uv_bis.y) *
|
||||
(1.0 - smoothstep(1.0 - mindist, 1.0, uv_bis.x)) *
|
||||
(1.0 - smoothstep(1.0 - mindist, 1.0, uv_bis.y));
|
||||
|
||||
offset *= 50.0 * fade * maxlen;
|
||||
|
||||
vec4 shiftval;
|
||||
shiftval.r = step(offset.x, 0.0) * -offset.x;
|
||||
shiftval.g = step(0.0, offset.x) * offset.x;
|
||||
|
@ -1,8 +1,23 @@
|
||||
#ifdef UBO_DISABLED
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 InverseViewMatrix;
|
||||
uniform mat4 InverseProjectionMatrix;
|
||||
#else
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
vec2 screen;
|
||||
};
|
||||
#endif
|
||||
|
||||
uniform sampler2D Albedo;
|
||||
uniform vec3 SunDir;
|
||||
uniform mat4 invproj;
|
||||
uniform sampler2D dtex;
|
||||
uniform vec2 screen;
|
||||
|
||||
in vec3 nor;
|
||||
in vec2 uv;
|
||||
@ -16,7 +31,7 @@ void main(void)
|
||||
float z = texture(dtex, texc).x;
|
||||
|
||||
vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0f;
|
||||
xpos = invproj * xpos;
|
||||
xpos = InverseProjectionMatrix * xpos;
|
||||
xpos /= xpos.w;
|
||||
vec3 eyedir = normalize(xpos.xyz);
|
||||
|
||||
|
49
data/shaders/instanciedgrassshadow.vert
Normal file
49
data/shaders/instanciedgrassshadow.vert
Normal file
@ -0,0 +1,49 @@
|
||||
layout (std140) uniform MatrixesData
|
||||
{
|
||||
mat4 ViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 InverseViewMatrix;
|
||||
mat4 InverseProjectionMatrix;
|
||||
mat4 ShadowViewProjMatrixes[4];
|
||||
};
|
||||
uniform vec3 windDir;
|
||||
#if __VERSION__ >= 330
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 2) in vec4 Color;
|
||||
layout(location = 3) in vec2 Texcoord;
|
||||
|
||||
layout(location = 7) in vec3 Origin;
|
||||
layout(location = 8) in vec3 Orientation;
|
||||
layout(location = 9) in vec3 Scale;
|
||||
#else
|
||||
in vec3 Position;
|
||||
in vec2 Texcoord;
|
||||
|
||||
in vec3 Origin;
|
||||
in vec3 Orientation;
|
||||
in vec3 Scale;
|
||||
#endif
|
||||
|
||||
#ifdef VSLayer
|
||||
out vec2 uv;
|
||||
#else
|
||||
out vec2 tc;
|
||||
out int layerId;
|
||||
#endif
|
||||
|
||||
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
||||
#ifdef VSLayer
|
||||
gl_Layer = gl_InstanceID & 3;
|
||||
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
|
||||
uv = Texcoord;
|
||||
#else
|
||||
layerId = gl_InstanceID & 3;
|
||||
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
|
||||
tc = Texcoord;
|
||||
#endif
|
||||
}
|
@ -787,673 +787,4 @@ void IrrDriver::renderGlow(std::vector<GlowData>& glows)
|
||||
m_rtts->getFBO(FBO_COLORS).Bind();
|
||||
m_post_processing->renderGlow(m_rtts->getRenderTarget(RTT_QUARTER1));
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static LightShader::PointLightInfo PointLightsInfo[MAXLIGHT];
|
||||
|
||||
static void renderPointLights(unsigned count)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
glUseProgram(LightShader::PointLightShader::Program);
|
||||
glBindVertexArray(LightShader::PointLightShader::vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, LightShader::PointLightShader::vbo);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(LightShader::PointLightInfo), PointLightsInfo);
|
||||
|
||||
setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
LightShader::PointLightShader
|
||||
::setUniforms(core::vector2df(float(UserConfigParams::m_width),
|
||||
float(UserConfigParams::m_height) ),
|
||||
200, 0, 1);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
|
||||
}
|
||||
|
||||
unsigned IrrDriver::UpdateLightsInfo(scene::ICameraSceneNode * const camnode, float dt)
|
||||
{
|
||||
const u32 lightcount = m_lights.size();
|
||||
const core::vector3df &campos = camnode->getAbsolutePosition();
|
||||
|
||||
std::vector<LightNode *> BucketedLN[15];
|
||||
for (unsigned int i = 0; i < lightcount; i++)
|
||||
{
|
||||
if (!m_lights[i]->isPointLight())
|
||||
{
|
||||
m_lights[i]->render();
|
||||
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;
|
||||
|
||||
for (unsigned i = 0; i < 15; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < BucketedLN[i].size(); j++)
|
||||
{
|
||||
if (++lightnum >= MAXLIGHT)
|
||||
{
|
||||
LightNode* light_node = BucketedLN[i].at(j);
|
||||
light_node->setEnergyMultiplier(0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
LightNode* light_node = BucketedLN[i].at(j);
|
||||
|
||||
float em = light_node->getEnergyMultiplier();
|
||||
if (em < 1.0f)
|
||||
{
|
||||
light_node->setEnergyMultiplier(std::min(1.0f, em + dt));
|
||||
}
|
||||
|
||||
const core::vector3df &pos = light_node->getAbsolutePosition();
|
||||
PointLightsInfo[lightnum].posX = pos.X;
|
||||
PointLightsInfo[lightnum].posY = pos.Y;
|
||||
PointLightsInfo[lightnum].posZ = pos.Z;
|
||||
|
||||
PointLightsInfo[lightnum].energy = light_node->getEffectiveEnergy();
|
||||
|
||||
const core::vector3df &col = light_node->getColor();
|
||||
PointLightsInfo[lightnum].red = col.X;
|
||||
PointLightsInfo[lightnum].green = col.Y;
|
||||
PointLightsInfo[lightnum].blue = col.Z;
|
||||
|
||||
// Light radius
|
||||
PointLightsInfo[lightnum].radius = light_node->getRadius();
|
||||
}
|
||||
}
|
||||
if (lightnum > MAXLIGHT)
|
||||
{
|
||||
irr_driver->setLastLightBucketDistance(i * 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lightnum++;
|
||||
return lightnum;
|
||||
}
|
||||
|
||||
void IrrDriver::renderLights(unsigned pointlightcount)
|
||||
{
|
||||
//RH
|
||||
if (UserConfigParams::m_gi)
|
||||
{
|
||||
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_RH));
|
||||
glDisable(GL_BLEND);
|
||||
m_rtts->getRH().Bind();
|
||||
glUseProgram(FullScreenShader::RadianceHintsConstructionShader::Program);
|
||||
glBindVertexArray(FullScreenShader::RadianceHintsConstructionShader::vao);
|
||||
setTexture(0, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(1, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(2, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::RadianceHintsConstructionShader::setUniforms(rsm_matrix, rh_matrix, rh_extend, 0, 1, 2);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
|
||||
sun_ortho_matrix[i] *= getInvViewMatrix();
|
||||
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
glClearColor(.5, .5, .5, .5);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
return;
|
||||
|
||||
m_rtts->getFBO(FBO_TMP1_WITH_DS).Bind();
|
||||
if (UserConfigParams::m_gi)
|
||||
{
|
||||
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_GI));
|
||||
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
|
||||
}
|
||||
|
||||
if (SkyboxCubeMap)
|
||||
{
|
||||
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_ENVMAP));
|
||||
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
}
|
||||
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
|
||||
|
||||
if (World::getWorld() && World::getWorld()->getTrack()->hasShadows() && SkyboxCubeMap)
|
||||
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
|
||||
|
||||
// Render sunlight if and only if track supports shadow
|
||||
if (!World::getWorld() || World::getWorld()->getTrack()->hasShadows())
|
||||
{
|
||||
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_SUN));
|
||||
if (World::getWorld() && UserConfigParams::m_shadows)
|
||||
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
|
||||
else
|
||||
m_post_processing->renderSunlight();
|
||||
}
|
||||
{
|
||||
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_POINTLIGHTS));
|
||||
renderPointLights(MIN2(pointlightcount, MAXLIGHT));
|
||||
}
|
||||
}
|
||||
|
||||
void IrrDriver::renderSSAO()
|
||||
{
|
||||
m_rtts->getFBO(FBO_SSAO).Bind();
|
||||
glClearColor(1., 1., 1., 1.);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
m_post_processing->renderSSAO();
|
||||
// Blur it to reduce noise.
|
||||
FrameBuffer::Blit(m_rtts->getFBO(FBO_SSAO), m_rtts->getFBO(FBO_HALF1_R), GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
m_post_processing->renderGaussian17TapBlur(irr_driver->getFBO(FBO_HALF1_R), irr_driver->getFBO(FBO_HALF2_R));
|
||||
|
||||
}
|
||||
|
||||
static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z)
|
||||
{
|
||||
switch (face)
|
||||
{
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
x = 1.;
|
||||
y = -i;
|
||||
z = -j;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
x = -1.;
|
||||
y = -i;
|
||||
z = j;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
x = j;
|
||||
y = 1.;
|
||||
z = i;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
x = j;
|
||||
y = -1;
|
||||
z = -i;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
x = j;
|
||||
y = -i;
|
||||
z = 1;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
x = -j;
|
||||
y = -i;
|
||||
z = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
float norm = sqrt(x * x + y * y + z * z);
|
||||
x /= norm, y /= norm, z /= norm;
|
||||
return;
|
||||
}
|
||||
|
||||
static void getYml(GLenum face, size_t width, size_t height,
|
||||
float *Y00,
|
||||
float *Y1minus1, float *Y10, float *Y11,
|
||||
float *Y2minus2, float *Y2minus1, float *Y20, float *Y21, float *Y22)
|
||||
{
|
||||
for (unsigned i = 0; i < width; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < height; j++)
|
||||
{
|
||||
float x, y, z;
|
||||
float fi = float(i), fj = float(j);
|
||||
fi /= width, fj /= height;
|
||||
fi = 2 * fi - 1, fj = 2 * fj - 1;
|
||||
getXYZ(face, fi, fj, x, y, z);
|
||||
|
||||
// constant part of Ylm
|
||||
float c00 = 0.282095f;
|
||||
float c1minus1 = 0.488603f;
|
||||
float c10 = 0.488603f;
|
||||
float c11 = 0.488603f;
|
||||
float c2minus2 = 1.092548f;
|
||||
float c2minus1 = 1.092548f;
|
||||
float c21 = 1.092548f;
|
||||
float c20 = 0.315392f;
|
||||
float c22 = 0.546274f;
|
||||
|
||||
size_t idx = i * height + j;
|
||||
|
||||
Y00[idx] = c00;
|
||||
Y1minus1[idx] = c1minus1 * y;
|
||||
Y10[idx] = c10 * z;
|
||||
Y11[idx] = c11 * x;
|
||||
Y2minus2[idx] = c2minus2 * x * y;
|
||||
Y2minus1[idx] = c2minus1 * y * z;
|
||||
Y21[idx] = c21 * x * z;
|
||||
Y20[idx] = c20 * (3 * z * z - 1);
|
||||
Y22[idx] = c22 * (x * x - y * y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static float getTexelValue(unsigned i, unsigned j, size_t width, size_t height, float *Coeff, float *Y00, float *Y1minus1, float *Y10, float *Y11,
|
||||
float *Y2minus2, float * Y2minus1, float * Y20, float *Y21, float *Y22)
|
||||
{
|
||||
float d = sqrt((float)(i * i + j * j + 1));
|
||||
float solidangle = 1.;
|
||||
size_t idx = i * height + j;
|
||||
float reconstructedVal = Y00[idx] * Coeff[0];
|
||||
reconstructedVal += Y1minus1[i * height + j] * Coeff[1] + Y10[i * height + j] * Coeff[2] + Y11[i * height + j] * Coeff[3];
|
||||
reconstructedVal += Y2minus2[idx] * Coeff[4] + Y2minus1[idx] * Coeff[5] + Y20[idx] * Coeff[6] + Y21[idx] * Coeff[7] + Y22[idx] * Coeff[8];
|
||||
reconstructedVal /= solidangle;
|
||||
return MAX2(255.0f * reconstructedVal, 0.f);
|
||||
}
|
||||
|
||||
static void unprojectSH(float *output[], size_t width, size_t height,
|
||||
float *Y00[],
|
||||
float *Y1minus1[], float *Y10[], float *Y11[],
|
||||
float *Y2minus2[], float *Y2minus1[], float * Y20[],float *Y21[], float *Y22[],
|
||||
float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff)
|
||||
{
|
||||
for (unsigned face = 0; face < 6; face++)
|
||||
{
|
||||
for (unsigned i = 0; i < width; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < height; j++)
|
||||
{
|
||||
float fi = float(i), fj = float(j);
|
||||
fi /= width, fj /= height;
|
||||
fi = 2 * fi - 1, fj = 2 * fj - 1;
|
||||
|
||||
output[face][4 * height * i + 4 * j + 2] = getTexelValue(i, j, width, height,
|
||||
redSHCoeff,
|
||||
Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
|
||||
output[face][4 * height * i + 4 * j + 1] = getTexelValue(i, j, width, height,
|
||||
greenSHCoeff,
|
||||
Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
|
||||
output[face][4 * height * i + 4 * j] = getTexelValue(i, j, width, height,
|
||||
blueSHCoeff,
|
||||
Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void projectSH(float *color[], size_t width, size_t height,
|
||||
float *Y00[],
|
||||
float *Y1minus1[], float *Y10[], float *Y11[],
|
||||
float *Y2minus2[], float *Y2minus1[], float * Y20[], float *Y21[], float *Y22[],
|
||||
float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff
|
||||
)
|
||||
{
|
||||
for (unsigned i = 0; i < 9; i++)
|
||||
{
|
||||
blueSHCoeff[i] = 0;
|
||||
greenSHCoeff[i] = 0;
|
||||
redSHCoeff[i] = 0;
|
||||
}
|
||||
float wh = float(width * height);
|
||||
for (unsigned face = 0; face < 6; face++)
|
||||
{
|
||||
for (unsigned i = 0; i < width; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < height; j++)
|
||||
{
|
||||
size_t idx = i * height + j;
|
||||
float fi = float(i), fj = float(j);
|
||||
fi /= width, fj /= height;
|
||||
fi = 2 * fi - 1, fj = 2 * fj - 1;
|
||||
|
||||
|
||||
float d = sqrt(fi * fi + fj * fj + 1);
|
||||
|
||||
// Constant obtained by projecting unprojected ref values
|
||||
float solidangle = 2.75f / (wh * pow(d, 1.5f));
|
||||
// pow(., 2.2) to convert from srgb
|
||||
float b = pow(color[face][4 * height * i + 4 * j ] / 255.f, 2.2f);
|
||||
float g = pow(color[face][4 * height * i + 4 * j + 1] / 255.f, 2.2f);
|
||||
float r = pow(color[face][4 * height * i + 4 * j + 2] / 255.f, 2.2f);
|
||||
|
||||
assert(b >= 0.);
|
||||
|
||||
blueSHCoeff[0] += b * Y00[face][idx] * solidangle;
|
||||
blueSHCoeff[1] += b * Y1minus1[face][idx] * solidangle;
|
||||
blueSHCoeff[2] += b * Y10[face][idx] * solidangle;
|
||||
blueSHCoeff[3] += b * Y11[face][idx] * solidangle;
|
||||
blueSHCoeff[4] += b * Y2minus2[face][idx] * solidangle;
|
||||
blueSHCoeff[5] += b * Y2minus1[face][idx] * solidangle;
|
||||
blueSHCoeff[6] += b * Y20[face][idx] * solidangle;
|
||||
blueSHCoeff[7] += b * Y21[face][idx] * solidangle;
|
||||
blueSHCoeff[8] += b * Y22[face][idx] * solidangle;
|
||||
|
||||
greenSHCoeff[0] += g * Y00[face][idx] * solidangle;
|
||||
greenSHCoeff[1] += g * Y1minus1[face][idx] * solidangle;
|
||||
greenSHCoeff[2] += g * Y10[face][idx] * solidangle;
|
||||
greenSHCoeff[3] += g * Y11[face][idx] * solidangle;
|
||||
greenSHCoeff[4] += g * Y2minus2[face][idx] * solidangle;
|
||||
greenSHCoeff[5] += g * Y2minus1[face][idx] * solidangle;
|
||||
greenSHCoeff[6] += g * Y20[face][idx] * solidangle;
|
||||
greenSHCoeff[7] += g * Y21[face][idx] * solidangle;
|
||||
greenSHCoeff[8] += g * Y22[face][idx] * solidangle;
|
||||
|
||||
|
||||
redSHCoeff[0] += r * Y00[face][idx] * solidangle;
|
||||
redSHCoeff[1] += r * Y1minus1[face][idx] * solidangle;
|
||||
redSHCoeff[2] += r * Y10[face][idx] * solidangle;
|
||||
redSHCoeff[3] += r * Y11[face][idx] * solidangle;
|
||||
redSHCoeff[4] += r * Y2minus2[face][idx] * solidangle;
|
||||
redSHCoeff[5] += r * Y2minus1[face][idx] * solidangle;
|
||||
redSHCoeff[6] += r * Y20[face][idx] * solidangle;
|
||||
redSHCoeff[7] += r * Y21[face][idx] * solidangle;
|
||||
redSHCoeff[8] += r * Y22[face][idx] * solidangle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void displayCoeff(float *SHCoeff)
|
||||
{
|
||||
printf("L00:%f\n", SHCoeff[0]);
|
||||
printf("L1-1:%f, L10:%f, L11:%f\n", SHCoeff[1], SHCoeff[2], SHCoeff[3]);
|
||||
printf("L2-2:%f, L2-1:%f, L20:%f, L21:%f, L22:%f\n", SHCoeff[4], SHCoeff[5], SHCoeff[6], SHCoeff[7], SHCoeff[8]);
|
||||
}
|
||||
|
||||
// Only for 9 coefficients
|
||||
static void testSH(unsigned char *color[6], size_t width, size_t height,
|
||||
float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff)
|
||||
{
|
||||
float *Y00[6];
|
||||
float *Y1minus1[6];
|
||||
float *Y10[6];
|
||||
float *Y11[6];
|
||||
float *Y2minus2[6];
|
||||
float *Y2minus1[6];
|
||||
float *Y20[6];
|
||||
float *Y21[6];
|
||||
float *Y22[6];
|
||||
|
||||
float *testoutput[6];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
testoutput[i] = new float[width * height * 4];
|
||||
for (unsigned j = 0; j < width * height; j++)
|
||||
{
|
||||
testoutput[i][4 * j ] = float(0xFF & color[i][4 * j]);
|
||||
testoutput[i][4 * j + 1] = float(0xFF & color[i][4 * j + 1]);
|
||||
testoutput[i][4 * j + 2] = float(0xFF & color[i][4 * j + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned face = 0; face < 6; face++)
|
||||
{
|
||||
Y00[face] = new float[width * height];
|
||||
Y1minus1[face] = new float[width * height];
|
||||
Y10[face] = new float[width * height];
|
||||
Y11[face] = new float[width * height];
|
||||
Y2minus2[face] = new float[width * height];
|
||||
Y2minus1[face] = new float[width * height];
|
||||
Y20[face] = new float[width * height];
|
||||
Y21[face] = new float[width * height];
|
||||
Y22[face] = new float[width * height];
|
||||
|
||||
getYml(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, width, height, Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
|
||||
}
|
||||
|
||||
/* blueSHCoeff[0] = 0.54,
|
||||
blueSHCoeff[1] = .6, blueSHCoeff[2] = -.27, blueSHCoeff[3] = .01,
|
||||
blueSHCoeff[4] = -.12, blueSHCoeff[5] = -.47, blueSHCoeff[6] = -.15, blueSHCoeff[7] = .14, blueSHCoeff[8] = -.3;
|
||||
greenSHCoeff[0] = .44,
|
||||
greenSHCoeff[1] = .35, greenSHCoeff[2] = -.18, greenSHCoeff[3] = -.06,
|
||||
greenSHCoeff[4] = -.05, greenSHCoeff[5] = -.22, greenSHCoeff[6] = -.09, greenSHCoeff[7] = .21, greenSHCoeff[8] = -.05;
|
||||
redSHCoeff[0] = .79,
|
||||
redSHCoeff[1] = .39, redSHCoeff[2] = -.34, redSHCoeff[3] = -.29,
|
||||
redSHCoeff[4] = -.11, redSHCoeff[5] = -.26, redSHCoeff[6] = -.16, redSHCoeff[7] = .56, redSHCoeff[8] = .21;
|
||||
|
||||
printf("Blue:\n");
|
||||
displayCoeff(blueSHCoeff);
|
||||
printf("Green:\n");
|
||||
displayCoeff(greenSHCoeff);
|
||||
printf("Red:\n");
|
||||
displayCoeff(redSHCoeff);*/
|
||||
|
||||
projectSH(testoutput, width, height,
|
||||
Y00,
|
||||
Y1minus1, Y10, Y11,
|
||||
Y2minus2, Y2minus1, Y20, Y21, Y22,
|
||||
blueSHCoeff, greenSHCoeff, redSHCoeff
|
||||
);
|
||||
|
||||
//printf("Blue:\n");
|
||||
//displayCoeff(blueSHCoeff);
|
||||
//printf("Green:\n");
|
||||
//displayCoeff(greenSHCoeff);
|
||||
//printf("Red:\n");
|
||||
//displayCoeff(redSHCoeff);
|
||||
|
||||
|
||||
|
||||
// Convolute in frequency space
|
||||
/* float A0 = 3.141593;
|
||||
float A1 = 2.094395;
|
||||
float A2 = 0.785398;
|
||||
blueSHCoeff[0] *= A0;
|
||||
greenSHCoeff[0] *= A0;
|
||||
redSHCoeff[0] *= A0;
|
||||
for (unsigned i = 0; i < 3; i++)
|
||||
{
|
||||
blueSHCoeff[1 + i] *= A1;
|
||||
greenSHCoeff[1 + i] *= A1;
|
||||
redSHCoeff[1 + i] *= A1;
|
||||
}
|
||||
for (unsigned i = 0; i < 5; i++)
|
||||
{
|
||||
blueSHCoeff[4 + i] *= A2;
|
||||
greenSHCoeff[4 + i] *= A2;
|
||||
redSHCoeff[4 + i] *= A2;
|
||||
}
|
||||
|
||||
|
||||
unprojectSH(testoutput, width, height,
|
||||
Y00,
|
||||
Y1minus1, Y10, Y11,
|
||||
Y2minus2, Y2minus1, Y20, Y21, Y22,
|
||||
blueSHCoeff, greenSHCoeff, redSHCoeff
|
||||
);*/
|
||||
|
||||
|
||||
/* printf("Blue:\n");
|
||||
displayCoeff(blueSHCoeff);
|
||||
printf("Green:\n");
|
||||
displayCoeff(greenSHCoeff);
|
||||
printf("Red:\n");
|
||||
displayCoeff(redSHCoeff);
|
||||
|
||||
printf("\nAfter projection\n\n");*/
|
||||
|
||||
|
||||
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < width * height; j++)
|
||||
{
|
||||
color[i][4 * j ] = char(MIN2(testoutput[i][4 * j], 255));
|
||||
color[i][4 * j + 1] = char(MIN2(testoutput[i][4 * j + 1], 255));
|
||||
color[i][4 * j + 2] = char(MIN2(testoutput[i][4 * j + 2], 255));
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned face = 0; face < 6; face++)
|
||||
{
|
||||
delete[] testoutput[face];
|
||||
delete[] Y00[face];
|
||||
delete[] Y1minus1[face];
|
||||
delete[] Y10[face];
|
||||
delete[] Y11[face];
|
||||
}
|
||||
}
|
||||
|
||||
/** Generate an opengl cubemap texture from 6 2d textures.
|
||||
Out of legacy the sequence of textures maps to :
|
||||
- 1st texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_Y
|
||||
- 2nd texture maps to GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
|
||||
- 3rd texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_X
|
||||
- 4th texture maps to GL_TEXTURE_CUBE_MAP_NEGATIVE_X
|
||||
- 5th texture maps to GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
|
||||
- 6th texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_Z
|
||||
* \param textures sequence of 6 textures.
|
||||
*/
|
||||
GLuint generateCubeMapFromTextures(const std::vector<video::ITexture *> &textures)
|
||||
{
|
||||
assert(textures.size() == 6);
|
||||
|
||||
GLuint result;
|
||||
glGenTextures(1, &result);
|
||||
|
||||
unsigned w = 0, h = 0;
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
w = MAX2(w, textures[i]->getOriginalSize().Width);
|
||||
h = MAX2(h, textures[i]->getOriginalSize().Height);
|
||||
}
|
||||
|
||||
const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 };
|
||||
char *rgba[6];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
rgba[i] = new char[w * h * 4];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
unsigned idx = texture_permutation[i];
|
||||
|
||||
video::IImage* image = irr_driver->getVideoDriver()->createImageFromData(
|
||||
textures[idx]->getColorFormat(),
|
||||
textures[idx]->getSize(),
|
||||
textures[idx]->lock(),
|
||||
false
|
||||
);
|
||||
textures[idx]->unlock();
|
||||
|
||||
image->copyToScaling(rgba[i], w, h);
|
||||
image->drop();
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, result);
|
||||
if (UserConfigParams::m_texture_compression)
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_COMPRESSED_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
|
||||
else
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
|
||||
}
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
delete[] rgba[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
void IrrDriver::generateSkyboxCubemap()
|
||||
{
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
|
||||
assert(SkyboxTextures.size() == 6);
|
||||
SkyboxCubeMap = generateCubeMapFromTextures(SkyboxTextures);
|
||||
const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 };
|
||||
|
||||
if (SphericalHarmonicsTextures.size() == 6)
|
||||
{
|
||||
unsigned sh_w = 0, sh_h = 0;
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
sh_w = MAX2(sh_w, SphericalHarmonicsTextures[i]->getOriginalSize().Width);
|
||||
sh_h = MAX2(sh_h, SphericalHarmonicsTextures[i]->getOriginalSize().Height);
|
||||
}
|
||||
|
||||
unsigned char *sh_rgba[6];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
sh_rgba[i] = new unsigned char[sh_w * sh_h * 4];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
unsigned idx = texture_permutation[i];
|
||||
|
||||
video::IImage* image = getVideoDriver()->createImageFromData(
|
||||
SphericalHarmonicsTextures[idx]->getColorFormat(),
|
||||
SphericalHarmonicsTextures[idx]->getSize(),
|
||||
SphericalHarmonicsTextures[idx]->lock(),
|
||||
false
|
||||
);
|
||||
SphericalHarmonicsTextures[idx]->unlock();
|
||||
|
||||
image->copyToScaling(sh_rgba[i], sh_w, sh_h);
|
||||
image->drop();
|
||||
}
|
||||
|
||||
testSH(sh_rgba, sh_w, sh_h, blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
delete[] sh_rgba[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
int sh_w = 16;
|
||||
int sh_h = 16;
|
||||
|
||||
const video::SColorf& ambientf = irr_driver->getSceneManager()->getAmbientLight();
|
||||
video::SColor ambient = ambientf.toSColor();
|
||||
|
||||
unsigned char *sh_rgba[6];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
sh_rgba[i] = new unsigned char[sh_w * sh_h * 4];
|
||||
|
||||
for (int j = 0; j < sh_w * sh_h * 4; j+=4)
|
||||
{
|
||||
sh_rgba[i][j] = ambient.getBlue();
|
||||
sh_rgba[i][j + 1] = ambient.getGreen();
|
||||
sh_rgba[i][j + 2] = ambient.getRed();
|
||||
sh_rgba[i][j + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
testSH(sh_rgba, sh_w, sh_h, blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
delete[] sh_rgba[i];
|
||||
}
|
||||
|
||||
/*for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, ConvolutedSkyboxCubeMap);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);*/
|
||||
}
|
||||
|
||||
void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
|
||||
{
|
||||
if (SkyboxTextures.empty())
|
||||
return;
|
||||
if (!SkyboxCubeMap)
|
||||
generateSkyboxCubemap();
|
||||
glBindVertexArray(MeshShader::SkyboxShader::cubevao);
|
||||
glDisable(GL_CULL_FACE);
|
||||
assert(SkyboxTextures.size() == 6);
|
||||
|
||||
core::matrix4 translate;
|
||||
translate.setTranslation(camera->getAbsolutePosition());
|
||||
|
||||
// Draw the sky box between the near and far clip plane
|
||||
const f32 viewDistance = (camera->getNearValue() + camera->getFarValue()) * 0.5f;
|
||||
core::matrix4 scale;
|
||||
scale.setScale(core::vector3df(viewDistance, viewDistance, viewDistance));
|
||||
core::matrix4 transform = translate * scale;
|
||||
core::matrix4 invtransform;
|
||||
transform.getInverse(invtransform);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, SkyboxCubeMap);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glUseProgram(MeshShader::SkyboxShader::Program);
|
||||
MeshShader::SkyboxShader::setUniforms(transform,
|
||||
core::vector2df(float(UserConfigParams::m_width),
|
||||
float(UserConfigParams::m_height)),
|
||||
0);
|
||||
glDrawElements(GL_TRIANGLES, 6 * 6, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
@ -261,6 +261,9 @@ void IrrDriver::renderTransparent()
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
|
||||
glBindVertexArray(getVAO(EVT_2TCOORDS));
|
||||
// Generate displace mask
|
||||
// Use RTT_TMP4 as displace mask
|
||||
irr_driver->getFBO(FBO_TMP1_WITH_DS).Bind();
|
||||
for (unsigned i = 0; i < ListDisplacement::Arguments.size(); i++)
|
||||
{
|
||||
const GLMesh &mesh = *(std::get<0>(ListDisplacement::Arguments[i]));
|
||||
@ -273,35 +276,37 @@ void IrrDriver::renderTransparent()
|
||||
continue;
|
||||
}
|
||||
|
||||
DisplaceProvider * const cb = (DisplaceProvider *)irr_driver->getCallback(ES_DISPLACE);
|
||||
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
// Generate displace mask
|
||||
// Use RTT_TMP4 as displace mask
|
||||
irr_driver->getFBO(FBO_TMP1_WITH_DS).Bind();
|
||||
|
||||
glUseProgram(MeshShader::DisplaceMaskShader::Program);
|
||||
MeshShader::DisplaceMaskShader::setUniforms(AbsoluteTransformation);
|
||||
glUseProgram(MeshShader::DisplaceMaskShaderInstance->Program);
|
||||
MeshShader::DisplaceMaskShaderInstance->setUniforms(AbsoluteTransformation);
|
||||
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
|
||||
}
|
||||
|
||||
irr_driver->getFBO(FBO_DISPLACE).Bind();
|
||||
if (!displaceTex)
|
||||
displaceTex = irr_driver->getTexture(FileManager::TEXTURE, "displace.png");
|
||||
for (unsigned i = 0; i < ListDisplacement::Arguments.size(); i++)
|
||||
{
|
||||
const GLMesh &mesh = *(std::get<0>(ListDisplacement::Arguments[i]));
|
||||
const core::matrix4 &AbsoluteTransformation = std::get<1>(ListDisplacement::Arguments[i]);
|
||||
if (mesh.VAOType != video::EVT_2TCOORDS)
|
||||
continue;
|
||||
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
// Render the effect
|
||||
if (!displaceTex)
|
||||
displaceTex = irr_driver->getTexture(FileManager::TEXTURE, "displace.png");
|
||||
irr_driver->getFBO(FBO_DISPLACE).Bind();
|
||||
setTexture(0, getTextureGLuint(displaceTex), GL_LINEAR, GL_LINEAR, true);
|
||||
setTexture(1, irr_driver->getRenderTargetTexture(RTT_TMP1), GL_LINEAR, GL_LINEAR, true);
|
||||
setTexture(2, irr_driver->getRenderTargetTexture(RTT_COLOR), GL_LINEAR, GL_LINEAR, true);
|
||||
setTexture(3, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR, true);
|
||||
glUseProgram(MeshShader::DisplaceShader::Program);
|
||||
MeshShader::DisplaceShader::setUniforms(AbsoluteTransformation,
|
||||
setTexture(MeshShader::DisplaceShaderInstance->TU_displacement_tex, getTextureGLuint(displaceTex), GL_LINEAR, GL_LINEAR, true);
|
||||
setTexture(MeshShader::DisplaceShaderInstance->TU_mask_tex, irr_driver->getRenderTargetTexture(RTT_TMP1), GL_LINEAR, GL_LINEAR, true);
|
||||
setTexture(MeshShader::DisplaceShaderInstance->TU_color_tex, irr_driver->getRenderTargetTexture(RTT_COLOR), GL_LINEAR, GL_LINEAR, true);
|
||||
setTexture(MeshShader::DisplaceShaderInstance->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR, true);
|
||||
glUseProgram(MeshShader::DisplaceShaderInstance->Program);
|
||||
MeshShader::DisplaceShaderInstance->setUniforms(AbsoluteTransformation,
|
||||
core::vector2df(cb->getDirX(), cb->getDirY()),
|
||||
core::vector2df(cb->getDir2X(), cb->getDir2Y()),
|
||||
core::vector2df(float(UserConfigParams::m_width),
|
||||
float(UserConfigParams::m_height)),
|
||||
0, 1, 2, 3);
|
||||
core::vector2df(cb->getDir2X(), cb->getDir2Y()));
|
||||
|
||||
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
|
||||
}
|
||||
|
199
src/graphics/render_lighting.cpp
Normal file
199
src/graphics/render_lighting.cpp
Normal file
@ -0,0 +1,199 @@
|
||||
#include "graphics/irr_driver.hpp"
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/callbacks.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/lens_flare.hpp"
|
||||
#include "graphics/light.hpp"
|
||||
#include "graphics/lod_node.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/particle_kind_manager.hpp"
|
||||
#include "graphics/per_camera_node.hpp"
|
||||
#include "graphics/post_processing.hpp"
|
||||
#include "graphics/referee.hpp"
|
||||
#include "graphics/rtts.hpp"
|
||||
#include "graphics/screenquad.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/stkmeshscenenode.hpp"
|
||||
#include "graphics/stkinstancedscenenode.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "items/item.hpp"
|
||||
#include "items/item_manager.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "physics/physics.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/helpers.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/profiler.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN2(a, b) ((a) > (b) ? (b) : (a))
|
||||
|
||||
static LightShader::PointLightInfo PointLightsInfo[MAXLIGHT];
|
||||
|
||||
static void renderPointLights(unsigned count)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
glUseProgram(LightShader::PointLightShader::Program);
|
||||
glBindVertexArray(LightShader::PointLightShader::vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, LightShader::PointLightShader::vbo);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(LightShader::PointLightInfo), PointLightsInfo);
|
||||
|
||||
setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
LightShader::PointLightShader
|
||||
::setUniforms(core::vector2df(float(UserConfigParams::m_width),
|
||||
float(UserConfigParams::m_height)),
|
||||
200, 0, 1);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
|
||||
}
|
||||
|
||||
unsigned IrrDriver::UpdateLightsInfo(scene::ICameraSceneNode * const camnode, float dt)
|
||||
{
|
||||
const u32 lightcount = m_lights.size();
|
||||
const core::vector3df &campos = camnode->getAbsolutePosition();
|
||||
|
||||
std::vector<LightNode *> BucketedLN[15];
|
||||
for (unsigned int i = 0; i < lightcount; i++)
|
||||
{
|
||||
if (!m_lights[i]->isPointLight())
|
||||
{
|
||||
m_lights[i]->render();
|
||||
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;
|
||||
|
||||
for (unsigned i = 0; i < 15; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < BucketedLN[i].size(); j++)
|
||||
{
|
||||
if (++lightnum >= MAXLIGHT)
|
||||
{
|
||||
LightNode* light_node = BucketedLN[i].at(j);
|
||||
light_node->setEnergyMultiplier(0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
LightNode* light_node = BucketedLN[i].at(j);
|
||||
|
||||
float em = light_node->getEnergyMultiplier();
|
||||
if (em < 1.0f)
|
||||
{
|
||||
light_node->setEnergyMultiplier(std::min(1.0f, em + dt));
|
||||
}
|
||||
|
||||
const core::vector3df &pos = light_node->getAbsolutePosition();
|
||||
PointLightsInfo[lightnum].posX = pos.X;
|
||||
PointLightsInfo[lightnum].posY = pos.Y;
|
||||
PointLightsInfo[lightnum].posZ = pos.Z;
|
||||
|
||||
PointLightsInfo[lightnum].energy = light_node->getEffectiveEnergy();
|
||||
|
||||
const core::vector3df &col = light_node->getColor();
|
||||
PointLightsInfo[lightnum].red = col.X;
|
||||
PointLightsInfo[lightnum].green = col.Y;
|
||||
PointLightsInfo[lightnum].blue = col.Z;
|
||||
|
||||
// Light radius
|
||||
PointLightsInfo[lightnum].radius = light_node->getRadius();
|
||||
}
|
||||
}
|
||||
if (lightnum > MAXLIGHT)
|
||||
{
|
||||
irr_driver->setLastLightBucketDistance(i * 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lightnum++;
|
||||
return lightnum;
|
||||
}
|
||||
|
||||
void IrrDriver::renderLights(unsigned pointlightcount)
|
||||
{
|
||||
//RH
|
||||
if (UserConfigParams::m_gi)
|
||||
{
|
||||
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_RH));
|
||||
glDisable(GL_BLEND);
|
||||
m_rtts->getRH().Bind();
|
||||
glUseProgram(FullScreenShader::RadianceHintsConstructionShader::Program);
|
||||
glBindVertexArray(FullScreenShader::RadianceHintsConstructionShader::vao);
|
||||
setTexture(0, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(1, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(2, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::RadianceHintsConstructionShader::setUniforms(rsm_matrix, rh_matrix, rh_extend, 0, 1, 2);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
|
||||
sun_ortho_matrix[i] *= getInvViewMatrix();
|
||||
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
glClearColor(.5, .5, .5, .5);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
return;
|
||||
|
||||
m_rtts->getFBO(FBO_TMP1_WITH_DS).Bind();
|
||||
if (UserConfigParams::m_gi)
|
||||
{
|
||||
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_GI));
|
||||
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
|
||||
}
|
||||
|
||||
if (SkyboxCubeMap)
|
||||
{
|
||||
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_ENVMAP));
|
||||
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
}
|
||||
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
|
||||
|
||||
if (World::getWorld() && World::getWorld()->getTrack()->hasShadows() && SkyboxCubeMap)
|
||||
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
|
||||
|
||||
// Render sunlight if and only if track supports shadow
|
||||
if (!World::getWorld() || World::getWorld()->getTrack()->hasShadows())
|
||||
{
|
||||
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_SUN));
|
||||
if (World::getWorld() && UserConfigParams::m_shadows)
|
||||
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
|
||||
else
|
||||
m_post_processing->renderSunlight();
|
||||
}
|
||||
{
|
||||
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_POINTLIGHTS));
|
||||
renderPointLights(MIN2(pointlightcount, MAXLIGHT));
|
||||
}
|
||||
}
|
||||
|
||||
void IrrDriver::renderSSAO()
|
||||
{
|
||||
m_rtts->getFBO(FBO_SSAO).Bind();
|
||||
glClearColor(1., 1., 1., 1.);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
m_post_processing->renderSSAO();
|
||||
// Blur it to reduce noise.
|
||||
FrameBuffer::Blit(m_rtts->getFBO(FBO_SSAO), m_rtts->getFBO(FBO_HALF1_R), GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
m_post_processing->renderGaussian17TapBlur(irr_driver->getFBO(FBO_HALF1_R), irr_driver->getFBO(FBO_HALF2_R));
|
||||
|
||||
}
|
540
src/graphics/render_skybox.cpp
Normal file
540
src/graphics/render_skybox.cpp
Normal file
@ -0,0 +1,540 @@
|
||||
#include "graphics/irr_driver.hpp"
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/callbacks.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/lens_flare.hpp"
|
||||
#include "graphics/light.hpp"
|
||||
#include "graphics/lod_node.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/particle_kind_manager.hpp"
|
||||
#include "graphics/per_camera_node.hpp"
|
||||
#include "graphics/post_processing.hpp"
|
||||
#include "graphics/referee.hpp"
|
||||
#include "graphics/rtts.hpp"
|
||||
#include "graphics/screenquad.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/stkmeshscenenode.hpp"
|
||||
#include "graphics/stkinstancedscenenode.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "items/item.hpp"
|
||||
#include "items/item_manager.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "physics/physics.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/helpers.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/profiler.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN2(a, b) ((a) > (b) ? (b) : (a))
|
||||
|
||||
static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z)
|
||||
{
|
||||
switch (face)
|
||||
{
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
x = 1.;
|
||||
y = -i;
|
||||
z = -j;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
x = -1.;
|
||||
y = -i;
|
||||
z = j;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
x = j;
|
||||
y = 1.;
|
||||
z = i;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
x = j;
|
||||
y = -1;
|
||||
z = -i;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
x = j;
|
||||
y = -i;
|
||||
z = 1;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
x = -j;
|
||||
y = -i;
|
||||
z = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
float norm = sqrt(x * x + y * y + z * z);
|
||||
x /= norm, y /= norm, z /= norm;
|
||||
return;
|
||||
}
|
||||
|
||||
static void getYml(GLenum face, size_t width, size_t height,
|
||||
float *Y00,
|
||||
float *Y1minus1, float *Y10, float *Y11,
|
||||
float *Y2minus2, float *Y2minus1, float *Y20, float *Y21, float *Y22)
|
||||
{
|
||||
for (unsigned i = 0; i < width; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < height; j++)
|
||||
{
|
||||
float x, y, z;
|
||||
float fi = float(i), fj = float(j);
|
||||
fi /= width, fj /= height;
|
||||
fi = 2 * fi - 1, fj = 2 * fj - 1;
|
||||
getXYZ(face, fi, fj, x, y, z);
|
||||
|
||||
// constant part of Ylm
|
||||
float c00 = 0.282095f;
|
||||
float c1minus1 = 0.488603f;
|
||||
float c10 = 0.488603f;
|
||||
float c11 = 0.488603f;
|
||||
float c2minus2 = 1.092548f;
|
||||
float c2minus1 = 1.092548f;
|
||||
float c21 = 1.092548f;
|
||||
float c20 = 0.315392f;
|
||||
float c22 = 0.546274f;
|
||||
|
||||
size_t idx = i * height + j;
|
||||
|
||||
Y00[idx] = c00;
|
||||
Y1minus1[idx] = c1minus1 * y;
|
||||
Y10[idx] = c10 * z;
|
||||
Y11[idx] = c11 * x;
|
||||
Y2minus2[idx] = c2minus2 * x * y;
|
||||
Y2minus1[idx] = c2minus1 * y * z;
|
||||
Y21[idx] = c21 * x * z;
|
||||
Y20[idx] = c20 * (3 * z * z - 1);
|
||||
Y22[idx] = c22 * (x * x - y * y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static float getTexelValue(unsigned i, unsigned j, size_t width, size_t height, float *Coeff, float *Y00, float *Y1minus1, float *Y10, float *Y11,
|
||||
float *Y2minus2, float * Y2minus1, float * Y20, float *Y21, float *Y22)
|
||||
{
|
||||
float d = sqrt((float)(i * i + j * j + 1));
|
||||
float solidangle = 1.;
|
||||
size_t idx = i * height + j;
|
||||
float reconstructedVal = Y00[idx] * Coeff[0];
|
||||
reconstructedVal += Y1minus1[i * height + j] * Coeff[1] + Y10[i * height + j] * Coeff[2] + Y11[i * height + j] * Coeff[3];
|
||||
reconstructedVal += Y2minus2[idx] * Coeff[4] + Y2minus1[idx] * Coeff[5] + Y20[idx] * Coeff[6] + Y21[idx] * Coeff[7] + Y22[idx] * Coeff[8];
|
||||
reconstructedVal /= solidangle;
|
||||
return MAX2(255.0f * reconstructedVal, 0.f);
|
||||
}
|
||||
|
||||
static void unprojectSH(float *output[], size_t width, size_t height,
|
||||
float *Y00[],
|
||||
float *Y1minus1[], float *Y10[], float *Y11[],
|
||||
float *Y2minus2[], float *Y2minus1[], float * Y20[], float *Y21[], float *Y22[],
|
||||
float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff)
|
||||
{
|
||||
for (unsigned face = 0; face < 6; face++)
|
||||
{
|
||||
for (unsigned i = 0; i < width; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < height; j++)
|
||||
{
|
||||
float fi = float(i), fj = float(j);
|
||||
fi /= width, fj /= height;
|
||||
fi = 2 * fi - 1, fj = 2 * fj - 1;
|
||||
|
||||
output[face][4 * height * i + 4 * j + 2] = getTexelValue(i, j, width, height,
|
||||
redSHCoeff,
|
||||
Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
|
||||
output[face][4 * height * i + 4 * j + 1] = getTexelValue(i, j, width, height,
|
||||
greenSHCoeff,
|
||||
Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
|
||||
output[face][4 * height * i + 4 * j] = getTexelValue(i, j, width, height,
|
||||
blueSHCoeff,
|
||||
Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void projectSH(float *color[], size_t width, size_t height,
|
||||
float *Y00[],
|
||||
float *Y1minus1[], float *Y10[], float *Y11[],
|
||||
float *Y2minus2[], float *Y2minus1[], float * Y20[], float *Y21[], float *Y22[],
|
||||
float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff
|
||||
)
|
||||
{
|
||||
for (unsigned i = 0; i < 9; i++)
|
||||
{
|
||||
blueSHCoeff[i] = 0;
|
||||
greenSHCoeff[i] = 0;
|
||||
redSHCoeff[i] = 0;
|
||||
}
|
||||
float wh = float(width * height);
|
||||
for (unsigned face = 0; face < 6; face++)
|
||||
{
|
||||
for (unsigned i = 0; i < width; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < height; j++)
|
||||
{
|
||||
size_t idx = i * height + j;
|
||||
float fi = float(i), fj = float(j);
|
||||
fi /= width, fj /= height;
|
||||
fi = 2 * fi - 1, fj = 2 * fj - 1;
|
||||
|
||||
|
||||
float d = sqrt(fi * fi + fj * fj + 1);
|
||||
|
||||
// Constant obtained by projecting unprojected ref values
|
||||
float solidangle = 2.75f / (wh * pow(d, 1.5f));
|
||||
// pow(., 2.2) to convert from srgb
|
||||
float b = pow(color[face][4 * height * i + 4 * j] / 255.f, 2.2f);
|
||||
float g = pow(color[face][4 * height * i + 4 * j + 1] / 255.f, 2.2f);
|
||||
float r = pow(color[face][4 * height * i + 4 * j + 2] / 255.f, 2.2f);
|
||||
|
||||
assert(b >= 0.);
|
||||
|
||||
blueSHCoeff[0] += b * Y00[face][idx] * solidangle;
|
||||
blueSHCoeff[1] += b * Y1minus1[face][idx] * solidangle;
|
||||
blueSHCoeff[2] += b * Y10[face][idx] * solidangle;
|
||||
blueSHCoeff[3] += b * Y11[face][idx] * solidangle;
|
||||
blueSHCoeff[4] += b * Y2minus2[face][idx] * solidangle;
|
||||
blueSHCoeff[5] += b * Y2minus1[face][idx] * solidangle;
|
||||
blueSHCoeff[6] += b * Y20[face][idx] * solidangle;
|
||||
blueSHCoeff[7] += b * Y21[face][idx] * solidangle;
|
||||
blueSHCoeff[8] += b * Y22[face][idx] * solidangle;
|
||||
|
||||
greenSHCoeff[0] += g * Y00[face][idx] * solidangle;
|
||||
greenSHCoeff[1] += g * Y1minus1[face][idx] * solidangle;
|
||||
greenSHCoeff[2] += g * Y10[face][idx] * solidangle;
|
||||
greenSHCoeff[3] += g * Y11[face][idx] * solidangle;
|
||||
greenSHCoeff[4] += g * Y2minus2[face][idx] * solidangle;
|
||||
greenSHCoeff[5] += g * Y2minus1[face][idx] * solidangle;
|
||||
greenSHCoeff[6] += g * Y20[face][idx] * solidangle;
|
||||
greenSHCoeff[7] += g * Y21[face][idx] * solidangle;
|
||||
greenSHCoeff[8] += g * Y22[face][idx] * solidangle;
|
||||
|
||||
|
||||
redSHCoeff[0] += r * Y00[face][idx] * solidangle;
|
||||
redSHCoeff[1] += r * Y1minus1[face][idx] * solidangle;
|
||||
redSHCoeff[2] += r * Y10[face][idx] * solidangle;
|
||||
redSHCoeff[3] += r * Y11[face][idx] * solidangle;
|
||||
redSHCoeff[4] += r * Y2minus2[face][idx] * solidangle;
|
||||
redSHCoeff[5] += r * Y2minus1[face][idx] * solidangle;
|
||||
redSHCoeff[6] += r * Y20[face][idx] * solidangle;
|
||||
redSHCoeff[7] += r * Y21[face][idx] * solidangle;
|
||||
redSHCoeff[8] += r * Y22[face][idx] * solidangle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void displayCoeff(float *SHCoeff)
|
||||
{
|
||||
printf("L00:%f\n", SHCoeff[0]);
|
||||
printf("L1-1:%f, L10:%f, L11:%f\n", SHCoeff[1], SHCoeff[2], SHCoeff[3]);
|
||||
printf("L2-2:%f, L2-1:%f, L20:%f, L21:%f, L22:%f\n", SHCoeff[4], SHCoeff[5], SHCoeff[6], SHCoeff[7], SHCoeff[8]);
|
||||
}
|
||||
|
||||
// Only for 9 coefficients
|
||||
static void testSH(unsigned char *color[6], size_t width, size_t height,
|
||||
float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff)
|
||||
{
|
||||
float *Y00[6];
|
||||
float *Y1minus1[6];
|
||||
float *Y10[6];
|
||||
float *Y11[6];
|
||||
float *Y2minus2[6];
|
||||
float *Y2minus1[6];
|
||||
float *Y20[6];
|
||||
float *Y21[6];
|
||||
float *Y22[6];
|
||||
|
||||
float *testoutput[6];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
testoutput[i] = new float[width * height * 4];
|
||||
for (unsigned j = 0; j < width * height; j++)
|
||||
{
|
||||
testoutput[i][4 * j] = float(0xFF & color[i][4 * j]);
|
||||
testoutput[i][4 * j + 1] = float(0xFF & color[i][4 * j + 1]);
|
||||
testoutput[i][4 * j + 2] = float(0xFF & color[i][4 * j + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned face = 0; face < 6; face++)
|
||||
{
|
||||
Y00[face] = new float[width * height];
|
||||
Y1minus1[face] = new float[width * height];
|
||||
Y10[face] = new float[width * height];
|
||||
Y11[face] = new float[width * height];
|
||||
Y2minus2[face] = new float[width * height];
|
||||
Y2minus1[face] = new float[width * height];
|
||||
Y20[face] = new float[width * height];
|
||||
Y21[face] = new float[width * height];
|
||||
Y22[face] = new float[width * height];
|
||||
|
||||
getYml(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, width, height, Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
|
||||
}
|
||||
|
||||
/* blueSHCoeff[0] = 0.54,
|
||||
blueSHCoeff[1] = .6, blueSHCoeff[2] = -.27, blueSHCoeff[3] = .01,
|
||||
blueSHCoeff[4] = -.12, blueSHCoeff[5] = -.47, blueSHCoeff[6] = -.15, blueSHCoeff[7] = .14, blueSHCoeff[8] = -.3;
|
||||
greenSHCoeff[0] = .44,
|
||||
greenSHCoeff[1] = .35, greenSHCoeff[2] = -.18, greenSHCoeff[3] = -.06,
|
||||
greenSHCoeff[4] = -.05, greenSHCoeff[5] = -.22, greenSHCoeff[6] = -.09, greenSHCoeff[7] = .21, greenSHCoeff[8] = -.05;
|
||||
redSHCoeff[0] = .79,
|
||||
redSHCoeff[1] = .39, redSHCoeff[2] = -.34, redSHCoeff[3] = -.29,
|
||||
redSHCoeff[4] = -.11, redSHCoeff[5] = -.26, redSHCoeff[6] = -.16, redSHCoeff[7] = .56, redSHCoeff[8] = .21;
|
||||
|
||||
printf("Blue:\n");
|
||||
displayCoeff(blueSHCoeff);
|
||||
printf("Green:\n");
|
||||
displayCoeff(greenSHCoeff);
|
||||
printf("Red:\n");
|
||||
displayCoeff(redSHCoeff);*/
|
||||
|
||||
projectSH(testoutput, width, height,
|
||||
Y00,
|
||||
Y1minus1, Y10, Y11,
|
||||
Y2minus2, Y2minus1, Y20, Y21, Y22,
|
||||
blueSHCoeff, greenSHCoeff, redSHCoeff
|
||||
);
|
||||
|
||||
//printf("Blue:\n");
|
||||
//displayCoeff(blueSHCoeff);
|
||||
//printf("Green:\n");
|
||||
//displayCoeff(greenSHCoeff);
|
||||
//printf("Red:\n");
|
||||
//displayCoeff(redSHCoeff);
|
||||
|
||||
|
||||
|
||||
// Convolute in frequency space
|
||||
/* float A0 = 3.141593;
|
||||
float A1 = 2.094395;
|
||||
float A2 = 0.785398;
|
||||
blueSHCoeff[0] *= A0;
|
||||
greenSHCoeff[0] *= A0;
|
||||
redSHCoeff[0] *= A0;
|
||||
for (unsigned i = 0; i < 3; i++)
|
||||
{
|
||||
blueSHCoeff[1 + i] *= A1;
|
||||
greenSHCoeff[1 + i] *= A1;
|
||||
redSHCoeff[1 + i] *= A1;
|
||||
}
|
||||
for (unsigned i = 0; i < 5; i++)
|
||||
{
|
||||
blueSHCoeff[4 + i] *= A2;
|
||||
greenSHCoeff[4 + i] *= A2;
|
||||
redSHCoeff[4 + i] *= A2;
|
||||
}
|
||||
|
||||
|
||||
unprojectSH(testoutput, width, height,
|
||||
Y00,
|
||||
Y1minus1, Y10, Y11,
|
||||
Y2minus2, Y2minus1, Y20, Y21, Y22,
|
||||
blueSHCoeff, greenSHCoeff, redSHCoeff
|
||||
);*/
|
||||
|
||||
|
||||
/* printf("Blue:\n");
|
||||
displayCoeff(blueSHCoeff);
|
||||
printf("Green:\n");
|
||||
displayCoeff(greenSHCoeff);
|
||||
printf("Red:\n");
|
||||
displayCoeff(redSHCoeff);
|
||||
|
||||
printf("\nAfter projection\n\n");*/
|
||||
|
||||
|
||||
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < width * height; j++)
|
||||
{
|
||||
color[i][4 * j] = char(MIN2(testoutput[i][4 * j], 255));
|
||||
color[i][4 * j + 1] = char(MIN2(testoutput[i][4 * j + 1], 255));
|
||||
color[i][4 * j + 2] = char(MIN2(testoutput[i][4 * j + 2], 255));
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned face = 0; face < 6; face++)
|
||||
{
|
||||
delete[] testoutput[face];
|
||||
delete[] Y00[face];
|
||||
delete[] Y1minus1[face];
|
||||
delete[] Y10[face];
|
||||
delete[] Y11[face];
|
||||
}
|
||||
}
|
||||
|
||||
/** Generate an opengl cubemap texture from 6 2d textures.
|
||||
Out of legacy the sequence of textures maps to :
|
||||
- 1st texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_Y
|
||||
- 2nd texture maps to GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
|
||||
- 3rd texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_X
|
||||
- 4th texture maps to GL_TEXTURE_CUBE_MAP_NEGATIVE_X
|
||||
- 5th texture maps to GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
|
||||
- 6th texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_Z
|
||||
* \param textures sequence of 6 textures.
|
||||
*/
|
||||
GLuint generateCubeMapFromTextures(const std::vector<video::ITexture *> &textures)
|
||||
{
|
||||
assert(textures.size() == 6);
|
||||
|
||||
GLuint result;
|
||||
glGenTextures(1, &result);
|
||||
|
||||
unsigned w = 0, h = 0;
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
w = MAX2(w, textures[i]->getOriginalSize().Width);
|
||||
h = MAX2(h, textures[i]->getOriginalSize().Height);
|
||||
}
|
||||
|
||||
const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 };
|
||||
char *rgba[6];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
rgba[i] = new char[w * h * 4];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
unsigned idx = texture_permutation[i];
|
||||
|
||||
video::IImage* image = irr_driver->getVideoDriver()->createImageFromData(
|
||||
textures[idx]->getColorFormat(),
|
||||
textures[idx]->getSize(),
|
||||
textures[idx]->lock(),
|
||||
false
|
||||
);
|
||||
textures[idx]->unlock();
|
||||
|
||||
image->copyToScaling(rgba[i], w, h);
|
||||
image->drop();
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, result);
|
||||
if (UserConfigParams::m_texture_compression)
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_COMPRESSED_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
|
||||
else
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
|
||||
}
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
delete[] rgba[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
void IrrDriver::generateSkyboxCubemap()
|
||||
{
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
|
||||
assert(SkyboxTextures.size() == 6);
|
||||
SkyboxCubeMap = generateCubeMapFromTextures(SkyboxTextures);
|
||||
const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 };
|
||||
|
||||
if (SphericalHarmonicsTextures.size() == 6)
|
||||
{
|
||||
unsigned sh_w = 0, sh_h = 0;
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
sh_w = MAX2(sh_w, SphericalHarmonicsTextures[i]->getOriginalSize().Width);
|
||||
sh_h = MAX2(sh_h, SphericalHarmonicsTextures[i]->getOriginalSize().Height);
|
||||
}
|
||||
|
||||
unsigned char *sh_rgba[6];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
sh_rgba[i] = new unsigned char[sh_w * sh_h * 4];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
unsigned idx = texture_permutation[i];
|
||||
|
||||
video::IImage* image = getVideoDriver()->createImageFromData(
|
||||
SphericalHarmonicsTextures[idx]->getColorFormat(),
|
||||
SphericalHarmonicsTextures[idx]->getSize(),
|
||||
SphericalHarmonicsTextures[idx]->lock(),
|
||||
false
|
||||
);
|
||||
SphericalHarmonicsTextures[idx]->unlock();
|
||||
|
||||
image->copyToScaling(sh_rgba[i], sh_w, sh_h);
|
||||
image->drop();
|
||||
}
|
||||
|
||||
testSH(sh_rgba, sh_w, sh_h, blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
delete[] sh_rgba[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
int sh_w = 16;
|
||||
int sh_h = 16;
|
||||
|
||||
const video::SColorf& ambientf = irr_driver->getSceneManager()->getAmbientLight();
|
||||
video::SColor ambient = ambientf.toSColor();
|
||||
|
||||
unsigned char *sh_rgba[6];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
sh_rgba[i] = new unsigned char[sh_w * sh_h * 4];
|
||||
|
||||
for (int j = 0; j < sh_w * sh_h * 4; j += 4)
|
||||
{
|
||||
sh_rgba[i][j] = ambient.getBlue();
|
||||
sh_rgba[i][j + 1] = ambient.getGreen();
|
||||
sh_rgba[i][j + 2] = ambient.getRed();
|
||||
sh_rgba[i][j + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
testSH(sh_rgba, sh_w, sh_h, blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
delete[] sh_rgba[i];
|
||||
}
|
||||
|
||||
/*for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, ConvolutedSkyboxCubeMap);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);*/
|
||||
}
|
||||
|
||||
void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
|
||||
{
|
||||
if (SkyboxTextures.empty())
|
||||
return;
|
||||
if (!SkyboxCubeMap)
|
||||
generateSkyboxCubemap();
|
||||
glBindVertexArray(MeshShader::SkyboxShader::cubevao);
|
||||
glDisable(GL_CULL_FACE);
|
||||
assert(SkyboxTextures.size() == 6);
|
||||
|
||||
core::matrix4 translate;
|
||||
translate.setTranslation(camera->getAbsolutePosition());
|
||||
|
||||
// Draw the sky box between the near and far clip plane
|
||||
const f32 viewDistance = (camera->getNearValue() + camera->getFarValue()) * 0.5f;
|
||||
core::matrix4 scale;
|
||||
scale.setScale(core::vector3df(viewDistance, viewDistance, viewDistance));
|
||||
core::matrix4 transform = translate * scale;
|
||||
core::matrix4 invtransform;
|
||||
transform.getInverse(invtransform);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, SkyboxCubeMap);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glUseProgram(MeshShader::SkyboxShader::Program);
|
||||
MeshShader::SkyboxShader::setUniforms(transform,
|
||||
core::vector2df(float(UserConfigParams::m_width),
|
||||
float(UserConfigParams::m_height)),
|
||||
0);
|
||||
glDrawElements(GL_TRIANGLES, 6 * 6, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
@ -328,13 +328,13 @@ void Shaders::loadShaders()
|
||||
MeshShader::NormalMapShaderInstance = new MeshShader::NormalMapShader();
|
||||
MeshShader::ObjectPass1ShaderInstance = new MeshShader::ObjectPass1Shader();
|
||||
MeshShader::ObjectRefPass1ShaderInstance = new MeshShader::ObjectRefPass1Shader();
|
||||
MeshShader::InstancedObjectPass1Shader::init();
|
||||
MeshShader::InstancedObjectRefPass1Shader::init();
|
||||
MeshShader::InstancedGrassPass1Shader::init();
|
||||
MeshShader::InstancedObjectPass1ShaderInstance = new MeshShader::InstancedObjectPass1Shader();
|
||||
MeshShader::InstancedObjectRefPass1ShaderInstance = new MeshShader::InstancedObjectRefPass1Shader();
|
||||
MeshShader::InstancedGrassPass1ShaderInstance = new MeshShader::InstancedGrassPass1Shader();
|
||||
MeshShader::ObjectPass2ShaderInstance = new MeshShader::ObjectPass2Shader();
|
||||
MeshShader::InstancedObjectPass2Shader::init();
|
||||
MeshShader::InstancedObjectRefPass2Shader::init();
|
||||
MeshShader::InstancedGrassPass2Shader::init();
|
||||
MeshShader::InstancedObjectPass2ShaderInstance = new MeshShader::InstancedObjectPass2Shader();
|
||||
MeshShader::InstancedObjectRefPass2ShaderInstance = new MeshShader::InstancedObjectRefPass2Shader();
|
||||
MeshShader::InstancedGrassPass2ShaderInstance = new MeshShader::InstancedGrassPass2Shader();
|
||||
MeshShader::DetailledObjectPass2ShaderInstance = new MeshShader::DetailledObjectPass2Shader();
|
||||
MeshShader::ObjectRefPass2ShaderInstance = new MeshShader::ObjectRefPass2Shader();
|
||||
MeshShader::ObjectUnlitShaderInstance = new MeshShader::ObjectUnlitShader();
|
||||
@ -347,14 +347,15 @@ void Shaders::loadShaders()
|
||||
MeshShader::TransparentFogShaderInstance = new MeshShader::TransparentFogShader();
|
||||
MeshShader::BillboardShader::init();
|
||||
LightShader::PointLightShader::init();
|
||||
MeshShader::DisplaceShader::init();
|
||||
MeshShader::DisplaceMaskShader::init();
|
||||
MeshShader::DisplaceShaderInstance = new MeshShader::DisplaceShader();
|
||||
MeshShader::DisplaceMaskShaderInstance = new MeshShader::DisplaceMaskShader();
|
||||
MeshShader::ShadowShaderInstance = new MeshShader::ShadowShader();
|
||||
MeshShader::RSMShader::init();
|
||||
MeshShader::InstancedShadowShader::init();
|
||||
MeshShader::InstancedShadowShaderInstance = new MeshShader::InstancedShadowShader();
|
||||
MeshShader::RefShadowShaderInstance = new MeshShader::RefShadowShader();
|
||||
MeshShader::InstancedRefShadowShader::init();
|
||||
MeshShader::InstancedRefShadowShaderInstance = new MeshShader::InstancedRefShadowShader();
|
||||
MeshShader::GrassShadowShaderInstance = new MeshShader::GrassShadowShader();
|
||||
MeshShader::InstancedGrassShadowShaderInstance = new MeshShader::InstancedGrassShadowShader();
|
||||
MeshShader::SkyboxShader::init();
|
||||
MeshShader::ViewFrustrumShader::init();
|
||||
ParticleShader::FlipParticleRender::init();
|
||||
@ -474,6 +475,11 @@ void glUniform3fWraper(GLuint a, float b, float c, float d)
|
||||
glUniform3f(a, b, c, d);
|
||||
}
|
||||
|
||||
void glUniform2fWraper(GLuint a, float b, float c)
|
||||
{
|
||||
glUniform2f(a, b, c);
|
||||
}
|
||||
|
||||
void glUniform1fWrapper(GLuint a, float b)
|
||||
{
|
||||
glUniform1f(a, b);
|
||||
@ -548,17 +554,15 @@ namespace MeshShader
|
||||
}
|
||||
NormalMapShader *NormalMapShaderInstance;
|
||||
|
||||
GLuint InstancedObjectPass1Shader::Program;
|
||||
GLuint InstancedObjectPass1Shader::uniform_tex;
|
||||
|
||||
void InstancedObjectPass1Shader::init()
|
||||
InstancedObjectPass1Shader::InstancedObjectPass1Shader()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass1.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
TU_tex = 0;
|
||||
AssignTextureUnit(Program, { { TU_tex, "tex" } });
|
||||
if (!UserConfigParams::m_ubo_disabled)
|
||||
{
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
@ -566,24 +570,17 @@ namespace MeshShader
|
||||
}
|
||||
}
|
||||
|
||||
void InstancedObjectPass1Shader::setUniforms(unsigned TU_tex)
|
||||
{
|
||||
if (UserConfigParams::m_ubo_disabled)
|
||||
bypassUBO(Program);
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
}
|
||||
InstancedObjectPass1Shader *InstancedObjectPass1ShaderInstance;
|
||||
|
||||
GLuint InstancedObjectRefPass1Shader::Program;
|
||||
GLuint InstancedObjectRefPass1Shader::uniform_tex;
|
||||
|
||||
void InstancedObjectRefPass1Shader::init()
|
||||
InstancedObjectRefPass1Shader::InstancedObjectRefPass1Shader()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass1.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
TU_tex = 0;
|
||||
AssignTextureUnit(Program, { { TU_tex, "tex" } });
|
||||
if (!UserConfigParams::m_ubo_disabled)
|
||||
{
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
@ -591,26 +588,18 @@ namespace MeshShader
|
||||
}
|
||||
}
|
||||
|
||||
void InstancedObjectRefPass1Shader::setUniforms(unsigned TU_tex)
|
||||
{
|
||||
if (UserConfigParams::m_ubo_disabled)
|
||||
bypassUBO(Program);
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
}
|
||||
InstancedObjectRefPass1Shader *InstancedObjectRefPass1ShaderInstance;
|
||||
|
||||
GLuint InstancedGrassPass1Shader::Program;
|
||||
GLuint InstancedGrassPass1Shader::uniform_windDir;
|
||||
GLuint InstancedGrassPass1Shader::uniform_tex;
|
||||
|
||||
void InstancedGrassPass1Shader::init()
|
||||
InstancedGrassPass1Shader::InstancedGrassPass1Shader()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_grass.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass1.frag").c_str());
|
||||
uniform_windDir = glGetUniformLocation(Program, "windDir");
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
AssignUniforms(Program, uniforms, { "windDir" });
|
||||
TU_tex = 0;
|
||||
AssignTextureUnit(Program, { { TU_tex, "tex" } });
|
||||
if (!UserConfigParams::m_ubo_disabled)
|
||||
{
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
@ -618,13 +607,7 @@ namespace MeshShader
|
||||
}
|
||||
}
|
||||
|
||||
void InstancedGrassPass1Shader::setUniforms(const core::vector3df &windDir, unsigned TU_tex)
|
||||
{
|
||||
if (UserConfigParams::m_ubo_disabled)
|
||||
bypassUBO(Program);
|
||||
glUniform3f(uniform_windDir, windDir.X, windDir.Y, windDir.Z);
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
}
|
||||
InstancedGrassPass1Shader *InstancedGrassPass1ShaderInstance;
|
||||
|
||||
// Solid Lit pass shaders
|
||||
ObjectPass2Shader::ObjectPass2Shader()
|
||||
@ -646,22 +629,14 @@ namespace MeshShader
|
||||
|
||||
ObjectPass2Shader *ObjectPass2ShaderInstance;
|
||||
|
||||
GLuint InstancedObjectPass2Shader::Program;
|
||||
GLuint InstancedObjectPass2Shader::uniform_VP;
|
||||
GLuint InstancedObjectPass2Shader::uniform_TM;
|
||||
GLuint InstancedObjectPass2Shader::uniform_ambient;
|
||||
GLuint InstancedObjectPass2Shader::TU_Albedo;
|
||||
|
||||
void InstancedObjectPass2Shader::init()
|
||||
InstancedObjectPass2Shader::InstancedObjectPass2Shader()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass2.frag").c_str());
|
||||
uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix");
|
||||
uniform_TM = glGetUniformLocation(Program, "TextureMatrix");
|
||||
uniform_ambient = glGetUniformLocation(Program, "ambient");
|
||||
AssignUniforms(Program, uniforms, { "ambient" });
|
||||
TU_Albedo = 3;
|
||||
|
||||
AssignTextureUnit(Program, { { 0, "DiffuseMap" }, { 1, "SpecularMap" }, { 2, "SSAO" }, { TU_Albedo, "Albedo" } });
|
||||
@ -673,32 +648,16 @@ namespace MeshShader
|
||||
}
|
||||
}
|
||||
|
||||
void InstancedObjectPass2Shader::setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &TextureMatrix)
|
||||
{
|
||||
if (UserConfigParams::m_ubo_disabled)
|
||||
bypassUBO(Program);
|
||||
glUniformMatrix4fv(uniform_VP, 1, GL_FALSE, ViewProjectionMatrix.pointer());
|
||||
glUniformMatrix4fv(uniform_TM, 1, GL_FALSE, TextureMatrix.pointer());
|
||||
const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight();
|
||||
glUniform3f(uniform_ambient, s.r, s.g, s.b);
|
||||
}
|
||||
InstancedObjectPass2Shader *InstancedObjectPass2ShaderInstance;
|
||||
|
||||
GLuint InstancedObjectRefPass2Shader::Program;
|
||||
GLuint InstancedObjectRefPass2Shader::uniform_VP;
|
||||
GLuint InstancedObjectRefPass2Shader::uniform_TM;
|
||||
GLuint InstancedObjectRefPass2Shader::uniform_ambient;
|
||||
GLuint InstancedObjectRefPass2Shader::TU_Albedo;
|
||||
|
||||
void InstancedObjectRefPass2Shader::init()
|
||||
InstancedObjectRefPass2Shader::InstancedObjectRefPass2Shader()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass2.frag").c_str());
|
||||
uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix");
|
||||
uniform_TM = glGetUniformLocation(Program, "TextureMatrix");
|
||||
uniform_ambient = glGetUniformLocation(Program, "ambient");
|
||||
AssignUniforms(Program, uniforms, { "ambient" });
|
||||
TU_Albedo = 3;
|
||||
|
||||
AssignTextureUnit(Program, { { 0, "DiffuseMap" }, { 1, "SpecularMap" }, { 2, "SSAO" }, { TU_Albedo, "Albedo" } });
|
||||
@ -707,15 +666,7 @@ namespace MeshShader
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
void InstancedObjectRefPass2Shader::setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &TextureMatrix)
|
||||
{
|
||||
if (UserConfigParams::m_ubo_disabled)
|
||||
bypassUBO(Program);
|
||||
glUniformMatrix4fv(uniform_VP, 1, GL_FALSE, ViewProjectionMatrix.pointer());
|
||||
glUniformMatrix4fv(uniform_TM, 1, GL_FALSE, TextureMatrix.pointer());
|
||||
const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight();
|
||||
glUniform3f(uniform_ambient, s.r, s.g, s.b);
|
||||
}
|
||||
InstancedObjectRefPass2Shader *InstancedObjectRefPass2ShaderInstance;
|
||||
|
||||
DetailledObjectPass2Shader::DetailledObjectPass2Shader()
|
||||
{
|
||||
@ -785,29 +736,14 @@ namespace MeshShader
|
||||
|
||||
GrassPass2Shader *GrassPass2ShaderInstance;
|
||||
|
||||
GLuint InstancedGrassPass2Shader::Program;
|
||||
GLuint InstancedGrassPass2Shader::uniform_VP;
|
||||
GLuint InstancedGrassPass2Shader::uniform_ambient;
|
||||
GLuint InstancedGrassPass2Shader::uniform_windDir;
|
||||
GLuint InstancedGrassPass2Shader::uniform_invproj;
|
||||
GLuint InstancedGrassPass2Shader::uniform_IVM;
|
||||
GLuint InstancedGrassPass2Shader::uniform_SunDir;
|
||||
GLuint InstancedGrassPass2Shader::TU_Albedo;
|
||||
GLuint InstancedGrassPass2Shader::TU_dtex;
|
||||
|
||||
void InstancedGrassPass2Shader::init()
|
||||
InstancedGrassPass2Shader::InstancedGrassPass2Shader()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_grass.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/grass_pass2.frag").c_str());
|
||||
uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix");
|
||||
uniform_ambient = glGetUniformLocation(Program, "ambient");
|
||||
uniform_windDir = glGetUniformLocation(Program, "windDir");
|
||||
uniform_invproj = glGetUniformLocation(Program, "invproj");
|
||||
uniform_IVM = glGetUniformLocation(Program, "InverseViewMatrix");
|
||||
uniform_SunDir = glGetUniformLocation(Program, "SunDir");
|
||||
AssignUniforms(Program, uniforms, { "windDir", "SunDir", "ambient" });
|
||||
TU_Albedo = 3;
|
||||
TU_dtex = 4;
|
||||
|
||||
@ -817,19 +753,7 @@ namespace MeshShader
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
void InstancedGrassPass2Shader::setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &InverseViewMatrix, const core::matrix4 &invproj, const core::vector3df &windDirection, const core::vector3df &SunDir)
|
||||
{
|
||||
if (UserConfigParams::m_ubo_disabled)
|
||||
bypassUBO(Program);
|
||||
glUniformMatrix4fv(uniform_VP, 1, GL_FALSE, ViewProjectionMatrix.pointer());
|
||||
glUniformMatrix4fv(uniform_invproj, 1, GL_FALSE, invproj.pointer());
|
||||
glUniformMatrix4fv(uniform_IVM, 1, GL_FALSE, InverseViewMatrix.pointer());
|
||||
glUniform3f(uniform_SunDir, SunDir.X, SunDir.Y, SunDir.Z);
|
||||
const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight();
|
||||
glUniform3f(uniform_ambient, s.r, s.g, s.b);
|
||||
glUniform3f(uniform_windDir, windDirection.X, windDirection.Y, windDirection.Z);
|
||||
}
|
||||
|
||||
InstancedGrassPass2Shader *InstancedGrassPass2ShaderInstance;
|
||||
|
||||
SphereMapShader::SphereMapShader()
|
||||
{
|
||||
@ -1039,9 +963,7 @@ namespace MeshShader
|
||||
glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer());
|
||||
}
|
||||
|
||||
GLuint InstancedShadowShader::Program;
|
||||
|
||||
void InstancedShadowShader::init()
|
||||
InstancedShadowShader::InstancedShadowShader()
|
||||
{
|
||||
// Geometry shader needed
|
||||
if (irr_driver->getGLSLVersion() < 150)
|
||||
@ -1065,9 +987,7 @@ namespace MeshShader
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
void InstancedShadowShader::setUniforms()
|
||||
{
|
||||
}
|
||||
InstancedShadowShader *InstancedShadowShaderInstance;
|
||||
|
||||
RefShadowShader::RefShadowShader()
|
||||
{
|
||||
@ -1097,10 +1017,7 @@ namespace MeshShader
|
||||
|
||||
RefShadowShader *RefShadowShaderInstance;
|
||||
|
||||
GLuint InstancedRefShadowShader::Program;
|
||||
GLuint InstancedRefShadowShader::uniform_tex;
|
||||
|
||||
void InstancedRefShadowShader::init()
|
||||
InstancedRefShadowShader::InstancedRefShadowShader()
|
||||
{
|
||||
// Geometry shader needed
|
||||
if (irr_driver->getGLSLVersion() < 150)
|
||||
@ -1120,15 +1037,13 @@ namespace MeshShader
|
||||
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str());
|
||||
}
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
TU_tex = 0;
|
||||
AssignTextureUnit(Program, { { TU_tex, "tex" } });
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
void InstancedRefShadowShader::setUniforms(unsigned TU_tex)
|
||||
{
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
}
|
||||
InstancedRefShadowShader *InstancedRefShadowShaderInstance;
|
||||
|
||||
GrassShadowShader::GrassShadowShader()
|
||||
{
|
||||
@ -1158,15 +1073,42 @@ namespace MeshShader
|
||||
|
||||
GrassShadowShader *GrassShadowShaderInstance;
|
||||
|
||||
GLuint DisplaceMaskShader::Program;
|
||||
GLuint DisplaceMaskShader::uniform_MVP;
|
||||
InstancedGrassShadowShader::InstancedGrassShadowShader()
|
||||
{
|
||||
// Geometry shader needed
|
||||
if (irr_driver->getGLSLVersion() < 150)
|
||||
return;
|
||||
if (irr_driver->hasVSLayerExtension())
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedgrassshadow.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedgrassshadow.vert").c_str(),
|
||||
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str());
|
||||
}
|
||||
TU_tex = 0;
|
||||
AssignTextureUnit(Program, { { TU_tex, "tex" } });
|
||||
|
||||
void DisplaceMaskShader::init()
|
||||
AssignUniforms(Program, uniforms, { "windDir" });
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
InstancedGrassShadowShader *InstancedGrassShadowShaderInstance;
|
||||
|
||||
DisplaceMaskShader::DisplaceMaskShader()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/displace.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str());
|
||||
uniform_MVP = glGetUniformLocation(Program, "ModelMatrix");
|
||||
AssignUniforms(Program, uniforms, { "ModelMatrix"});
|
||||
if (!UserConfigParams::m_ubo_disabled)
|
||||
{
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
@ -1174,46 +1116,25 @@ namespace MeshShader
|
||||
}
|
||||
}
|
||||
|
||||
void DisplaceMaskShader::setUniforms(const core::matrix4 &ModelMatrix)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelMatrix.pointer());
|
||||
}
|
||||
DisplaceMaskShader *DisplaceMaskShaderInstance;
|
||||
|
||||
GLuint DisplaceShader::Program;
|
||||
GLuint DisplaceShader::uniform_MVP;
|
||||
GLuint DisplaceShader::uniform_displacement_tex;
|
||||
GLuint DisplaceShader::uniform_mask_tex;
|
||||
GLuint DisplaceShader::uniform_color_tex;
|
||||
GLuint DisplaceShader::uniform_tex;
|
||||
GLuint DisplaceShader::uniform_dir;
|
||||
GLuint DisplaceShader::uniform_dir2;
|
||||
|
||||
void DisplaceShader::init()
|
||||
DisplaceShader::DisplaceShader()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/displace.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/displace.frag").c_str());
|
||||
uniform_MVP = glGetUniformLocation(Program, "ModelMatrix");
|
||||
uniform_displacement_tex = glGetUniformLocation(Program, "displacement_tex");
|
||||
uniform_color_tex = glGetUniformLocation(Program, "color_tex");
|
||||
uniform_mask_tex = glGetUniformLocation(Program, "mask_tex");
|
||||
uniform_dir = glGetUniformLocation(Program, "dir");
|
||||
uniform_dir2 = glGetUniformLocation(Program, "dir2");
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
AssignUniforms(Program, uniforms, { "ModelMatrix", "dir", "dir2" });
|
||||
TU_displacement_tex = 0;
|
||||
TU_color_tex = 1;
|
||||
TU_mask_tex = 2;
|
||||
TU_tex = 3;
|
||||
AssignTextureUnit(Program, { { TU_displacement_tex, "displacement_tex" }, { TU_color_tex, "color_tex" }, { TU_mask_tex, "mask_tex" }, { TU_tex, "tex" } });
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
void DisplaceShader::setUniforms(const core::matrix4 &ModelMatrix, const core::vector2df &dir, const core::vector2df &dir2, const core::vector2df &screen, unsigned TU_displacement_tex, unsigned TU_mask_tex, unsigned TU_color_tex, unsigned TU_tex)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelMatrix.pointer());
|
||||
glUniform2f(uniform_dir, dir.X, dir.Y);
|
||||
glUniform2f(uniform_dir2, dir2.X, dir2.Y);
|
||||
glUniform1i(uniform_displacement_tex, TU_displacement_tex);
|
||||
glUniform1i(uniform_mask_tex, TU_mask_tex);
|
||||
glUniform1i(uniform_color_tex, TU_color_tex);
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
}
|
||||
DisplaceShader *DisplaceShaderInstance;
|
||||
|
||||
GLuint SkyboxShader::Program;
|
||||
GLuint SkyboxShader::attrib_position;
|
||||
|
@ -50,11 +50,12 @@ public:
|
||||
|
||||
void glUniformMatrix4fvWraper(GLuint, size_t, unsigned, const float *mat);
|
||||
void glUniform3fWraper(GLuint, float, float, float);
|
||||
void glUniform2fWraper(GLuint a, float b, float c);
|
||||
void glUniform1fWrapper(GLuint, float);
|
||||
|
||||
struct UniformHelper
|
||||
{
|
||||
template<unsigned N>
|
||||
template<unsigned N = 0>
|
||||
static void setUniformsHelper(const std::vector<GLuint> &uniforms)
|
||||
{
|
||||
}
|
||||
@ -83,6 +84,14 @@ struct UniformHelper
|
||||
setUniformsHelper<N + 1>(uniforms, arg...);
|
||||
}
|
||||
|
||||
|
||||
template<unsigned N = 0, typename... Args>
|
||||
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const core::vector2df &v, Args... arg)
|
||||
{
|
||||
glUniform2fWraper(uniforms[N], v.X, v.Y);
|
||||
setUniformsHelper<N + 1>(uniforms, arg...);
|
||||
}
|
||||
|
||||
template<unsigned N = 0, typename... Args>
|
||||
static void setUniformsHelper(const std::vector<GLuint> &uniforms, float f, Args... arg)
|
||||
{
|
||||
@ -150,36 +159,36 @@ public:
|
||||
|
||||
extern NormalMapShader *NormalMapShaderInstance;
|
||||
|
||||
class InstancedObjectPass1Shader
|
||||
class InstancedObjectPass1Shader : public ShaderHelper<>
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_tex;
|
||||
GLuint TU_tex;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(unsigned TU_tex);
|
||||
InstancedObjectPass1Shader();
|
||||
};
|
||||
|
||||
class InstancedObjectRefPass1Shader
|
||||
extern InstancedObjectPass1Shader *InstancedObjectPass1ShaderInstance;
|
||||
|
||||
class InstancedObjectRefPass1Shader : public ShaderHelper<>
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_tex;
|
||||
GLuint TU_tex;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(unsigned TU_tex);
|
||||
InstancedObjectRefPass1Shader();
|
||||
};
|
||||
|
||||
class InstancedGrassPass1Shader
|
||||
extern InstancedObjectRefPass1Shader *InstancedObjectRefPass1ShaderInstance;
|
||||
|
||||
class InstancedGrassPass1Shader : public ShaderHelper<core::vector3df>
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_windDir, uniform_tex;
|
||||
GLuint TU_tex;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::vector3df &windDir, unsigned TU_tex);
|
||||
InstancedGrassPass1Shader();
|
||||
};
|
||||
|
||||
extern InstancedGrassPass1Shader *InstancedGrassPass1ShaderInstance;
|
||||
|
||||
class ObjectPass2Shader : public ShaderHelper<core::matrix4, core::matrix4, video::SColorf>
|
||||
{
|
||||
public:
|
||||
@ -190,28 +199,26 @@ public:
|
||||
|
||||
extern ObjectPass2Shader *ObjectPass2ShaderInstance;
|
||||
|
||||
class InstancedObjectPass2Shader
|
||||
class InstancedObjectPass2Shader : public ShaderHelper<video::SColorf>
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_VP, uniform_TM, uniform_ambient;
|
||||
static GLuint TU_Albedo;
|
||||
GLuint TU_Albedo;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &TextureMatrix);
|
||||
InstancedObjectPass2Shader();
|
||||
};
|
||||
|
||||
class InstancedObjectRefPass2Shader
|
||||
extern InstancedObjectPass2Shader *InstancedObjectPass2ShaderInstance;
|
||||
|
||||
class InstancedObjectRefPass2Shader : public ShaderHelper<video::SColorf>
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_VP, uniform_TM, uniform_ambient;
|
||||
static GLuint TU_Albedo;
|
||||
GLuint TU_Albedo;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &TextureMatrix);
|
||||
InstancedObjectRefPass2Shader();
|
||||
};
|
||||
|
||||
extern InstancedObjectRefPass2Shader *InstancedObjectRefPass2ShaderInstance;
|
||||
|
||||
class DetailledObjectPass2Shader : public ShaderHelper<core::matrix4, video::SColorf>
|
||||
{
|
||||
public:
|
||||
@ -252,17 +259,16 @@ public:
|
||||
|
||||
extern GrassPass2Shader *GrassPass2ShaderInstance;
|
||||
|
||||
class InstancedGrassPass2Shader
|
||||
class InstancedGrassPass2Shader : public ShaderHelper<core::vector3df, core::vector3df, video::SColorf>
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_VP, uniform_TM, uniform_IVM, uniform_ambient, uniform_windDir, uniform_invproj, uniform_SunDir;
|
||||
static GLuint TU_Albedo, TU_dtex;
|
||||
GLuint TU_Albedo, TU_dtex;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &InverseViewMatrix, const core::matrix4 &invproj, const core::vector3df &windDirection, const core::vector3df &SunDir);
|
||||
InstancedGrassPass2Shader();
|
||||
};
|
||||
|
||||
extern InstancedGrassPass2Shader *InstancedGrassPass2ShaderInstance;
|
||||
|
||||
class SphereMapShader : public ShaderHelper<core::matrix4, core::matrix4, video::SColorf>
|
||||
{
|
||||
public:
|
||||
@ -354,15 +360,14 @@ public:
|
||||
static void setUniforms(const core::matrix4 &RSMMatrix, const core::matrix4 &ModelMatrix);
|
||||
};
|
||||
|
||||
class InstancedShadowShader
|
||||
class InstancedShadowShader : public ShaderHelper<>
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
|
||||
static void init();
|
||||
static void setUniforms();
|
||||
InstancedShadowShader();
|
||||
};
|
||||
|
||||
extern InstancedShadowShader *InstancedShadowShaderInstance;
|
||||
|
||||
class RefShadowShader : public ShaderHelper<core::matrix4>
|
||||
{
|
||||
public:
|
||||
@ -373,16 +378,16 @@ public:
|
||||
|
||||
extern RefShadowShader *RefShadowShaderInstance;
|
||||
|
||||
class InstancedRefShadowShader
|
||||
class InstancedRefShadowShader : public ShaderHelper<>
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_tex;
|
||||
GLuint TU_tex;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(unsigned TU_tex);
|
||||
InstancedRefShadowShader();
|
||||
};
|
||||
|
||||
extern InstancedRefShadowShader *InstancedRefShadowShaderInstance;
|
||||
|
||||
class GrassShadowShader : public ShaderHelper<core::matrix4, core::vector3df>
|
||||
{
|
||||
public:
|
||||
@ -392,26 +397,33 @@ public:
|
||||
|
||||
extern GrassShadowShader *GrassShadowShaderInstance;
|
||||
|
||||
class DisplaceMaskShader
|
||||
class InstancedGrassShadowShader : public ShaderHelper<core::vector3df>
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_MVP;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &ModelMatrix);
|
||||
GLuint TU_tex;
|
||||
InstancedGrassShadowShader();
|
||||
};
|
||||
|
||||
class DisplaceShader
|
||||
extern InstancedGrassShadowShader *InstancedGrassShadowShaderInstance;
|
||||
|
||||
class DisplaceMaskShader : public ShaderHelper<core::matrix4>
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_MVP, uniform_displacement_tex, uniform_mask_tex, uniform_color_tex, uniform_tex, uniform_dir, uniform_dir2;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &ModelMatrix, const core::vector2df &dir, const core::vector2df &dir2, const core::vector2df &screen, unsigned TU_displacement_tex, unsigned TU_mask_tex, unsigned TU_color_tex, unsigned TU_tex);
|
||||
DisplaceMaskShader();
|
||||
};
|
||||
|
||||
extern DisplaceMaskShader *DisplaceMaskShaderInstance;
|
||||
|
||||
class DisplaceShader : public ShaderHelper<core::matrix4, core::vector2df, core::vector2df>
|
||||
{
|
||||
public:
|
||||
GLuint TU_displacement_tex, TU_mask_tex, TU_color_tex, TU_tex;
|
||||
|
||||
DisplaceShader();
|
||||
};
|
||||
|
||||
extern DisplaceShader *DisplaceShaderInstance;
|
||||
|
||||
class SkyboxShader
|
||||
{
|
||||
public:
|
||||
|
@ -117,13 +117,13 @@ void STKAnimatedMesh::render()
|
||||
const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
|
||||
if (isObject(material.MaterialType))
|
||||
{
|
||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
|
||||
{
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, getVBO(mb->getVertexType()));
|
||||
glBufferSubData(GL_ARRAY_BUFFER, GLmeshes[i].vaoBaseVertex * GLmeshes[i].Stride, mb->getVertexCount() * GLmeshes[i].Stride, mb->getVertices());
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == TRANSPARENT_PASS)
|
||||
{
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, getVBO(mb->getVertexType()));
|
||||
glBufferSubData(GL_ARRAY_BUFFER, GLmeshes[i].vaoBaseVertex * GLmeshes[i].Stride, mb->getVertexCount() * GLmeshes[i].Stride, mb->getVertices());
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
if (mb)
|
||||
GLmeshes[i].TextureMatrix = getMaterial(i).getTextureMatrix(0);
|
||||
|
@ -131,15 +131,15 @@ static void drawFSPMDefault(GLMesh &mesh, size_t instance_count)
|
||||
if (mesh.textures[0])
|
||||
{
|
||||
compressTexture(mesh.textures[0], true);
|
||||
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
setTexture(MeshShader::InstancedObjectPass1ShaderInstance->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
setTexture(0, 0, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, false);
|
||||
setTexture(MeshShader::InstancedObjectPass1ShaderInstance->TU_tex, 0, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, false);
|
||||
GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ONE };
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
MeshShader::InstancedObjectPass1Shader::setUniforms(0);
|
||||
MeshShader::InstancedObjectPass1ShaderInstance->setUniforms();
|
||||
|
||||
glBindVertexArray(mesh.vao);
|
||||
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
|
||||
@ -158,7 +158,7 @@ static void drawShadowDefault(GLMesh &mesh, size_t instance_count)
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
MeshShader::InstancedShadowShader::setUniforms();
|
||||
MeshShader::InstancedShadowShaderInstance->setUniforms();
|
||||
|
||||
glBindVertexArray(mesh.vao_shadow_pass);
|
||||
glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count);
|
||||
@ -172,8 +172,8 @@ static void drawFSPMAlphaRefTexture(GLMesh &mesh, size_t instance_count)
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
compressTexture(mesh.textures[0], true);
|
||||
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
MeshShader::InstancedObjectRefPass1Shader::setUniforms(0);
|
||||
setTexture(MeshShader::InstancedObjectRefPass1ShaderInstance->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
MeshShader::InstancedObjectRefPass1ShaderInstance->setUniforms();
|
||||
|
||||
glBindVertexArray(mesh.vao);
|
||||
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
|
||||
@ -187,8 +187,23 @@ static void drawShadowAlphaRefTexture(GLMesh &mesh, size_t instance_count)
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
compressTexture(mesh.textures[0], true);
|
||||
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
MeshShader::InstancedRefShadowShader::setUniforms(0);
|
||||
setTexture(MeshShader::InstancedRefShadowShaderInstance->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
MeshShader::InstancedRefShadowShaderInstance->setUniforms();
|
||||
|
||||
glBindVertexArray(mesh.vao_shadow_pass);
|
||||
glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count);
|
||||
}
|
||||
|
||||
static void drawShadowGrass(GLMesh &mesh, const core::vector3df &windDir, size_t instance_count)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
compressTexture(mesh.textures[0], true);
|
||||
setTexture(MeshShader::InstancedGrassShadowShaderInstance->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
MeshShader::InstancedGrassShadowShaderInstance->setUniforms(windDir);
|
||||
|
||||
glBindVertexArray(mesh.vao_shadow_pass);
|
||||
glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count);
|
||||
@ -202,8 +217,8 @@ static void drawFSPMGrass(GLMesh &mesh, const core::vector3df &windDir, size_t i
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
compressTexture(mesh.textures[0], true);
|
||||
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
MeshShader::InstancedGrassPass1Shader::setUniforms(windDir, 0);
|
||||
setTexture(MeshShader::InstancedGrassPass1ShaderInstance->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
MeshShader::InstancedGrassPass1ShaderInstance->setUniforms(windDir);
|
||||
|
||||
glBindVertexArray(mesh.vao);
|
||||
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
|
||||
@ -216,7 +231,7 @@ static void drawSMDefault(GLMesh &mesh, const core::matrix4 &ModelViewProjection
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
setTexture(MeshShader::InstancedObjectPass2Shader::TU_Albedo, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
setTexture(MeshShader::InstancedObjectPass2ShaderInstance->TU_Albedo, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
if (irr_driver->getLightViz())
|
||||
{
|
||||
GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ALPHA };
|
||||
@ -228,7 +243,7 @@ static void drawSMDefault(GLMesh &mesh, const core::matrix4 &ModelViewProjection
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
|
||||
MeshShader::InstancedObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, core::matrix4::EM4CONST_IDENTITY);
|
||||
MeshShader::InstancedObjectPass2ShaderInstance->setUniforms(irr_driver->getSceneManager()->getAmbientLight());
|
||||
|
||||
glBindVertexArray(mesh.vao);
|
||||
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
|
||||
@ -242,7 +257,7 @@ static void drawSMAlphaRefTexture(GLMesh &mesh, const core::matrix4 &ModelViewPr
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
compressTexture(mesh.textures[0], true);
|
||||
setTexture(MeshShader::InstancedObjectRefPass2Shader::TU_Albedo, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
setTexture(MeshShader::InstancedObjectRefPass2ShaderInstance->TU_Albedo, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
if (irr_driver->getLightViz())
|
||||
{
|
||||
GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ALPHA };
|
||||
@ -254,7 +269,7 @@ static void drawSMAlphaRefTexture(GLMesh &mesh, const core::matrix4 &ModelViewPr
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
|
||||
MeshShader::InstancedObjectRefPass2Shader::setUniforms(ModelViewProjectionMatrix, core::matrix4::EM4CONST_IDENTITY);
|
||||
MeshShader::InstancedObjectRefPass2ShaderInstance->setUniforms(irr_driver->getSceneManager()->getAmbientLight());
|
||||
|
||||
glBindVertexArray(mesh.vao);
|
||||
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
|
||||
@ -268,7 +283,7 @@ static void drawSMGrass(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMa
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
compressTexture(mesh.textures[0], true);
|
||||
setTexture(MeshShader::InstancedGrassPass2Shader::TU_Albedo, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
setTexture(MeshShader::InstancedGrassPass2ShaderInstance->TU_Albedo, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
if (irr_driver->getLightViz())
|
||||
{
|
||||
GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ALPHA };
|
||||
@ -279,10 +294,10 @@ static void drawSMGrass(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMa
|
||||
GLint swizzleMask[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
setTexture(MeshShader::InstancedGrassPass2Shader::TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(MeshShader::InstancedGrassPass2ShaderInstance->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
|
||||
|
||||
MeshShader::InstancedGrassPass2Shader::setUniforms(ModelViewProjectionMatrix, irr_driver->getInvViewMatrix(), irr_driver->getInvProjMatrix(), windDir, cb->getPosition());
|
||||
MeshShader::InstancedGrassPass2ShaderInstance->setUniforms(windDir, cb->getPosition(), irr_driver->getSceneManager()->getAmbientLight());
|
||||
|
||||
glBindVertexArray(mesh.vao);
|
||||
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
|
||||
@ -304,18 +319,18 @@ void STKInstancedSceneNode::render()
|
||||
ModelViewProjectionMatrix *= irr_driver->getViewMatrix();
|
||||
|
||||
if (!GeometricMesh[FPSM_DEFAULT_STANDARD].empty())
|
||||
glUseProgram(MeshShader::InstancedObjectPass1Shader::Program);
|
||||
glUseProgram(MeshShader::InstancedObjectPass1ShaderInstance->Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT_STANDARD].size(); i++)
|
||||
drawFSPMDefault(*GeometricMesh[FPSM_DEFAULT_STANDARD][i], instance_pos.size() / 9);
|
||||
|
||||
if (!GeometricMesh[FPSM_ALPHA_REF_TEXTURE].empty())
|
||||
glUseProgram(MeshShader::InstancedObjectRefPass1Shader::Program);
|
||||
glUseProgram(MeshShader::InstancedObjectRefPass1ShaderInstance->Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++)
|
||||
drawFSPMAlphaRefTexture(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i], instance_pos.size() / 9);
|
||||
|
||||
windDir = getWind();
|
||||
if (!GeometricMesh[FPSM_GRASS].empty())
|
||||
glUseProgram(MeshShader::InstancedGrassPass1Shader::Program);
|
||||
glUseProgram(MeshShader::InstancedGrassPass1ShaderInstance->Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_GRASS].size(); i++)
|
||||
drawFSPMGrass(*GeometricMesh[FPSM_GRASS][i], windDir, instance_pos.size() / 9);
|
||||
return;
|
||||
@ -324,17 +339,17 @@ void STKInstancedSceneNode::render()
|
||||
if (irr_driver->getPhase() == SOLID_LIT_PASS)
|
||||
{
|
||||
if (!ShadedMesh[SM_DEFAULT_STANDARD].empty())
|
||||
glUseProgram(MeshShader::InstancedObjectPass2Shader::Program);
|
||||
glUseProgram(MeshShader::InstancedObjectPass2ShaderInstance->Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_DEFAULT_STANDARD].size(); i++)
|
||||
drawSMDefault(*ShadedMesh[SM_DEFAULT_STANDARD][i], ModelViewProjectionMatrix, instance_pos.size() / 9);
|
||||
|
||||
if (!ShadedMesh[SM_ALPHA_REF_TEXTURE].empty())
|
||||
glUseProgram(MeshShader::InstancedObjectRefPass2Shader::Program);
|
||||
glUseProgram(MeshShader::InstancedObjectRefPass2ShaderInstance->Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_ALPHA_REF_TEXTURE].size(); i++)
|
||||
drawSMAlphaRefTexture(*ShadedMesh[SM_ALPHA_REF_TEXTURE][i], ModelViewProjectionMatrix, instance_pos.size() / 9);
|
||||
|
||||
if (!ShadedMesh[SM_GRASS].empty())
|
||||
glUseProgram(MeshShader::InstancedGrassPass2Shader::Program);
|
||||
glUseProgram(MeshShader::InstancedGrassPass2ShaderInstance->Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_GRASS].size(); i++)
|
||||
drawSMGrass(*ShadedMesh[SM_GRASS][i], ModelViewProjectionMatrix, windDir, instance_pos.size() / 9);
|
||||
return;
|
||||
@ -343,14 +358,19 @@ void STKInstancedSceneNode::render()
|
||||
if (irr_driver->getPhase() == SHADOW_PASS)
|
||||
{
|
||||
if (!GeometricMesh[FPSM_DEFAULT_STANDARD].empty())
|
||||
glUseProgram(MeshShader::InstancedShadowShader::Program);
|
||||
glUseProgram(MeshShader::InstancedShadowShaderInstance->Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT_STANDARD].size(); i++)
|
||||
drawShadowDefault(*GeometricMesh[FPSM_DEFAULT_STANDARD][i], instance_pos.size() / 9);
|
||||
|
||||
if (!GeometricMesh[FPSM_ALPHA_REF_TEXTURE].empty())
|
||||
glUseProgram(MeshShader::InstancedRefShadowShader::Program);
|
||||
glUseProgram(MeshShader::InstancedRefShadowShaderInstance->Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++)
|
||||
drawShadowAlphaRefTexture(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i], instance_pos.size() / 9);
|
||||
|
||||
if (!GeometricMesh[FPSM_GRASS].empty())
|
||||
glUseProgram(MeshShader::InstancedGrassShadowShaderInstance->Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_GRASS].size(); i++)
|
||||
drawShadowGrass(*GeometricMesh[FPSM_GRASS][i], windDir, instance_pos.size() / 9);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -307,16 +307,6 @@ bool isObject(video::E_MATERIAL_TYPE type)
|
||||
return false;
|
||||
}
|
||||
|
||||
void initvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat)
|
||||
{
|
||||
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride));
|
||||
}
|
||||
|
||||
void initvaostate(GLMesh &mesh, TransparentMaterial TranspMat)
|
||||
{
|
||||
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride));
|
||||
}
|
||||
|
||||
std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4> > ListDefaultStandardG::Arguments;
|
||||
std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4> > ListDefault2TCoordG::Arguments;
|
||||
std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4, core::matrix4> > ListAlphaRefG::Arguments;
|
||||
|
@ -63,8 +63,6 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb);
|
||||
void fillLocalBuffer(GLMesh &, scene::IMeshBuffer* mb);
|
||||
video::E_VERTEX_TYPE getVTXTYPEFromStride(size_t stride);
|
||||
GLuint createVAO(GLuint vbo, GLuint idx, video::E_VERTEX_TYPE type);
|
||||
void initvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat);
|
||||
void initvaostate(GLMesh &mesh, TransparentMaterial TranspMat);
|
||||
core::matrix4 computeMVP(const core::matrix4 &ModelViewProjectionMatrix);
|
||||
bool isObject(video::E_MATERIAL_TYPE type);
|
||||
|
||||
|
@ -69,7 +69,7 @@ void STKMeshSceneNode::setFirstTimeMaterial()
|
||||
if (immediate_draw)
|
||||
{
|
||||
fillLocalBuffer(mesh, mb);
|
||||
initvaostate(mesh, TranspMat);
|
||||
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
else
|
||||
@ -83,7 +83,7 @@ void STKMeshSceneNode::setFirstTimeMaterial()
|
||||
if (immediate_draw)
|
||||
{
|
||||
fillLocalBuffer(mesh, mb);
|
||||
initvaostate(mesh, GeometricType, ShadedType);
|
||||
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
else
|
||||
|
@ -259,15 +259,19 @@ void GPInfoDialog::onEnterPressedInternal()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
GUIEngine::EventPropagation GPInfoDialog::processEvent(const std::string& eventSource)
|
||||
GUIEngine::EventPropagation GPInfoDialog::processEvent(const std::string& event_source)
|
||||
{
|
||||
if (eventSource == "start" || eventSource == "continue")
|
||||
if (event_source == "start" || event_source == "continue")
|
||||
{
|
||||
// Save GP identifier, since dismiss will delete this object.
|
||||
std::string gp_id = m_gp.getId();
|
||||
// Also create a copy of the string: it is a reference to data
|
||||
// in a widget in the dialog - so if we call dismiss, this reference
|
||||
// becomes invalid!
|
||||
std::string save_source = event_source;
|
||||
ModalDialog::dismiss();
|
||||
race_manager->startGP(grand_prix_manager->getGrandPrix(gp_id), false,
|
||||
(eventSource == "continue"));
|
||||
(save_source == "continue"));
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
}
|
||||
|
||||
|
@ -134,8 +134,10 @@ GUIEngine::EventPropagation RandomGPInfoDialog::processEvent(
|
||||
{
|
||||
if (eventSource == "start")
|
||||
{
|
||||
// Save GP data, since dismiss will delete this object.
|
||||
GrandPrixData gp = m_gp;
|
||||
ModalDialog::dismiss();
|
||||
race_manager->startGP(&m_gp, false, false);
|
||||
race_manager->startGP(&gp, false, false);
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
}
|
||||
else if (eventSource == "Number of tracks")
|
||||
|
Loading…
Reference in New Issue
Block a user