#include #include #include "utils/logger.h" #include "render/shadersystem.h" #include "render/shader.h" #include 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() { LogMsg("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*/) { for (int i = 0; i < m_shaders.size(); i++) { if (m_shaders[i].name == name) return m_shaders[i].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(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(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 ] ); } }