333 lines
7.8 KiB
C++
333 lines
7.8 KiB
C++
#include "ShaderManager.h"
|
|
|
|
#include "Utilities/Log.h"
|
|
#include "Utilities/CfgParser.h"
|
|
|
|
// library includes
|
|
#include "physfs.h"
|
|
|
|
// system includes
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
using namespace std;
|
|
|
|
namespace BlueCore
|
|
{
|
|
//------------------------------------------------------------------------------
|
|
ShaderManager::ShaderManager(RenderWindow* renderwindow) :
|
|
_usingShaders(true), _RenderWindow(renderwindow)
|
|
{
|
|
glewInit();
|
|
|
|
if (GLEW_ARB_fragment_shader == false)
|
|
_usingShaders = false;
|
|
|
|
_RenderWindow->WindowCloseSignal.connect(this,
|
|
&ShaderManager::WindowCloseSlot);
|
|
|
|
clog << ">>> ShaderManager constructed ..."<< endline;
|
|
if (_usingShaders)
|
|
clog << " using shaders"<< endline;
|
|
else
|
|
clog << " shaders not supported!"<< endlog;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
ShaderManager::~ShaderManager()
|
|
{
|
|
clog << ">>> ShaderManager destructed ..."<< endlog;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void ShaderManager::shutdown()
|
|
{
|
|
clog << ">>> ShaderManager shutting down ..."<< endlog;
|
|
|
|
ShaderProgramMap::iterator prog_iter;
|
|
for (prog_iter = shader_programs.begin(); prog_iter!= shader_programs.end(); prog_iter++)
|
|
{
|
|
glDeleteObjectARB(prog_iter->second);
|
|
}
|
|
shader_programs.clear();
|
|
|
|
VertexShaderMap::iterator vert_iter;
|
|
for (vert_iter = vertex_shader.begin(); vert_iter != vertex_shader.end(); vert_iter++)
|
|
{
|
|
glDeleteObjectARB(vert_iter->second);
|
|
}
|
|
vertex_shader.clear();
|
|
|
|
FragmentShaderMap::iterator frag_iter;
|
|
for (frag_iter = fragment_shader.begin(); frag_iter!= fragment_shader.end(); frag_iter++)
|
|
{
|
|
glDeleteObjectARB(frag_iter->second);
|
|
}
|
|
fragment_shader.clear();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void ShaderManager::WindowCloseSlot()
|
|
{
|
|
shutdown();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
bool ShaderManager::usingShaders()
|
|
{
|
|
return _usingShaders;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void printInfoLog(GLhandleARB obj)
|
|
{
|
|
int infologLength = 0;
|
|
int charsWritten = 0;
|
|
char *infoLog;
|
|
|
|
glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB,
|
|
&infologLength);
|
|
|
|
if (infologLength > 1)
|
|
{
|
|
infoLog = new char[infologLength+1];
|
|
|
|
glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
|
|
|
|
clog << " "<< infoLog << endline;
|
|
|
|
delete [] infoLog;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
VertexShader ShaderManager::loadVertexShader(const string &name)
|
|
{
|
|
if ( !_usingShaders)
|
|
return 0;
|
|
|
|
// check if this mesh is already loaded
|
|
VertexShaderMap::const_iterator result;
|
|
|
|
result = vertex_shader.find(name);
|
|
|
|
if (result != vertex_shader.end() )
|
|
{
|
|
return result->second;
|
|
}
|
|
|
|
string filename = name + ".vert";
|
|
|
|
PHYSFS_file *file = PHYSFS_openRead(filename.c_str() );
|
|
|
|
if ( !file)
|
|
{
|
|
clog << "!!! VertexShader '"<< name << "' not found"<< endline;
|
|
return 0;
|
|
}
|
|
|
|
char *buffer = new char[ PHYSFS_fileLength ( file ) ];
|
|
|
|
PHYSFS_read(file, buffer, 1, PHYSFS_fileLength(file) );
|
|
buffer[ PHYSFS_fileLength ( file ) - 1] = 0;
|
|
|
|
PHYSFS_close(file);
|
|
|
|
VertexShader shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
|
|
|
|
glShaderSourceARB(shader, 1, ( const GLcharARB** ) &buffer, NULL);
|
|
|
|
delete [] buffer;
|
|
|
|
glCompileShaderARB(shader);
|
|
|
|
vertex_shader[name] = shader;
|
|
|
|
clog << ">>> VertexShader '"<< name << "' loaded"<< endline;
|
|
|
|
return shader;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
FragmentShader ShaderManager::loadFragmentShader(const string &name)
|
|
{
|
|
if ( !_usingShaders)
|
|
return 0;
|
|
|
|
// check if this mesh is already loaded
|
|
FragmentShaderMap::const_iterator result;
|
|
|
|
result = fragment_shader.find(name);
|
|
|
|
if (result != fragment_shader.end() )
|
|
{
|
|
return result->second;
|
|
}
|
|
|
|
string filename = name + ".frag";
|
|
|
|
PHYSFS_file *file = PHYSFS_openRead(filename.c_str() );
|
|
|
|
if ( !file)
|
|
{
|
|
clog << "!!! FragmentShader '"<< name << "' not found"<< endline;
|
|
return 0;
|
|
}
|
|
|
|
char *buffer = new char[ PHYSFS_fileLength ( file ) ];
|
|
|
|
PHYSFS_read(file, buffer, 1, PHYSFS_fileLength(file) );
|
|
buffer[ PHYSFS_fileLength ( file ) - 1] = 0;
|
|
|
|
PHYSFS_close(file);
|
|
|
|
FragmentShader shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
|
|
|
|
glShaderSourceARB(shader, 1, ( const GLcharARB** ) &buffer, NULL);
|
|
|
|
delete [] buffer;
|
|
|
|
glCompileShaderARB(shader);
|
|
|
|
printInfoLog(shader);
|
|
|
|
fragment_shader[name] = shader;
|
|
|
|
clog << ">>> FragmentShader '"<< name << "' loaded"<< endline;
|
|
|
|
return shader;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
ShaderProgram ShaderManager::loadShaderProgram(const std::string &name)
|
|
{
|
|
if ( !_usingShaders)
|
|
return 0;
|
|
|
|
if (name.empty() )
|
|
return 0;
|
|
|
|
// check if this mesh is already loaded
|
|
ShaderProgramMap::const_iterator result;
|
|
|
|
result = shader_programs.find(name);
|
|
|
|
if (result != shader_programs.end() )
|
|
{
|
|
return result->second;
|
|
}
|
|
|
|
string filename = name + ".prog";
|
|
|
|
PHYSFS_file *file = PHYSFS_openRead(filename.c_str() );
|
|
|
|
if ( !file)
|
|
{
|
|
clog << "!!! ShaderProgramm '"<< name << "' not found"<< endline;
|
|
return 0;
|
|
}
|
|
|
|
unsigned int length = PHYSFS_fileLength(file);
|
|
char *buffer = new char[length];
|
|
|
|
PHYSFS_read(file, buffer, 1, length);
|
|
PHYSFS_close(file);
|
|
|
|
CfgParser cfg;
|
|
cfg.parse(buffer, length);
|
|
|
|
delete [] buffer;
|
|
|
|
ShaderProgram program = glCreateProgramObjectARB();
|
|
|
|
std::vector<std::string> vertex_shaders;
|
|
if (cfg.getStrings("vertex_shaders", vertex_shaders) )
|
|
{
|
|
for (unsigned int i = 0; i < vertex_shaders.size(); i++)
|
|
{
|
|
VertexShader shader = loadVertexShader(vertex_shaders[i]);
|
|
|
|
if (shader != 0)
|
|
glAttachObjectARB(program, shader);
|
|
}
|
|
}
|
|
|
|
std::vector<std::string> fragment_shaders;
|
|
if (cfg.getStrings("fragment_shaders", fragment_shaders) )
|
|
{
|
|
for (unsigned int i = 0; i < fragment_shaders.size(); i++)
|
|
{
|
|
FragmentShader shader = loadFragmentShader(fragment_shaders[i]);
|
|
|
|
if (shader != 0)
|
|
glAttachObjectARB(program, shader);
|
|
}
|
|
}
|
|
|
|
glLinkProgramARB(program);
|
|
|
|
printInfoLog(program);
|
|
|
|
shader_programs[name] = program;
|
|
|
|
clog << ">>> ShaderProgramm '"<< name << "' loaded"<< endline;
|
|
|
|
return program;
|
|
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void ShaderManager::useShaderProgram(ShaderProgram shader_program)
|
|
{
|
|
if ( !_usingShaders)
|
|
return;
|
|
|
|
glUseProgramObjectARB(shader_program);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void ShaderManager::useTexture(ShaderProgram shader_program,
|
|
unsigned int texture, const std::string &name)
|
|
{
|
|
if ( !_usingShaders)
|
|
return;
|
|
|
|
GLint location = glGetUniformLocationARB(shader_program, name.c_str() );
|
|
|
|
//if( location > 0 )
|
|
glUniform1iARB(location, texture);
|
|
}
|
|
/*
|
|
//------------------------------------------------------------------------------
|
|
void ShaderManager::useTangentBuffer (
|
|
ShaderProgram shader_program,
|
|
TangentBuffer *tangent_buffer,
|
|
const std::string &name )
|
|
{
|
|
if ( !_usingShaders || !tangent_buffer )
|
|
return;
|
|
|
|
GLuint location = glGetAttribLocationARB ( shader_program, name.c_str() );
|
|
|
|
glEnableVertexAttribArrayARB ( location );
|
|
|
|
tangent_buffer->bind();
|
|
|
|
glVertexAttribPointerARB ( location, 3, GL_FLOAT, 0, 0, 0 );
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void ShaderManager::disableTangentBuffer (
|
|
ShaderProgram shader_program,
|
|
const std::string &name )
|
|
{
|
|
if ( !_usingShaders )
|
|
return;
|
|
|
|
GLuint location = glGetAttribLocationARB ( shader_program, name.c_str() );
|
|
|
|
glDisableVertexAttribArrayARB ( location );
|
|
}
|
|
*/
|
|
}
|