Start working on instancing library node
This commit is contained in:
parent
4af050e1c0
commit
dd5997d277
18
data/shaders/instanced_object_pass1.vert
Normal file
18
data/shaders/instanced_object_pass1.vert
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
uniform mat4 ViewProjectionMatrix;
|
||||||
|
uniform mat4 ViewMatrix;
|
||||||
|
|
||||||
|
in vec3 Origin;
|
||||||
|
in vec3 Orientation;
|
||||||
|
|
||||||
|
in vec3 Position;
|
||||||
|
in vec3 Normal;
|
||||||
|
out vec3 nor;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
mat4 ModelMatrix = mat4(1.);
|
||||||
|
ModelMatrix[3].xyz += Origin;
|
||||||
|
mat4 TransposeInverseModelView = transpose(inverse(ViewMatrix * ModelMatrix));
|
||||||
|
gl_Position = ViewProjectionMatrix * ModelMatrix * vec4(Position, 1.);
|
||||||
|
nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz;
|
||||||
|
}
|
23
data/shaders/instanced_object_pass2.vert
Normal file
23
data/shaders/instanced_object_pass2.vert
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
uniform mat4 ViewProjectionMatrix;
|
||||||
|
uniform mat4 TextureMatrix =
|
||||||
|
mat4(1., 0., 0., 0.,
|
||||||
|
0., 1., 0., 0.,
|
||||||
|
0., 0., 1., 0.,
|
||||||
|
0., 0., 0., 1.);
|
||||||
|
|
||||||
|
|
||||||
|
in vec3 Origin;
|
||||||
|
|
||||||
|
in vec3 Position;
|
||||||
|
in vec2 Texcoord;
|
||||||
|
out vec2 uv;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
mat4 ModelMatrix = mat4(1.);
|
||||||
|
ModelMatrix[3].xyz += Origin;
|
||||||
|
uv = (TextureMatrix * vec4(Texcoord, 1., 1.)).xy;
|
||||||
|
gl_Position = ViewProjectionMatrix * ModelMatrix * vec4(Position, 1.);
|
||||||
|
}
|
@ -63,6 +63,7 @@ src/graphics/slip_stream.cpp
|
|||||||
src/graphics/stars.cpp
|
src/graphics/stars.cpp
|
||||||
src/graphics/stkanimatedmesh.cpp
|
src/graphics/stkanimatedmesh.cpp
|
||||||
src/graphics/stkbillboard.cpp
|
src/graphics/stkbillboard.cpp
|
||||||
|
src/graphics/stkinstancedscenenode.cpp
|
||||||
src/graphics/stkmesh.cpp
|
src/graphics/stkmesh.cpp
|
||||||
src/graphics/stkmeshscenenode.cpp
|
src/graphics/stkmeshscenenode.cpp
|
||||||
src/graphics/sun.cpp
|
src/graphics/sun.cpp
|
||||||
@ -395,6 +396,7 @@ src/graphics/slip_stream.hpp
|
|||||||
src/graphics/stars.hpp
|
src/graphics/stars.hpp
|
||||||
src/graphics/stkanimatedmesh.hpp
|
src/graphics/stkanimatedmesh.hpp
|
||||||
src/graphics/stkbillboard.hpp
|
src/graphics/stkbillboard.hpp
|
||||||
|
src/graphics/stkinstancedscenenode.hpp
|
||||||
src/graphics/stkmesh.hpp
|
src/graphics/stkmesh.hpp
|
||||||
src/graphics/stkmeshscenenode.hpp
|
src/graphics/stkmeshscenenode.hpp
|
||||||
src/graphics/sun.hpp
|
src/graphics/sun.hpp
|
||||||
|
@ -46,6 +46,7 @@ PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
|
|||||||
PFNGLBLENDEQUATIONPROC glBlendEquation;
|
PFNGLBLENDEQUATIONPROC glBlendEquation;
|
||||||
PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
|
PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
|
||||||
PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
|
PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
|
||||||
|
PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
|
||||||
PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||||
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||||
PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||||
@ -181,6 +182,7 @@ void initGL()
|
|||||||
glBlendEquation = (PFNGLBLENDEQUATIONPROC)IRR_OGL_LOAD_EXTENSION("glBlendEquation");
|
glBlendEquation = (PFNGLBLENDEQUATIONPROC)IRR_OGL_LOAD_EXTENSION("glBlendEquation");
|
||||||
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribDivisor");
|
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribDivisor");
|
||||||
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced");
|
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced");
|
||||||
|
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawElementsInstanced");
|
||||||
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteBuffers");
|
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteBuffers");
|
||||||
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)IRR_OGL_LOAD_EXTENSION("glGenVertexArrays");
|
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)IRR_OGL_LOAD_EXTENSION("glGenVertexArrays");
|
||||||
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)IRR_OGL_LOAD_EXTENSION("glBindVertexArray");
|
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)IRR_OGL_LOAD_EXTENSION("glBindVertexArray");
|
||||||
|
@ -68,6 +68,7 @@ extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
|
|||||||
extern PFNGLBLENDEQUATIONPROC glBlendEquation;
|
extern PFNGLBLENDEQUATIONPROC glBlendEquation;
|
||||||
extern PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
|
extern PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
|
||||||
extern PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
|
extern PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
|
||||||
|
extern PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
|
||||||
extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||||
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||||
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "graphics/shaders.hpp"
|
#include "graphics/shaders.hpp"
|
||||||
#include "graphics/shadow_importance.hpp"
|
#include "graphics/shadow_importance.hpp"
|
||||||
#include "graphics/stkmeshscenenode.hpp"
|
#include "graphics/stkmeshscenenode.hpp"
|
||||||
|
#include "graphics/stkinstancedscenenode.hpp"
|
||||||
#include "graphics/wind.hpp"
|
#include "graphics/wind.hpp"
|
||||||
#include "io/file_manager.hpp"
|
#include "io/file_manager.hpp"
|
||||||
#include "items/item.hpp"
|
#include "items/item.hpp"
|
||||||
@ -50,6 +51,8 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
STKInstancedSceneNode *InstancedBox = 0;
|
||||||
|
|
||||||
void IrrDriver::renderGLSL(float dt)
|
void IrrDriver::renderGLSL(float dt)
|
||||||
{
|
{
|
||||||
World *world = World::getWorld(); // Never NULL.
|
World *world = World::getWorld(); // Never NULL.
|
||||||
@ -132,6 +135,15 @@ void IrrDriver::renderGLSL(float dt)
|
|||||||
transparent_glow_nodes.push_back(repnode);
|
transparent_glow_nodes.push_back(repnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!InstancedBox)
|
||||||
|
{
|
||||||
|
InstancedBox = new STKInstancedSceneNode(items->getItemModel(items->getItem(0)->getType()), m_scene_manager->getRootSceneNode(), m_scene_manager, -1);
|
||||||
|
InstancedBox->addWorldMatrix(core::vector3df(0, 0, 0));
|
||||||
|
InstancedBox->addWorldMatrix(core::vector3df(1., 0, 0));
|
||||||
|
InstancedBox->addWorldMatrix(core::vector3df(0, 1., 0));
|
||||||
|
InstancedBox->addWorldMatrix(core::vector3df(0, 0, 1.));
|
||||||
|
}
|
||||||
|
|
||||||
// Start the RTT for post-processing.
|
// Start the RTT for post-processing.
|
||||||
// We do this before beginScene() because we want to capture the glClear()
|
// We do this before beginScene() because we want to capture the glClear()
|
||||||
// because of tracks that do not have skyboxes (generally add-on tracks)
|
// because of tracks that do not have skyboxes (generally add-on tracks)
|
||||||
@ -203,7 +215,7 @@ void IrrDriver::renderGLSL(float dt)
|
|||||||
irr_driver->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION));
|
irr_driver->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION));
|
||||||
irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
|
irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
|
||||||
irr_driver->genProjViewMatrix();
|
irr_driver->genProjViewMatrix();
|
||||||
|
InstancedBox->render();
|
||||||
PROFILER_POP_CPU_MARKER();
|
PROFILER_POP_CPU_MARKER();
|
||||||
|
|
||||||
// Todo : reenable glow and shadows
|
// Todo : reenable glow and shadows
|
||||||
@ -245,7 +257,7 @@ void IrrDriver::renderGLSL(float dt)
|
|||||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||||
}
|
}
|
||||||
m_scene_manager->drawAll(m_renderpass);
|
m_scene_manager->drawAll(m_renderpass);
|
||||||
|
InstancedBox->render();
|
||||||
PROFILER_POP_CPU_MARKER();
|
PROFILER_POP_CPU_MARKER();
|
||||||
|
|
||||||
if (World::getWorld()->getTrack()->isFogEnabled())
|
if (World::getWorld()->getTrack()->isFogEnabled())
|
||||||
|
@ -255,7 +255,9 @@ void Shaders::loadShaders()
|
|||||||
MeshShader::NormalMapShader::init();
|
MeshShader::NormalMapShader::init();
|
||||||
MeshShader::ObjectPass1Shader::init();
|
MeshShader::ObjectPass1Shader::init();
|
||||||
MeshShader::ObjectRefPass1Shader::init();
|
MeshShader::ObjectRefPass1Shader::init();
|
||||||
|
MeshShader::InstancedObjectPass1Shader::init();
|
||||||
MeshShader::ObjectPass2Shader::init();
|
MeshShader::ObjectPass2Shader::init();
|
||||||
|
MeshShader::InstancedObjectPass2Shader::init();
|
||||||
MeshShader::DetailledObjectPass2Shader::init();
|
MeshShader::DetailledObjectPass2Shader::init();
|
||||||
MeshShader::ObjectRimLimitShader::init();
|
MeshShader::ObjectRimLimitShader::init();
|
||||||
MeshShader::UntexturedObjectShader::init();
|
MeshShader::UntexturedObjectShader::init();
|
||||||
@ -425,6 +427,29 @@ namespace MeshShader
|
|||||||
glUniform1i(uniform_normalMap, TU_normalMap);
|
glUniform1i(uniform_normalMap, TU_normalMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLuint InstancedObjectPass1Shader::Program;
|
||||||
|
GLuint InstancedObjectPass1Shader::attrib_position;
|
||||||
|
GLuint InstancedObjectPass1Shader::attrib_normal;
|
||||||
|
GLuint InstancedObjectPass1Shader::attrib_origin;
|
||||||
|
GLuint InstancedObjectPass1Shader::uniform_MP;
|
||||||
|
GLuint InstancedObjectPass1Shader::uniform_VM;
|
||||||
|
|
||||||
|
void InstancedObjectPass1Shader::init()
|
||||||
|
{
|
||||||
|
Program = LoadProgram(file_manager->getAsset("shaders/instanced_object_pass1.vert").c_str(), file_manager->getAsset("shaders/object_pass1.frag").c_str());
|
||||||
|
attrib_origin = glGetAttribLocation(Program, "Origin");
|
||||||
|
attrib_position = glGetAttribLocation(Program, "Position");
|
||||||
|
attrib_normal = glGetAttribLocation(Program, "Normal");
|
||||||
|
uniform_MP = glGetUniformLocation(Program, "ViewProjectionMatrix");
|
||||||
|
uniform_VM = glGetUniformLocation(Program, "ViewMatrix");
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstancedObjectPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ViewMatrix)
|
||||||
|
{
|
||||||
|
glUniformMatrix4fv(uniform_MP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
|
||||||
|
glUniformMatrix4fv(uniform_VM, 1, GL_FALSE, ViewMatrix.pointer());
|
||||||
|
}
|
||||||
|
|
||||||
// Solid Lit pass shaders
|
// Solid Lit pass shaders
|
||||||
|
|
||||||
GLuint ObjectPass2Shader::Program;
|
GLuint ObjectPass2Shader::Program;
|
||||||
@ -468,6 +493,49 @@ namespace MeshShader
|
|||||||
glUniform3f(uniform_ambient, s.r, s.g, s.b);
|
glUniform3f(uniform_ambient, s.r, s.g, s.b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLuint InstancedObjectPass2Shader::Program;
|
||||||
|
GLuint InstancedObjectPass2Shader::attrib_position;
|
||||||
|
GLuint InstancedObjectPass2Shader::attrib_texcoord;
|
||||||
|
GLuint InstancedObjectPass2Shader::attrib_origin;
|
||||||
|
GLuint InstancedObjectPass2Shader::uniform_VP;
|
||||||
|
GLuint InstancedObjectPass2Shader::uniform_TM;
|
||||||
|
GLuint InstancedObjectPass2Shader::uniform_screen;
|
||||||
|
GLuint InstancedObjectPass2Shader::uniform_ambient;
|
||||||
|
GLuint InstancedObjectPass2Shader::TU_Albedo;
|
||||||
|
|
||||||
|
void InstancedObjectPass2Shader::init()
|
||||||
|
{
|
||||||
|
Program = LoadProgram(file_manager->getAsset("shaders/instanced_object_pass2.vert").c_str(), file_manager->getAsset("shaders/object_pass2.frag").c_str());
|
||||||
|
attrib_position = glGetAttribLocation(Program, "Position");
|
||||||
|
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
|
||||||
|
attrib_origin = glGetAttribLocation(Program, "Origin");
|
||||||
|
uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix");
|
||||||
|
uniform_TM = glGetUniformLocation(Program, "TextureMatrix");
|
||||||
|
GLuint uniform_Albedo = glGetUniformLocation(Program, "Albedo");
|
||||||
|
GLuint uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap");
|
||||||
|
GLuint uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap");
|
||||||
|
GLuint uniform_SSAO = glGetUniformLocation(Program, "SSAO");
|
||||||
|
uniform_screen = glGetUniformLocation(Program, "screen");
|
||||||
|
uniform_ambient = glGetUniformLocation(Program, "ambient");
|
||||||
|
TU_Albedo = 3;
|
||||||
|
|
||||||
|
glUseProgram(Program);
|
||||||
|
glUniform1i(uniform_DiffuseMap, 0);
|
||||||
|
glUniform1i(uniform_SpecularMap, 1);
|
||||||
|
glUniform1i(uniform_SSAO, 2);
|
||||||
|
glUniform1i(uniform_Albedo, TU_Albedo);
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstancedObjectPass2Shader::setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &TextureMatrix)
|
||||||
|
{
|
||||||
|
glUniformMatrix4fv(uniform_VP, 1, GL_FALSE, ViewProjectionMatrix.pointer());
|
||||||
|
glUniformMatrix4fv(uniform_TM, 1, GL_FALSE, TextureMatrix.pointer());
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
GLuint DetailledObjectPass2Shader::Program;
|
GLuint DetailledObjectPass2Shader::Program;
|
||||||
GLuint DetailledObjectPass2Shader::attrib_position;
|
GLuint DetailledObjectPass2Shader::attrib_position;
|
||||||
GLuint DetailledObjectPass2Shader::attrib_texcoord;
|
GLuint DetailledObjectPass2Shader::attrib_texcoord;
|
||||||
|
@ -76,6 +76,17 @@ public:
|
|||||||
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_normalMap);
|
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_normalMap);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class InstancedObjectPass1Shader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static GLuint Program;
|
||||||
|
static GLuint attrib_position, attrib_normal, attrib_origin;
|
||||||
|
static GLuint uniform_MP, uniform_VM;
|
||||||
|
|
||||||
|
static void init();
|
||||||
|
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &ViewMatrix);
|
||||||
|
};
|
||||||
|
|
||||||
class ObjectPass2Shader
|
class ObjectPass2Shader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -88,6 +99,18 @@ public:
|
|||||||
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix);
|
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class InstancedObjectPass2Shader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static GLuint Program;
|
||||||
|
static GLuint attrib_position, attrib_texcoord, attrib_origin;
|
||||||
|
static GLuint uniform_VP, uniform_TM, uniform_screen, uniform_ambient;
|
||||||
|
static GLuint TU_Albedo;
|
||||||
|
|
||||||
|
static void init();
|
||||||
|
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &TextureMatrix);
|
||||||
|
};
|
||||||
|
|
||||||
class DetailledObjectPass2Shader
|
class DetailledObjectPass2Shader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
141
src/graphics/stkinstancedscenenode.cpp
Normal file
141
src/graphics/stkinstancedscenenode.cpp
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#include "stkinstancedscenenode.hpp"
|
||||||
|
#include "graphics/irr_driver.hpp"
|
||||||
|
|
||||||
|
STKInstancedSceneNode::STKInstancedSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||||
|
const irr::core::vector3df& position,
|
||||||
|
const irr::core::vector3df& rotation,
|
||||||
|
const irr::core::vector3df& scale) :
|
||||||
|
CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
|
||||||
|
{
|
||||||
|
createGLMeshes();
|
||||||
|
}
|
||||||
|
|
||||||
|
void STKInstancedSceneNode::createGLMeshes()
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
|
||||||
|
{
|
||||||
|
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||||
|
GLmeshes.push_back(allocateMeshBuffer(mb));
|
||||||
|
}
|
||||||
|
isMaterialInitialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat)
|
||||||
|
{
|
||||||
|
glGenVertexArrays(1, &mesh.vao_first_pass);
|
||||||
|
glBindVertexArray(mesh.vao_first_pass);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vertex_buffer);
|
||||||
|
glEnableVertexAttribArray(MeshShader::InstancedObjectPass1Shader::attrib_position);
|
||||||
|
glEnableVertexAttribArray(MeshShader::InstancedObjectPass1Shader::attrib_normal);
|
||||||
|
glVertexAttribPointer(MeshShader::InstancedObjectPass1Shader::attrib_position, 3, GL_FLOAT, GL_FALSE, mesh.Stride, 0);
|
||||||
|
glVertexAttribPointer(MeshShader::InstancedObjectPass1Shader::attrib_normal, 3, GL_FLOAT, GL_FALSE, mesh.Stride, (GLvoid*)12);
|
||||||
|
|
||||||
|
glGenBuffers(1, &instances_vbo);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
|
||||||
|
glEnableVertexAttribArray(MeshShader::InstancedObjectPass1Shader::attrib_origin);
|
||||||
|
glVertexAttribPointer(MeshShader::InstancedObjectPass1Shader::attrib_origin, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
|
||||||
|
|
||||||
|
glVertexAttribDivisor(MeshShader::InstancedObjectPass1Shader::attrib_origin, 1);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.index_buffer);
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &mesh.vao_second_pass);
|
||||||
|
glBindVertexArray(mesh.vao_second_pass);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vertex_buffer);
|
||||||
|
glEnableVertexAttribArray(MeshShader::InstancedObjectPass2Shader::attrib_position);
|
||||||
|
glEnableVertexAttribArray(MeshShader::InstancedObjectPass2Shader::attrib_texcoord);
|
||||||
|
glVertexAttribPointer(MeshShader::InstancedObjectPass2Shader::attrib_position, 3, GL_FLOAT, GL_FALSE, mesh.Stride, 0);
|
||||||
|
glVertexAttribPointer(MeshShader::InstancedObjectPass2Shader::attrib_texcoord, 3, GL_FLOAT, GL_FALSE, mesh.Stride, (GLvoid*)28);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
|
||||||
|
glEnableVertexAttribArray(MeshShader::InstancedObjectPass2Shader::attrib_origin);
|
||||||
|
glVertexAttribPointer(MeshShader::InstancedObjectPass2Shader::attrib_origin, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
|
||||||
|
|
||||||
|
glVertexAttribDivisor(MeshShader::InstancedObjectPass2Shader::attrib_origin, 1);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.index_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void STKInstancedSceneNode::setFirstTimeMaterial()
|
||||||
|
{
|
||||||
|
if (isMaterialInitialized)
|
||||||
|
return;
|
||||||
|
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||||
|
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
|
||||||
|
{
|
||||||
|
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||||
|
if (!mb)
|
||||||
|
continue;
|
||||||
|
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
|
||||||
|
|
||||||
|
GLMesh &mesh = GLmeshes[i];
|
||||||
|
GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type);
|
||||||
|
ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures);
|
||||||
|
initinstancedvaostate(mesh, GeometricType, ShadedType);
|
||||||
|
}
|
||||||
|
isMaterialInitialized = true;
|
||||||
|
printf("instance count : %d\n", instance_pos.size() / 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void STKInstancedSceneNode::addWorldMatrix(const core::vector3df &v)
|
||||||
|
{
|
||||||
|
instance_pos.push_back(v.X);
|
||||||
|
instance_pos.push_back(v.Y);
|
||||||
|
instance_pos.push_back(v.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void STKInstancedSceneNode::render()
|
||||||
|
{
|
||||||
|
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||||
|
setFirstTimeMaterial();
|
||||||
|
// AbsoluteTransformation.setTranslation(vector3df(0., 0., 10.));
|
||||||
|
// driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||||
|
|
||||||
|
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
|
||||||
|
{
|
||||||
|
ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION);
|
||||||
|
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
|
||||||
|
|
||||||
|
glUseProgram(MeshShader::InstancedObjectPass1Shader::Program);
|
||||||
|
for (unsigned i = 0; i < GLmeshes.size(); i++)
|
||||||
|
{
|
||||||
|
GLMesh &mesh = GLmeshes[i];
|
||||||
|
|
||||||
|
irr_driver->IncreaseObjectCount();
|
||||||
|
GLenum ptype = mesh.PrimitiveType;
|
||||||
|
GLenum itype = mesh.IndexType;
|
||||||
|
size_t count = mesh.IndexCount;
|
||||||
|
|
||||||
|
MeshShader::InstancedObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
|
||||||
|
|
||||||
|
glBindVertexArray(mesh.vao_first_pass);
|
||||||
|
glDrawElementsInstanced(ptype, count, itype, 0, instance_pos.size() / 3);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (irr_driver->getPhase() == SOLID_LIT_PASS)
|
||||||
|
{
|
||||||
|
glUseProgram(MeshShader::InstancedObjectPass2Shader::Program);
|
||||||
|
for (unsigned i = 0; i < GLmeshes.size(); i++)
|
||||||
|
{
|
||||||
|
GLMesh &mesh = GLmeshes[i];
|
||||||
|
|
||||||
|
irr_driver->IncreaseObjectCount();
|
||||||
|
GLenum ptype = mesh.PrimitiveType;
|
||||||
|
GLenum itype = mesh.IndexType;
|
||||||
|
size_t count = mesh.IndexCount;
|
||||||
|
|
||||||
|
setTexture(MeshShader::InstancedObjectPass2Shader::TU_Albedo, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||||
|
|
||||||
|
MeshShader::InstancedObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, core::matrix4::EM4CONST_IDENTITY);
|
||||||
|
|
||||||
|
assert(mesh.vao_second_pass);
|
||||||
|
glBindVertexArray(mesh.vao_second_pass);
|
||||||
|
glDrawElementsInstanced(ptype, count, itype, 0, instance_pos.size() / 3);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
26
src/graphics/stkinstancedscenenode.hpp
Normal file
26
src/graphics/stkinstancedscenenode.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef STKINSTANCEDSCENENODE_HPP
|
||||||
|
#define STKINSTANCEDSCENENODE_HPP
|
||||||
|
|
||||||
|
#include "stkmesh.hpp"
|
||||||
|
|
||||||
|
class STKInstancedSceneNode : public irr::scene::CMeshSceneNode
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
std::vector<GLMesh> GLmeshes;
|
||||||
|
std::vector<float> instance_pos;
|
||||||
|
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView;
|
||||||
|
GLuint instances_vbo;
|
||||||
|
void createGLMeshes();
|
||||||
|
bool isMaterialInitialized;
|
||||||
|
void setFirstTimeMaterial();
|
||||||
|
void initinstancedvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat);
|
||||||
|
public:
|
||||||
|
STKInstancedSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||||
|
const irr::core::vector3df& position = irr::core::vector3df(0, 0, 0),
|
||||||
|
const irr::core::vector3df& rotation = irr::core::vector3df(0, 0, 0),
|
||||||
|
const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f));
|
||||||
|
virtual void render();
|
||||||
|
void addWorldMatrix(const core::vector3df &);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user