#include "stdafx.h" #include "Shaders.h" 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; } } 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; } return lh_Shader; } GLhandleARB createFragmentShader(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_FRAGMENT_SHADER); glShaderSource(lh_Shader, 1, (const char**)&ls_ShaderSource, NULL); 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; } 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; } 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; }