|
|
|
|
@@ -2,6 +2,7 @@
|
|
|
|
|
#include "graphics/irr_driver.hpp"
|
|
|
|
|
#include <ISceneManager.h>
|
|
|
|
|
#include <IMaterialRenderer.h>
|
|
|
|
|
#include "config/user_config.hpp"
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_normal, size_t stride)
|
|
|
|
|
@@ -11,39 +12,72 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t
|
|
|
|
|
glBindVertexArray(vao);
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
|
|
|
glEnableVertexAttribArray(attrib_position);
|
|
|
|
|
glEnableVertexAttribArray(attrib_texcoord);
|
|
|
|
|
glEnableVertexAttribArray(attrib_normal);
|
|
|
|
|
if ((GLint)attrib_texcoord != -1)
|
|
|
|
|
glEnableVertexAttribArray(attrib_texcoord);
|
|
|
|
|
if ((GLint)attrib_normal != -1)
|
|
|
|
|
glEnableVertexAttribArray(attrib_normal);
|
|
|
|
|
glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, stride, 0);
|
|
|
|
|
glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28);
|
|
|
|
|
glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12);
|
|
|
|
|
if ((GLint)attrib_texcoord != -1)
|
|
|
|
|
glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28);
|
|
|
|
|
if ((GLint)attrib_normal != -1)
|
|
|
|
|
glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12);
|
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx);
|
|
|
|
|
glBindVertexArray(0);
|
|
|
|
|
return vao;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace ObjectShader
|
|
|
|
|
namespace ObjectPass1Shader
|
|
|
|
|
{
|
|
|
|
|
GLuint Program;
|
|
|
|
|
GLuint attrib_position, attrib_texcoord, attrib_normal;
|
|
|
|
|
GLuint uniform_MVP, uniform_TIMV, uniform_texture;
|
|
|
|
|
GLuint attrib_position, attrib_normal;
|
|
|
|
|
GLuint uniform_MVP, uniform_TIMV;
|
|
|
|
|
|
|
|
|
|
void init()
|
|
|
|
|
{
|
|
|
|
|
initGL();
|
|
|
|
|
Program = LoadProgram(file_manager->getAsset("shaders/object.vert").c_str(), file_manager->getAsset("shaders/object.frag").c_str());
|
|
|
|
|
Program = LoadProgram(file_manager->getAsset("shaders/object_pass1.vert").c_str(), file_manager->getAsset("shaders/object_pass1.frag").c_str());
|
|
|
|
|
attrib_position = glGetAttribLocation(Program, "Position");
|
|
|
|
|
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
|
|
|
|
|
attrib_normal = glGetAttribLocation(Program, "Normal");
|
|
|
|
|
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
|
|
|
|
|
uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView");
|
|
|
|
|
uniform_texture = glGetUniformLocation(Program, "texture");
|
|
|
|
|
uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView");;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setProgramAndUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_texture)
|
|
|
|
|
void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView)
|
|
|
|
|
{
|
|
|
|
|
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
|
|
|
|
|
glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer());
|
|
|
|
|
glUniform1i(uniform_texture, TU_texture);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace ObjectPass2Shader
|
|
|
|
|
{
|
|
|
|
|
GLuint Program;
|
|
|
|
|
GLuint attrib_position, attrib_texcoord;
|
|
|
|
|
GLuint uniform_MVP, uniform_TIMV, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_screen, uniform_ambient;
|
|
|
|
|
|
|
|
|
|
void init()
|
|
|
|
|
{
|
|
|
|
|
initGL();
|
|
|
|
|
Program = LoadProgram(file_manager->getAsset("shaders/object_pass2.vert").c_str(), file_manager->getAsset("shaders/object_pass2.frag").c_str());
|
|
|
|
|
attrib_position = glGetAttribLocation(Program, "Position");
|
|
|
|
|
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
|
|
|
|
|
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
|
|
|
|
|
uniform_Albedo = glGetUniformLocation(Program, "Albedo");
|
|
|
|
|
uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap");
|
|
|
|
|
uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap");
|
|
|
|
|
uniform_screen = glGetUniformLocation(Program, "screen");
|
|
|
|
|
uniform_ambient = glGetUniformLocation(Program, "ambient");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap)
|
|
|
|
|
{
|
|
|
|
|
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
|
|
|
|
|
glUniform1i(uniform_Albedo, TU_Albedo);
|
|
|
|
|
glUniform1i(uniform_DiffuseMap, TU_DiffuseMap);
|
|
|
|
|
glUniform1i(uniform_SpecularMap, TU_SpecularMap);
|
|
|
|
|
glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height);
|
|
|
|
|
const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight();
|
|
|
|
|
glUniform3f(uniform_ambient, s.r, s.g, s.b);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -123,7 +157,6 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
|
|
|
|
|
result.textures = static_cast<irr::video::COpenGLTexture*>(tex)->getOpenGLTextureName();
|
|
|
|
|
else
|
|
|
|
|
result.textures = 0;
|
|
|
|
|
result.vao = 0;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -139,9 +172,10 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene
|
|
|
|
|
GLmeshes.push_back(allocateMeshBuffer(mb));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if (ObjectShader::Program)
|
|
|
|
|
if (ObjectPass1Shader::Program && ObjectPass2Shader::Program)
|
|
|
|
|
return;
|
|
|
|
|
ObjectShader::init();
|
|
|
|
|
ObjectPass1Shader::init();
|
|
|
|
|
ObjectPass2Shader::init();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STKMesh::~STKMesh()
|
|
|
|
|
@@ -150,43 +184,87 @@ STKMesh::~STKMesh()
|
|
|
|
|
// glDeleteBuffers(index_buffer.size(), index_buffer.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
void drawFirstPass(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
|
|
|
|
{
|
|
|
|
|
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false);
|
|
|
|
|
|
|
|
|
|
glStencilFunc(GL_ALWAYS, 0, ~0);
|
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
|
glEnable(GL_ALPHA_TEST);
|
|
|
|
|
glDepthMask(GL_TRUE);
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
GLenum ptype = mesh.PrimitiveType;
|
|
|
|
|
GLenum itype = mesh.IndexType;
|
|
|
|
|
size_t count = mesh.IndexCount;
|
|
|
|
|
|
|
|
|
|
core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION);
|
|
|
|
|
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
|
|
|
|
|
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
|
|
|
|
core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
|
|
|
|
|
TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
|
|
|
|
TransposeInverseModelView.makeInverse();
|
|
|
|
|
TransposeInverseModelView = TransposeInverseModelView.getTransposed();
|
|
|
|
|
|
|
|
|
|
glUseProgram(ObjectPass1Shader::Program);
|
|
|
|
|
ObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView);
|
|
|
|
|
|
|
|
|
|
glBindVertexArray(mesh.vao_first_pass);
|
|
|
|
|
glDrawElements(ptype, count, itype, 0);
|
|
|
|
|
glBindVertexArray(0);
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
|
glStencilFunc(GL_ALWAYS, 1, ~0);
|
|
|
|
|
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
void drawSecondPass(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
|
|
|
|
{
|
|
|
|
|
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false);
|
|
|
|
|
|
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
|
glEnable(GL_ALPHA_TEST);
|
|
|
|
|
glDepthMask(GL_FALSE);
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
GLenum ptype = mesh.PrimitiveType;
|
|
|
|
|
GLenum itype = mesh.IndexType;
|
|
|
|
|
size_t count = mesh.IndexCount;
|
|
|
|
|
|
|
|
|
|
core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION);
|
|
|
|
|
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
|
|
|
|
|
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
|
|
|
|
|
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, mesh.textures);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
|
|
|
|
|
|
|
|
glActiveTexture(GL_TEXTURE1);
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, static_cast<irr::video::COpenGLTexture*>(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName());
|
|
|
|
|
glActiveTexture(GL_TEXTURE2);
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, static_cast<irr::video::COpenGLTexture*>(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName());
|
|
|
|
|
|
|
|
|
|
glUseProgram(ObjectPass2Shader::Program);
|
|
|
|
|
ObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2);
|
|
|
|
|
|
|
|
|
|
glBindVertexArray(mesh.vao_second_pass);
|
|
|
|
|
glDrawElements(ptype, count, itype, 0);
|
|
|
|
|
glBindVertexArray(0);
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
|
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
|
|
|
|
{
|
|
|
|
|
if (!mesh.textures)
|
|
|
|
|
return;
|
|
|
|
|
glStencilFunc(GL_ALWAYS, 0, ~0);
|
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
|
glEnable(GL_ALPHA_TEST);
|
|
|
|
|
glDepthMask(GL_TRUE);
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
GLenum ptype = mesh.PrimitiveType;
|
|
|
|
|
GLenum itype = mesh.IndexType;
|
|
|
|
|
size_t count = mesh.IndexCount;
|
|
|
|
|
|
|
|
|
|
core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION);
|
|
|
|
|
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
|
|
|
|
|
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
|
|
|
|
core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
|
|
|
|
|
TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
|
|
|
|
TransposeInverseModelView.makeInverse();
|
|
|
|
|
TransposeInverseModelView = TransposeInverseModelView.getTransposed();
|
|
|
|
|
|
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, mesh.textures);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
|
|
|
|
|
|
|
|
glUseProgram(ObjectShader::Program);
|
|
|
|
|
ObjectShader::setProgramAndUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0);
|
|
|
|
|
|
|
|
|
|
glBindVertexArray(mesh.vao);
|
|
|
|
|
glDrawElements(ptype, count, itype, 0);
|
|
|
|
|
glBindVertexArray(0);
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
|
glStencilFunc(GL_ALWAYS, 1, ~0);
|
|
|
|
|
if (irr_driver->getPhase() == 0)
|
|
|
|
|
drawFirstPass(mesh, type);
|
|
|
|
|
else
|
|
|
|
|
drawSecondPass(mesh, type);
|
|
|
|
|
|
|
|
|
|
video::SMaterial material;
|
|
|
|
|
material.MaterialType = irr_driver->getShader(ES_RAIN);
|
|
|
|
|
@@ -206,11 +284,14 @@ static bool isObject(video::E_MATERIAL_TYPE type)
|
|
|
|
|
|
|
|
|
|
static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
|
|
|
|
{
|
|
|
|
|
if (mesh.vao)
|
|
|
|
|
if (mesh.vao_first_pass)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
|
|
|
|
ObjectShader::attrib_position, ObjectShader::attrib_texcoord, ObjectShader::attrib_normal,
|
|
|
|
|
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
|
|
|
|
ObjectPass1Shader::attrib_position, -1, ObjectPass1Shader::attrib_normal,
|
|
|
|
|
mesh.Stride);
|
|
|
|
|
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
|
|
|
|
ObjectPass2Shader::attrib_position, ObjectPass2Shader::attrib_texcoord, -1,
|
|
|
|
|
mesh.Stride);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|