//#define DEBUG_COMPRESSED_SHADER #ifdef _DEBUG #include "Shaders.h" #include #include #include 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; } } 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 //#include "mark_small.h"; 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); /*const char* ShaderSource1[]= { mark_fs_0, mark_fs_p1_0, mark_fs_p2, mark_fs_p3_0, mark_fs_p4, mark_fs_p5_0, mark_fs_p6, }; glShaderSource(lh_Shader, 7, ShaderSource1, NULL);*/ 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; } 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; } void printShaderInfoLog(GLhandleARB ah_Shader) { int li_InfologLength = 0; int li_CharsWritten = 0; static char ls_InfoLog[8192]; ((PFNGLGETSHADERIVPROC)wglGetProcAddress("glGetShaderiv"))(ah_Shader, GL_INFO_LOG_LENGTH, &li_InfologLength); if (li_InfologLength > 0) { ((PFNGLGETSHADERINFOLOGPROC)wglGetProcAddress("glGetShaderInfoLog"))(ah_Shader, li_InfologLength, &li_CharsWritten, ls_InfoLog); OutputDebugString(ls_InfoLog); OutputDebugString("\n"); } } void printProgramInfoLog(GLhandleARB ah_Program) { int li_InfologLength = 0; int li_CharsWritten = 0; static char ls_InfoLog[8192]; ((PFNGLGETPROGRAMIVPROC)wglGetProcAddress("glGetProgramiv"))(ah_Program, GL_INFO_LOG_LENGTH, &li_InfologLength); if (li_InfologLength > 0) { ((PFNGLGETPROGRAMINFOLOGPROC)wglGetProcAddress("glGetProgramInfoLog"))(ah_Program, li_InfologLength, &li_CharsWritten, ls_InfoLog); OutputDebugString(ls_InfoLog); OutputDebugString("\n"); } } #endif