Files
pke/src/render/shadersystem.cpp
2026-02-26 14:46:29 +03:00

189 lines
4.5 KiB
C++

#include "shadersystem.h"
#include "shader.h"
#include "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",
};
static const char* g_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,
"a_boneIds",//SHADERSEMANTIC_BONEIDS,
"a_weights"//SHADERSEMANTIC_WEIGHTS,
};
static size_t g_attributeSizeTable[VERTEXATTR_MAX] =
{
sizeof(float) * 2,//VERTEXATTR_VEC2,
sizeof(float) * 3,//VERTEXATTR_VEC3,
sizeof(float) * 4,//VERTEXATTR_VEC4,
sizeof(unsigned int)//VERTEXATTR_UINT
};
size_t g_vertexAttribsSizeTable[VERTEXATTR_MAX] =
{
2, // VERTEXATTR_VEC2
3, // VERTEXATTR_VEC3
4, // VERTEXATTR_VEC4
4, // VERTEXATTR_UINT
};
size_t g_vertexAttribsRealSizeTable[VERTEXATTR_MAX] =
{
8, // VERTEXATTR_VEC2
12, // VERTEXATTR_VEC3
16, // VERTEXATTR_VEC4
4, // VERTEXATTR_UINT
};
ShaderSystem* g_shaderSystem = nullptr;
ShaderSystem::ShaderSystem()
{
}
ShaderSystem::~ShaderSystem()
{
}
void ShaderSystem::Init()
{
}
void ShaderSystem::Shutdown()
{
for (int i = 0; i < m_shaders.size(); i++)
{
if (m_shaders[i])
{
delete m_shaders[i];
m_shaders[i] = 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 Shader* shader) { return shader->GetName() == name; });
if ( it != m_shaders.end() )
{
return *it;
}
Shader* pShader = new Shader();
if ( inputLayout && inputLayoutCount > 0 )
{
memcpy( pShader->m_layouts, inputLayout, inputLayoutCount * sizeof( InputLayoutDesc_t ) );
pShader->m_layoutCount = inputLayoutCount;
}
pShader->Create( name, vsfilepath, psfilepath );
m_shaders.push_back(pShader);
return pShader;
}
void ShaderSystem::SetShader(const Shader* shader)
{
SDL_assert( shader );
glUseProgram( shader->m_program );
// apply input layout
size_t appliedOffset = 0;
for (int i = 0; i < shader->m_layoutCount; i++)
{
const InputLayoutDesc_t* layoutEntry = &shader->m_layouts[i];
glEnableVertexAttribArray(GLuint(i));
if (layoutEntry->attribute == VERTEXATTR_UINT)
{
glVertexAttribPointer(GLuint(i), GLint(g_vertexAttribsSizeTable[layoutEntry->attribute]),
GL_UNSIGNED_BYTE, GL_TRUE, static_cast<GLsizei>(shader->m_stride),
(appliedOffset > 0) ? (void*)(appliedOffset * sizeof(unsigned int)) : (void*)0);
}
else
{
glVertexAttribPointer(GLuint(i), GLint(g_vertexAttribsSizeTable[layoutEntry->attribute]),
GL_FLOAT, GL_FALSE, static_cast<GLsizei>(shader->m_stride),
(appliedOffset > 0) ? (void*)(appliedOffset * sizeof(float)) : (void*)0);
}
appliedOffset += g_vertexAttribsSizeTable[layoutEntry->attribute];
}
}
void ShaderSystem::SetUniformSampler(const Shader* shader, ShaderSamplers_t sampler, int index)
{
glUniform1i( shader->m_glSamplerLocation[ sampler ], static_cast< GLint >(index) );
}
void ShaderSystem::SetUniformFloat4(const Shader* shader, ShaderUniform_t uniform, const void* data)
{
glUniform4fv( shader->m_glUniformLocation[ uniform ], 1, ( const GLfloat* )data );
}
void ShaderSystem::SetUniformMatrix( const Shader* shader, ShaderUniform_t uniform, const void* data )
{
glUniformMatrix4fv( shader->m_glUniformLocation[ uniform ], 1, GL_FALSE, ( const GLfloat* )data );
}
void Shader::AllocateAttributes()
{
// Allocate input layout
for ( int i = 0; i < m_layoutCount; i++ )
{
const InputLayoutDesc_t& layout = m_layouts[ i ];
glBindAttribLocation( m_program, i, g_attributeNameTable[ layout.semantic ] );
GL_CHECK_ERROR();
// add element size to stride
m_stride += (int)g_attributeSizeTable[ layout.attribute ];
}
}
void Shader::AllocateUniforms()
{
// parse shader uniforms
for (int i = 0; i < UNIFORM_MAX; i++)
{
m_glUniformLocation[i] = glGetUniformLocation(m_program, g_uniformNameTable[i]);
}
// parse shader samplers
for (int i = 0; i < SAMPLER_MAX; i++)
{
m_glSamplerLocation[i] = glGetUniformLocation(m_program, g_samplersNameTable[i]);
}
}