Files
eepp/src/graphics/cshader.cpp

232 lines
5.4 KiB
C++

#include "cshader.hpp"
#include "glhelper.hpp"
#include "renderer/crenderergl3.hpp"
namespace EE { namespace Graphics {
bool cShader::Ensure = true;
cShader::cShader( const Uint32& Type ) {
Init( Type );
}
cShader::cShader( const Uint32& Type, const std::string& Filename ) {
Init( Type );
if ( FileExists( Filename ) ) {
SafeDataPointer PData;
FileGet( Filename, PData );
SetSource( (const char*)PData.Data, PData.DataSize );
} else {
cLog::instance()->Write( std::string( "Couldn't open shader object: " ) + Filename );
}
Compile();
}
cShader::cShader( const Uint32& Type, const char * Data, const Uint32& DataSize ) {
Init( Type );
SetSource( Data, DataSize );
Compile();
}
cShader::cShader( const Uint32& Type, cPack * Pack, const std::string& Filename ) {
SafeDataPointer PData;
Init( Type );
if ( NULL != Pack && Pack->IsOpen() && -1 != Pack->Exists( Filename ) ) {
Pack->ExtractFileToMemory( Filename, PData );
SetSource( reinterpret_cast<char*> ( PData.Data ), PData.DataSize );
}
Compile();
}
cShader::cShader( const Uint32& Type, const char ** Data, const Uint32& NumLines ) {
Init( Type );
SetSource( Data, NumLines );
Compile();
}
cShader::~cShader() {
if ( 0 != mGLId )
glDeleteShader( mGLId );
}
void cShader::Init( const Uint32& Type ) {
mType = Type;
mValid = false;
mCompiled = false;
mGLId = glCreateShader( mType );
}
void cShader::Reload() {
Init( mType );
cShader::Ensure = false;
SetSource( mSource );
cShader::Ensure = true;
Compile();
}
void cShader::EnsureVersion() {
#ifdef EE_GL3_ENABLED
if ( cShader::Ensure && ( GLi->Version() == GLv_3 || GLi->Version() == GLv_ES2 ) ) {
cLog::instance()->Write( "Shader " + toStr( mGLId ) + " converted to programmable pipeline automatically." );
if ( GL_VERTEX_SHADER == mType ) {
if ( mSource.find( "ftransform" ) != std::string::npos ) {
mSource = GLi->GetRendererGL3()->GetBaseVertexShader();
}
} else {
if ( mSource.find( "gl_FragColor" ) != std::string::npos ) {
mSource = "#version 150\nuniform int dgl_TexActive = 1;\ninvariant in vec4 gl_Color;\ninvariant in vec4 gl_TexCoord[ 4 ];\nout vec4 gl_FragColor;\n" + mSource;
ReplaceSubStr( mSource, "gl_FragColor" , "dgl_FragColor" );
ReplaceSubStr( mSource, "gl_Color" , "dgl_Color" );
ReplaceSubStr( mSource, "gl_TexCoord" , "dgl_TexCoord" );
}
}
}
#endif
}
void cShader::SetSource( const std::string& Source ) {
if ( IsCompiled() ) {
cLog::instance()->Write( "Can't set source for compiled shaders" );
return;
}
mSource = Source;
EnsureVersion();
const char * src = reinterpret_cast<const char *> ( &mSource[0] );
glShaderSource( mGLId, 1, &src, NULL );
}
void cShader::SetSource( const char** Data, const Uint32& NumLines ) {
std::string tstr;
for ( Uint32 i = 0; i < NumLines; i++ ) {
tstr += std::string( Data[i] );
}
SetSource( tstr );
}
void cShader::SetSource( const char * Data, const Uint32& DataSize ) {
std::string _dst( DataSize, 0 );
memcpy( reinterpret_cast<void*>( &_dst[0] ), reinterpret_cast<const void*>( &Data[0] ), DataSize );
SetSource( _dst );
}
void cShader::SetSource( const std::vector<Uint8>& Source ) {
std::string _dst( Source.size(), 0 );
memcpy( reinterpret_cast<void*>( &_dst[0] ), reinterpret_cast<const void*>( &Source[0] ), Source.size() );
SetSource( _dst );
}
bool cShader::Compile() {
if ( IsCompiled() ) {
cLog::instance()->Write( "Can't compile a shader twice" );
return false;
}
glCompileShader( GetId() );
mCompiled = true;
int Compiled;
glGetShaderiv( GetId(), GL_COMPILE_STATUS, &Compiled );
mValid = 0 != Compiled;
if ( !mValid ) {
GLsizei logsize, logarraysize;
glGetShaderiv( GetId(), GL_INFO_LOG_LENGTH, &logarraysize );
mCompileLog.resize( logarraysize - 1 );
glGetShaderInfoLog( GetId(), logarraysize, &logsize, reinterpret_cast<GLchar*>( &mCompileLog[0] ) );
cLog::instance()->Write( "Couldn't compile shader. Log follows:" );
cLog::instance()->Write( mCompileLog );
cLog::instance()->Write( mSource );
#ifdef EE_DEBUG
std::cout << "Couldn't compile shader. Log follows:" << std::endl;
std::cout << mCompileLog << std::endl;
std::cout << mSource << std::endl;
#endif
} else {
cLog::instance()->Write( "Shader Loaded Succesfully" );
}
return mValid;
}
cVertexShader::cVertexShader() :
cShader( GL_VERTEX_SHADER )
{
}
cVertexShader::cVertexShader( const std::string& Filename ) :
cShader( GL_VERTEX_SHADER, Filename )
{
}
cVertexShader::cVertexShader( const char * Data, const Uint32& DataSize ) :
cShader( GL_VERTEX_SHADER, Data, DataSize )
{
}
cVertexShader::cVertexShader( cPack * Pack, const std::string& Filename ) :
cShader( GL_VERTEX_SHADER, Pack, Filename )
{
}
cVertexShader::cVertexShader( const char ** Data, const Uint32& NumLines ) :
cShader( GL_VERTEX_SHADER, Data, NumLines )
{
}
cFragmentShader::cFragmentShader() :
cShader( GL_FRAGMENT_SHADER )
{
}
cFragmentShader::cFragmentShader( const std::string& Filename ) :
cShader( GL_FRAGMENT_SHADER, Filename )
{
}
cFragmentShader::cFragmentShader( const char * Data, const Uint32& DataSize ) :
cShader( GL_FRAGMENT_SHADER, Data, DataSize )
{
}
cFragmentShader::cFragmentShader( cPack * Pack, const std::string& Filename ) :
cShader( GL_FRAGMENT_SHADER, Pack, Filename )
{
}
cFragmentShader::cFragmentShader( const char ** Data, const Uint32& NumLines ) :
cShader( GL_FRAGMENT_SHADER, Data, NumLines )
{
}
}}