364 lines
9.4 KiB
C++
364 lines
9.4 KiB
C++
#include "Shaders.h"
|
|
|
|
//#define DEBUG_COMPRESSED_SHADER
|
|
|
|
#ifdef _DEBUG
|
|
|
|
PFNGLCREATESHADERPROC glCreateShader = NULL;
|
|
PFNGLSHADERSOURCEPROC glShaderSource = NULL;
|
|
PFNGLCOMPILESHADERPROC glCompileShader = NULL;
|
|
PFNGLGETSHADERIVPROC glGetShaderiv = NULL;
|
|
PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL;
|
|
PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
|
|
PFNGLATTACHSHADERPROC glAttachShader = NULL;
|
|
PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
|
|
PFNGLUSEPROGRAMPROC glUseProgram = NULL;
|
|
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL;
|
|
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL;
|
|
|
|
|
|
void useProgram(GLhandleARB ah_Program)
|
|
{
|
|
glUseProgram(ah_Program);
|
|
}
|
|
|
|
|
|
void initShaders()
|
|
{
|
|
glCreateShader = (PFNGLCREATESHADERPROC)myGetProcAddress("glCreateShader");
|
|
glShaderSource = (PFNGLSHADERSOURCEPROC)myGetProcAddress("glShaderSource");
|
|
glCompileShader = (PFNGLCOMPILESHADERPROC)myGetProcAddress("glCompileShader");
|
|
glGetShaderiv = (PFNGLGETSHADERIVPROC)myGetProcAddress("glGetShaderiv");
|
|
glGetProgramiv = (PFNGLGETPROGRAMIVPROC)myGetProcAddress("glGetProgramiv");
|
|
glCreateProgram = (PFNGLCREATEPROGRAMPROC)myGetProcAddress("glCreateProgram");
|
|
glAttachShader = (PFNGLATTACHSHADERPROC)myGetProcAddress("glAttachShader");
|
|
glLinkProgram = (PFNGLLINKPROGRAMPROC)myGetProcAddress("glLinkProgram");
|
|
glUseProgram = (PFNGLUSEPROGRAMPROC)myGetProcAddress("glUseProgram");
|
|
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)myGetProcAddress("glGetShaderInfoLog");
|
|
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)myGetProcAddress("glGetProgramInfoLog");
|
|
|
|
if (!(glCreateShader && glShaderSource && glCompileShader && glGetShaderiv && glGetProgramiv && glCreateProgram && glAttachShader && glLinkProgram && glUseProgram && glGetShaderInfoLog && glGetProgramInfoLog))
|
|
{
|
|
std::cerr << "Some shader functions are not available!" << std::endl;
|
|
}
|
|
}
|
|
|
|
#include <sstream>
|
|
#include <fstream>
|
|
|
|
std::string ReplaceString(const std::string &stringSearchString, const std::string &stringReplaceString, std::string stringStringToReplace)
|
|
{
|
|
std::string::size_type pos = stringStringToReplace.find(stringSearchString, 0);
|
|
int intLengthSearch = stringSearchString.length();
|
|
int intLengthReplacment = stringReplaceString.length();
|
|
|
|
while(std::string::npos != pos)
|
|
{
|
|
stringStringToReplace.replace(pos, intLengthSearch, stringReplaceString);
|
|
pos = stringStringToReplace.find(stringSearchString, pos + intLengthReplacment);
|
|
}
|
|
|
|
return stringStringToReplace;
|
|
}
|
|
|
|
std::string MakeFileName( const char* as_FileName, int ShaderID, bool bDebug )
|
|
{
|
|
std::stringstream ss;
|
|
ss << as_FileName << "_" << ShaderID;
|
|
if( bDebug )
|
|
{
|
|
ss << "_dbg";
|
|
}
|
|
return ss.str();
|
|
}
|
|
|
|
void CreateSubShader( const char* as_FileName, int ShaderID, bool bDebug )
|
|
{
|
|
char* ls_ShaderSource = textFileRead(as_FileName);
|
|
std::string strData= ls_ShaderSource;
|
|
std::string strNewData;
|
|
bool bRemove= false;
|
|
for( size_t i= 0; i < strData.size(); ++i )
|
|
{
|
|
bool bEndRemove= false;
|
|
if( strData[ i ] == '@' )
|
|
{
|
|
if( i + 2 >= strData.size() )
|
|
{
|
|
break;
|
|
}
|
|
i++;
|
|
if( strData[ i ] == '@' )
|
|
{
|
|
bRemove= false;
|
|
}
|
|
else if( strData[ i ] == 'D' )
|
|
{
|
|
bRemove= !bDebug;
|
|
}
|
|
else
|
|
{
|
|
int ID= (int)(strData[ i ] - '0');
|
|
bRemove= ID!=ShaderID;
|
|
}
|
|
i++;
|
|
}
|
|
if( !bRemove || strData[ i ] == 10 || strData[ i ] == 13)
|
|
{
|
|
strNewData+= strData[ i ];
|
|
}
|
|
}
|
|
|
|
std::string strFileOut= MakeFileName( as_FileName, ShaderID, bDebug );
|
|
std::ofstream ofs(strFileOut.c_str());
|
|
|
|
// some Renaming
|
|
/*strNewData= ReplaceString( "rayDir","q", strNewData);
|
|
strNewData= ReplaceString( "cRes","b", strNewData);
|
|
strNewData= ReplaceString( "cFac","a", strNewData);
|
|
strNewData= ReplaceString( "CurStep","d", strNewData);
|
|
strNewData= ReplaceString( "CurStep","d", strNewData);
|
|
strNewData= ReplaceString( "rotate","r", strNewData);
|
|
strNewData= ReplaceString( "repeatHex","sh", strNewData);
|
|
strNewData= ReplaceString( "repeat","s", strNewData);
|
|
strNewData= ReplaceString( "pi2","P", strNewData);
|
|
strNewData= ReplaceString( "sqrtOf075","Q", strNewData);
|
|
strNewData= ReplaceString( "EndlessBar","O", strNewData);
|
|
strNewData= ReplaceString( "CurTime","R", strNewData);
|
|
strNewData= ReplaceString( "CurScene","S", strNewData);
|
|
strNewData= ReplaceString( "torus","T", strNewData);
|
|
strNewData= ReplaceString( "noise3D","N", strNewData);
|
|
strNewData= ReplaceString( "smoothnoise","M", strNewData);*/
|
|
|
|
ofs << strNewData;
|
|
}
|
|
|
|
void CreateAllSubShader( const char* as_FileName )
|
|
{
|
|
for( int i= 0; i < MAX_SHADER_ID; ++i )
|
|
{
|
|
CreateSubShader( as_FileName, i, true );
|
|
CreateSubShader( as_FileName, i, false );
|
|
}
|
|
}
|
|
|
|
void PrintErrors()
|
|
{
|
|
GLenum lr_Error = GL_NO_ERROR;
|
|
int li_ErrorCount = 5;
|
|
do
|
|
{
|
|
lr_Error = glGetError();
|
|
if (lr_Error != GL_NO_ERROR)
|
|
{
|
|
li_ErrorCount--;
|
|
char* ls_ErrorString = (char*)gluErrorString(lr_Error);
|
|
if (ls_ErrorString != 0)
|
|
std::cout << "OPENGL :: ERROR " << ls_ErrorString << std::endl;
|
|
}
|
|
if (li_ErrorCount == 0)
|
|
{
|
|
std::cout << "OPENGL :: ERROR Too many errors!" << std::endl;
|
|
break;
|
|
}
|
|
} while (lr_Error != GL_NO_ERROR);
|
|
}
|
|
|
|
|
|
GLhandleARB createVertexShader(const char* as_FileName)
|
|
{
|
|
GLhandleARB lh_Shader = 0;
|
|
|
|
char* ls_ShaderSource = textFileRead(as_FileName);
|
|
|
|
if (ls_ShaderSource == NULL)
|
|
{
|
|
std::cerr << "Error reading file: " << as_FileName << std::endl;
|
|
return lh_Shader;
|
|
}
|
|
|
|
lh_Shader = glCreateShader(GL_VERTEX_SHADER);
|
|
|
|
glShaderSource(lh_Shader, 1, (const char**)&ls_ShaderSource, NULL);
|
|
glCompileShader(lh_Shader);
|
|
|
|
free(ls_ShaderSource);
|
|
|
|
int li_Status = 0;
|
|
glGetShaderiv(lh_Shader, GL_COMPILE_STATUS, &li_Status);
|
|
|
|
if (li_Status == GL_FALSE)
|
|
{
|
|
std::cerr << "Error compiling vertex shader: " << as_FileName << std::endl;
|
|
printShaderInfoLog(lh_Shader);
|
|
}
|
|
|
|
return lh_Shader;
|
|
}
|
|
|
|
|
|
#ifdef DEBUG_COMPRESSED_SHADER
|
|
#include "shader_code.h"
|
|
#endif
|
|
|
|
GLhandleARB createFragmentShader(const char* as_FileName, int ShaderID, bool bDebug)
|
|
{
|
|
CreateAllSubShader( as_FileName );
|
|
|
|
GLhandleARB lh_Shader = 0;
|
|
|
|
char* ls_ShaderSource = textFileRead(MakeFileName(as_FileName, ShaderID, bDebug).c_str());
|
|
if (ls_ShaderSource == NULL)
|
|
{
|
|
std::cerr << "Error reading file: " << as_FileName << std::endl;
|
|
return lh_Shader;
|
|
}
|
|
|
|
lh_Shader = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
|
glShaderSource(lh_Shader, 1, (const char**)&ls_ShaderSource, NULL);
|
|
#ifdef DEBUG_COMPRESSED_SHADER
|
|
glShaderSource(lh_Shader, 1, (const char**)&mark_fs, NULL);
|
|
#endif
|
|
glCompileShader(lh_Shader);
|
|
|
|
int li_Status = 0;
|
|
|
|
glGetShaderiv(lh_Shader, GL_COMPILE_STATUS, &li_Status);
|
|
|
|
if (li_Status == GL_FALSE)
|
|
{
|
|
std::cerr << "Error compiling fragment shader: " << as_FileName << std::endl;
|
|
printShaderInfoLog(lh_Shader);
|
|
}
|
|
|
|
free(ls_ShaderSource);
|
|
|
|
return lh_Shader;
|
|
}
|
|
|
|
|
|
GLhandleARB createProgram(GLhandleARB ah_VertexShader, GLhandleARB ah_FragmentShader)
|
|
{
|
|
GLhandleARB lh_Program = 0;
|
|
|
|
if (ah_VertexShader + ah_FragmentShader <= 1)
|
|
{
|
|
std::cerr << "Cannot create program." << std::endl;
|
|
return lh_Program;
|
|
}
|
|
|
|
lh_Program = glCreateProgram();
|
|
|
|
glAttachShader(lh_Program, ah_VertexShader);
|
|
glAttachShader(lh_Program, ah_FragmentShader);
|
|
glLinkProgram(lh_Program);
|
|
|
|
int li_Status = 0;
|
|
|
|
glGetProgramiv(lh_Program, GL_LINK_STATUS, &li_Status);
|
|
|
|
if (li_Status == GL_FALSE)
|
|
{
|
|
std::cerr << "Error linking shaders." << std::endl;
|
|
printProgramInfoLog(lh_Program);
|
|
}
|
|
|
|
return lh_Program;
|
|
}
|
|
|
|
|
|
char* textFileRead(const char* as_FileName)
|
|
{
|
|
FILE* lh_File;
|
|
char* ls_Content = NULL;
|
|
size_t li_Count = 0;
|
|
|
|
if (as_FileName != NULL)
|
|
{
|
|
fopen_s(&lh_File, as_FileName, "rt");
|
|
|
|
if (lh_File != NULL)
|
|
{
|
|
fseek(lh_File, 0, SEEK_END);
|
|
li_Count = ftell(lh_File);
|
|
rewind(lh_File);
|
|
|
|
if (li_Count > 0)
|
|
{
|
|
ls_Content = (char*) malloc(sizeof(char) * (li_Count + 1));
|
|
li_Count = fread(ls_Content, sizeof(char), li_Count, lh_File);
|
|
ls_Content[li_Count] = '\0';
|
|
}
|
|
|
|
fclose(lh_File);
|
|
}
|
|
}
|
|
|
|
return ls_Content;
|
|
}
|
|
|
|
|
|
void printShaderInfoLog(GLhandleARB ah_Shader)
|
|
{
|
|
int li_InfologLength = 0;
|
|
int li_CharsWritten = 0;
|
|
char* li_InfoLog;
|
|
|
|
glGetShaderiv(ah_Shader, GL_INFO_LOG_LENGTH, &li_InfologLength);
|
|
|
|
if (li_InfologLength > 0)
|
|
{
|
|
li_InfoLog = (char*) malloc(li_InfologLength);
|
|
|
|
glGetShaderInfoLog(ah_Shader, li_InfologLength, &li_CharsWritten, li_InfoLog);
|
|
|
|
std::cerr << li_InfoLog << std::endl;
|
|
free(li_InfoLog);
|
|
}
|
|
}
|
|
|
|
|
|
void printProgramInfoLog(GLhandleARB ah_Program)
|
|
{
|
|
int li_InfologLength = 0;
|
|
int li_CharsWritten = 0;
|
|
char* ls_InfoLog;
|
|
|
|
glGetProgramiv(ah_Program, GL_INFO_LOG_LENGTH, &li_InfologLength);
|
|
|
|
if (li_InfologLength > 0)
|
|
{
|
|
ls_InfoLog = (char *)malloc(li_InfologLength);
|
|
|
|
glGetProgramInfoLog(ah_Program, li_InfologLength, &li_CharsWritten, ls_InfoLog);
|
|
|
|
std::cerr << ls_InfoLog << std::endl;
|
|
free(ls_InfoLog);
|
|
}
|
|
}
|
|
|
|
|
|
bool printShaderStatistics()
|
|
{
|
|
if (GL_VERSION_2_1) std::cout << "Supports OpenGL 2.1. " << std::endl;
|
|
else if (GL_VERSION_2_0) std::cout << "Supports OpenGL 2.0. " << std::endl;
|
|
else if (GL_VERSION_1_5) std::cout << "Supports OpenGL 1.5. " << std::endl;
|
|
else if (GL_VERSION_1_4) std::cout << "Supports OpenGL 1.4. " << std::endl;
|
|
else if (GL_VERSION_1_3) std::cout << "Supports OpenGL 1.3. " << std::endl;
|
|
else if (GL_VERSION_1_2) std::cout << "Supports OpenGL 1.2. " << std::endl;
|
|
else if (GL_VERSION_1_1) std::cout << "Supports OpenGL 1.1. " << std::endl;
|
|
|
|
if (GL_ARB_shader_objects && GL_ARB_vertex_shader && GL_ARB_fragment_shader)
|
|
{
|
|
std::cout << "Status: Using GLSL " << glGetString(GL_SHADING_LANGUAGE_VERSION_ARB) << std::endl;
|
|
}
|
|
else
|
|
{
|
|
std::cerr << "No GLSL support!" << std::endl;
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
#endif |