Merge branch 'master' into konstin-m_random_gp

Conflicts:
	src/states_screens/dialogs/gp_info_dialog.cpp
This commit is contained in:
hiker 2014-07-15 11:07:44 +10:00
commit f24e53538c
16 changed files with 1048 additions and 970 deletions

View File

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

View File

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

View 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
}

View File

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

View File

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

View 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));
}

View 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);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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