Files
horror/src/engine/render/shadersystem.cpp
2024-06-10 12:48:14 +03:00

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