191 lines
5.1 KiB
C++
191 lines
5.1 KiB
C++
#include <assert.h>
|
|
#include <algorithm>
|
|
#include "utils/logger.h"
|
|
#include "render/shadersystem.h"
|
|
#include "render/shader.h"
|
|
#include <render/gl_shared.h>
|
|
|
|
static const char* g_uniformNameTable[UNIFORM_MAX] =
|
|
{
|
|
"u_modelMatrix",
|
|
"u_viewMatrix",
|
|
"u_projectionMatrix",
|
|
"u_modelViewProjection",
|
|
"u_customColor",
|
|
"u_sunDirection",
|
|
"u_sunColor",
|
|
"u_sunAmbientColor",
|
|
};
|
|
|
|
static const char* g_samplersNameTable[SAMPLER_MAX] =
|
|
{
|
|
"u_albedoTexture",
|
|
"u_normalTexture",
|
|
"u_lightmapTexture",
|
|
};
|
|
|
|
ShaderSystem* g_shaderSystem = nullptr;
|
|
|
|
ShaderSystem::ShaderSystem()
|
|
{
|
|
}
|
|
|
|
ShaderSystem::~ShaderSystem()
|
|
{
|
|
}
|
|
|
|
void ShaderSystem::Init()
|
|
{
|
|
Msg("Initializing Shader System ...");
|
|
}
|
|
|
|
void ShaderSystem::Shutdown()
|
|
{
|
|
for (int i = 0; i < m_shaders.size(); i++)
|
|
{
|
|
ShaderData& shaderData = m_shaders[i];
|
|
|
|
if (shaderData.shader)
|
|
{
|
|
delete shaderData.shader;
|
|
shaderData.shader = nullptr;
|
|
}
|
|
}
|
|
|
|
m_shaders.clear();
|
|
}
|
|
|
|
Shader* ShaderSystem::CreateShader(const char* name, const char* vsfilepath, const char* psfilepath, InputLayoutDesc_t* inputLayout /*= nullptr*/, int inputLayoutCount/* = 0*/)
|
|
{
|
|
auto it = std::find_if(m_shaders.begin(), m_shaders.end(), [=](const ShaderData& shaderData) { return shaderData.shadername == name; });
|
|
if ( it != m_shaders.end() )
|
|
{
|
|
return it->shader;
|
|
}
|
|
|
|
Shader* pShader = new Shader();
|
|
|
|
if ( inputLayout && inputLayoutCount > 0 )
|
|
{
|
|
memcpy( pShader->m_layouts, inputLayout, inputLayoutCount * sizeof( InputLayoutDesc_t ) );
|
|
pShader->m_layout_count = inputLayoutCount;
|
|
}
|
|
|
|
pShader->Create( name, vsfilepath, psfilepath );
|
|
|
|
ShaderData shaderData = { name, pShader };
|
|
m_shaders.push_back(shaderData);
|
|
|
|
return pShader;
|
|
}
|
|
|
|
size_t g_vertex_attribs_sizetable[VERTEXATTR_MAX] =
|
|
{
|
|
2, // VERTEXATTR_VEC2
|
|
3, // VERTEXATTR_VEC3
|
|
4, // VERTEXATTR_VEC4
|
|
};
|
|
|
|
size_t g_vertex_attribs_realsizetable[VERTEXATTR_MAX] =
|
|
{
|
|
8, // VERTEXATTR_VEC2
|
|
12, // VERTEXATTR_VEC3
|
|
16, // VERTEXATTR_VEC4
|
|
};
|
|
|
|
void ApplyVertexFormat(const Shader* shader, size_t stride)
|
|
{
|
|
size_t appliedOffset = 0;
|
|
for (int i = 0; i < shader->m_layout_count; i++)
|
|
{
|
|
const InputLayoutDesc_t* layoutEntry = &shader->m_layouts[i];
|
|
|
|
glEnableVertexAttribArray(GLuint(i));
|
|
|
|
glVertexAttribPointer(GLuint(i), GLint(g_vertex_attribs_sizetable[layoutEntry->attribute]),
|
|
GL_FLOAT, GL_FALSE, static_cast<GLsizei>(stride),
|
|
(appliedOffset > 0) ? (void*)(appliedOffset * sizeof(float)) : (void*)0);
|
|
|
|
appliedOffset += g_vertex_attribs_sizetable[layoutEntry->attribute];
|
|
}
|
|
}
|
|
|
|
void ShaderSystem::SetShader(const Shader* shader)
|
|
{
|
|
assert( shader );
|
|
glUseProgram( shader->m_program );
|
|
|
|
// apply input layout
|
|
|
|
//for ( int i = 0; i < shader->m_layout_count; i++ )
|
|
//{
|
|
// const InputLayoutDesc_t& layout = shader->m_layouts[ i ];
|
|
//
|
|
// //glEnableVertexAttribArray( shader->m_glLayouts[ i ] );
|
|
// //glVertexAttribPointer( shader->m_glLayouts[ i ], GetVertexAttributeSize( layout.attribute ), GL_FLOAT, GL_FALSE, shader->m_stride, NULL );
|
|
|
|
// glEnableVertexAttribArray( i );
|
|
// glVertexAttribPointer( i, GetVertexAttributeSize( layout.attribute ), GL_FLOAT, GL_FALSE, shader->m_stride, NULL );
|
|
//}
|
|
|
|
ApplyVertexFormat( shader, shader->m_stride );
|
|
//for ( int i = 0; i < shader->m_layout_count; i++ )
|
|
//{
|
|
// const InputLayoutDesc_t& layout = shader->m_layouts[ i ];
|
|
//
|
|
// glEnableVertexAttribArray( shader->m_glLayouts[ i ] );
|
|
// glVertexAttribPointer( shader->m_glLayouts[ i ], GetVertexAttributeSize( layout.attribute ), GL_FLOAT, GL_FALSE, shader->m_stride, NULL );
|
|
//}
|
|
|
|
}
|
|
|
|
void ShaderSystem::SetUniformSampler(const Shader* shader, ShaderSamplers_t sampler, int index)
|
|
{
|
|
glGetError();
|
|
|
|
GLint uniformLocation = glGetUniformLocation(shader->m_program, g_samplersNameTable[sampler]);
|
|
glUniform1i(uniformLocation, static_cast<GLint>(index));
|
|
}
|
|
|
|
void ShaderSystem::SetUniformFloat4(const Shader* shader, ShaderUniform_t uniform, const void* data)
|
|
{
|
|
GLint location = glGetUniformLocation( shader->m_program, g_uniformNameTable[ uniform ] );
|
|
glUniform4fv( location, 1, ( const GLfloat* )data );
|
|
}
|
|
|
|
void ShaderSystem::SetUniformMatrix( const Shader* shader, ShaderUniform_t uniform, const void* data )
|
|
{
|
|
GLint location = glGetUniformLocation( shader->m_program, g_uniformNameTable[ uniform ] );
|
|
glUniformMatrix4fv( location, 1, GL_FALSE, ( const GLfloat* )data );
|
|
}
|
|
|
|
// #TODO: Move out
|
|
|
|
static const char* s_attributeNameTable[SHADERSEMANTIC_MAX] =
|
|
{
|
|
"a_position",//SHADERSEMANTIC_POSITION,
|
|
"a_color", //SHADERSEMANTIC_COLOR
|
|
"a_texcoord",//SHADERSEMANTIC_TEXCOORD,
|
|
"a_texcoord0", //SHADERSEMANTIC_TEXCOORD0,
|
|
"a_texcoord1",//SHADERSEMANTIC_TEXCOORD1,
|
|
"a_normal",//SHADERSEMANTIC_NORMAL,
|
|
"a_tangent",//SHADERSEMANTIC_TANGENT,
|
|
"a_bitangent"//SHADERSEMANTIC_BITANGENT,
|
|
};
|
|
|
|
void Shader::AllocateAttributes()
|
|
{
|
|
// Allocate input layout
|
|
for ( int i = 0; i < m_layout_count; i++ )
|
|
{
|
|
const InputLayoutDesc_t& layout = m_layouts[ i ];
|
|
// Msg( "Shader::AllocateAttributes: Bind %i as %s", i, s_attributeNameTable[ layout.semantic ] );
|
|
glBindAttribLocation( m_program, i, s_attributeNameTable[ layout.semantic ] );
|
|
|
|
GL_CHECK_ERROR();
|
|
|
|
// m_glLayouts[ i ] = glGetAttribLocation( m_program, s_attributeNameTable[i] );
|
|
// assert( m_glLayouts[ i ] );
|
|
}
|
|
}
|