GLShader::GLShader(EGLShaderType type, const string &filename) :m_ID(GL_NONE), m_type(type) { // Check if file exists if(!fileExists(filename)) { cerr << "Shader source file '" << filename << "' does not exist." << endl; } // File exists else { // Create shader m_ID = glCreateShader(getShaderTypeConstant(type)); if(m_ID == GL_NONE) { cerr << "Could not create OpenGL shader." << endl; } // Successfully created shader else { cout << "Created OpenGL shader: " << m_ID << endl; // Load shader source string line, source; ifstream sourceStream(filename); while(sourceStream.good() && !sourceStream.eof()) { getline(sourceStream, line); source.append(line + "\n"); } // Compile shader const char *sourceCString = source.c_str(); glShaderSource(m_ID, 1, &sourceCString, nullptr); glCompileShader(m_ID); // Check compilation GLint compileResult; glGetShaderiv(m_ID, GL_COMPILE_STATUS, &compileResult); if(compileResult != GL_TRUE) { cerr << "Shader compilation of file '" << filename << "' failed." << endl; GLsizei logLength; GLchar log[1024]; glGetShaderInfoLog( m_ID, sizeof(log), &logLength, log); cerr << "Shader info log: " << endl << log << endl; } // Compilation worked else { cout << "Successfully compiled shader '" << filename << "'" << endl; } } } }
GLuint loadShaderFile(const GLenum type, const char* filename, const uint glslVersion) { GLuint shader; GLint compiled; // create the shader object shader = glCreateShader(type); FILE* commonShaderFile; std::string shaderSource; // load the common definitions from Common if (type == GL_VERTEX_SHADER) { char vertexShaderFileName[256]; if (glslVersion == 0) { sprintf_s(vertexShaderFileName, "%s/shaders/Common_vOld.vert", CONST_STR("resourcesDir").c_str()); } else { sprintf_s(vertexShaderFileName, "%s/shaders/Common_v%d.vert", CONST_STR("resourcesDir").c_str(), glslVersion); } if (fopen_s(&commonShaderFile, vertexShaderFileName, "rb") != 0) { TRACE_ERROR("Error: Error loading common vertex shader definitions.", 0); return 0; } } else { char fragmentShaderFileName[256]; if (glslVersion == 0) { sprintf_s(fragmentShaderFileName, "%s/shaders/Common_vOld.frag", CONST_STR("resourcesDir").c_str()); } else { sprintf_s(fragmentShaderFileName, "%s/shaders/Common_v%d.frag", CONST_STR("resourcesDir").c_str(), glslVersion); } if (fopen_s(&commonShaderFile, fragmentShaderFileName, "rb") != 0) { TRACE_ERROR("Error: Error loading common fragment shader definitions.", 0); return 0; } } fseek(commonShaderFile, 0, SEEK_END); long size = ftell(commonShaderFile); fseek(commonShaderFile, 0, SEEK_SET); char* shaderSrc = new char[size + 1]; fread(shaderSrc, sizeof(char), size, commonShaderFile); fclose(commonShaderFile); shaderSrc[size] = 0; shaderSource = shaderSrc; delete[] shaderSrc; // load the file FILE* shaderFile; if (fopen_s(&shaderFile, filename, "rb" ) != 0) { return 0; } fseek(shaderFile, 0, SEEK_END); size = ftell(shaderFile); fseek(shaderFile, 0, SEEK_SET); shaderSrc = new char[size + 1]; fread(shaderSrc, sizeof(char), size, shaderFile); fclose(shaderFile); shaderSrc[size] = 0; shaderSource += shaderSrc; delete[] shaderSrc; shaderSrc = (char*) shaderSource.c_str(); shaderSrc[shaderSource.size()] = 0; glShaderSource(shader, 1, (const char**) &shaderSrc, nullptr); // compile the shader glCompileShader(shader); // check the compile status glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); if (!compiled) { GLint infoLen = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { char* infoLog = new char[infoLen]; glGetShaderInfoLog(shader, infoLen, nullptr, infoLog); TRACE_ERROR("Error: Error compiling shader <" << filename << ">:" << std::endl << infoLog, 0); delete[] infoLog; } glDeleteShader(shader); return 0; } return shader; }
GLuint Shader::load(const char * filename, GLenum shader_type, bool check_errors) { GLuint result = 0; FILE * fp; size_t filesize; char * data; fp = fopen(filename, "rb"); if (!fp) { printf("Can't read the file: %s.", filename); return 0; } fseek(fp, 0, SEEK_END); filesize = ftell(fp); fseek(fp, 0, SEEK_SET); data = new char[filesize + 1]; if (!data) goto fail_data_alloc; fread(data, 1, filesize, fp); data[filesize] = 0; fclose(fp); result = glCreateShader(shader_type); if (!result) goto fail_shader_alloc; glShaderSource(result, 1, (const GLchar**)&data, NULL); delete[] data; glCompileShader(result); if (check_errors) { GLint status = 0; glGetShaderiv(result, GL_COMPILE_STATUS, &status); if (!status) { char buffer[4096]; glGetShaderInfoLog(result, 4096, NULL, buffer); #ifdef _WIN32 printf(filename); printf(":"); printf(buffer); printf("\n"); #else fprintf(stderr, "%s: %s\n", filename, buffer); #endif goto fail_compile_shader; } } return result; fail_compile_shader: glDeleteShader(result); fail_shader_alloc:; fail_data_alloc: return result; }
/*!**************************************************************************** @Function InitView @Return bool true if no error occured @Description Code in InitView() will be called by PVRShell upon initialization or after a change in the rendering context. Used to initialize variables that are dependant on the rendering context (e.g. textures, vertex buffers, etc.) ******************************************************************************/ bool OGLES3BinaryShader::InitView() { // Initialise a colour to draw our triangle // (For this training course, binary loaded shaders use a different colour // To show which is being used. Red means it had to compile the shaders, // green shows that it retrieved the binary from memory. float afColour[]={0.0,0.0,0.0}; // Filename and path strings. char* pWritePath = (char*)PVRShellGet(prefWritePath); char* shaderPath = new char[strlen(pWritePath) + 13]; sprintf(shaderPath, "%sShaderBinary", pWritePath); // If binary shaders are not supported or there isn't a valid binary shader stored, recompile the shaders. if(!loadBinaryProgram(shaderPath,m_uiProgramObject)) { { // Fragment shader code const char* pszFragShader = "\ #version 300 es\n\ uniform lowp vec3 myColour;\ layout (location = 0) out lowp vec4 oColour;\ void main (void)\ {\ oColour = vec4(myColour, 1.0);\ }"; // Create the fragment shader object m_uiFragShader = glCreateShader(GL_FRAGMENT_SHADER); // Load the source code into it glShaderSource(m_uiFragShader, 1, (const char**)&pszFragShader, NULL); // Compile the source code glCompileShader(m_uiFragShader); // Check if compilation succeeded GLint bShaderCompiled; glGetShaderiv(m_uiFragShader, GL_COMPILE_STATUS, &bShaderCompiled); if (!bShaderCompiled) { // An error happened, first retrieve the length of the log message int i32InfoLogLength, i32CharsWritten; glGetShaderiv(m_uiFragShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength); // Allocate enough space for the message and retrieve it char* pszInfoLog = new char[i32InfoLogLength]; glGetShaderInfoLog(m_uiFragShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog); /* Displays the message in a dialog box when the application quits using the shell PVRShellSet function with first parameter prefExitMessage. */ char* pszMsg = new char[i32InfoLogLength+256]; strcpy(pszMsg, "Failed to compile fragment shader: "); strcat(pszMsg, pszInfoLog); PVRShellSet(prefExitMessage, pszMsg); delete [] pszMsg; delete [] pszInfoLog; delete [] shaderPath; return false; } } { // Vertex shader code. const char* pszVertShader = "\ #version 300 es\n\ layout (location = 0) in highp vec4 myVertex;\ uniform mediump mat4 myPMVMatrix;\ void main(void)\ {\ gl_Position = myPMVMatrix * myVertex;\ }"; // Loads the vertex shader in the same way m_uiVertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(m_uiVertexShader, 1, (const char**)&pszVertShader, NULL); glCompileShader(m_uiVertexShader); // Checks if the shader has compiled. GLint bShaderCompiled; glGetShaderiv(m_uiVertexShader, GL_COMPILE_STATUS, &bShaderCompiled); if (!bShaderCompiled) { int i32InfoLogLength, i32CharsWritten; glGetShaderiv(m_uiVertexShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength); char* pszInfoLog = new char[i32InfoLogLength]; glGetShaderInfoLog(m_uiVertexShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog); char* pszMsg = new char[i32InfoLogLength+256]; strcpy(pszMsg, "Failed to compile vertex shader: "); strcat(pszMsg, pszInfoLog); PVRShellSet(prefExitMessage, pszMsg); delete [] pszMsg; delete [] pszInfoLog; delete [] shaderPath; return false; } } // Create the shader program m_uiProgramObject = glCreateProgram(); // Attach the fragment and vertex shaders to the shader program. glAttachShader(m_uiProgramObject, m_uiFragShader); glAttachShader(m_uiProgramObject, m_uiVertexShader); // Bind the custom vertex attribute "myVertex" to location VERTEX_ARRAY glBindAttribLocation(m_uiProgramObject, VERTEX_ARRAY, "myVertex"); // Link the program glLinkProgram(m_uiProgramObject); // Check if linking succeeded in the same way we checked for compilation success GLint bLinked; glGetProgramiv(m_uiProgramObject, GL_LINK_STATUS, &bLinked); if (!bLinked) { int i32InfoLogLength, i32CharsWritten; glGetProgramiv(m_uiProgramObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength); char* pszInfoLog = new char[i32InfoLogLength]; glGetProgramInfoLog(m_uiProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog); char* pszMsg = new char[i32InfoLogLength+256]; strcpy(pszMsg, "Failed to link program: "); strcat(pszMsg, pszInfoLog); PVRShellSet(prefExitMessage, pszMsg); delete [] pszMsg; delete [] pszInfoLog; delete [] shaderPath; return false; } // As there is no stored binary, save the current binary out for use later. // Note that this is done after both binding attributes and linking - // none of these can be performed after saveBinaryProgram(shaderPath,m_uiProgramObject); //Set red channel of the colour to maximum - red shows that the shaders had to be compiled. afColour[0]=1.0f; } else { //Set green channel of the colour to maximum - green shows that the shaders were loaded from binary files. afColour[1]=1.0f; } delete[] shaderPath; // Uses the program. glUseProgram(m_uiProgramObject); // Bind the colour to the fragment shader. GLint i32ColourLocation = glGetUniformLocation(m_uiProgramObject, "myColour"); // Then passes the colour to that variable glUniform3fv(i32ColourLocation, 1, afColour); // Sets the clear color glClearColor(0.6f, 0.8f, 1.0f, 1.0f); // Create VBO for the triangle from our data // Vertex data GLfloat afVertices[] = {-0.4f,-0.4f,0.0f, 0.4f,-0.4f,0.0f, 0.0f,0.4f,0.0f}; // Gen VBO glGenBuffers(1, &m_ui32Vbo); // Bind the VBO glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo); // Set the buffer's data glBufferData(GL_ARRAY_BUFFER, 3 * (3 * sizeof(GLfloat)) /* 3 Vertices of 3 floats in size */, afVertices, GL_STATIC_DRAW); // Unbind the VBO glBindBuffer(GL_ARRAY_BUFFER, 0); // Enable culling glEnable(GL_CULL_FACE); return true; }
String logObjectInfo(const String& msg, const GLuint obj) { String logMessage = msg; // Invalid object. if (obj <= 0) { return logMessage; } GLint infologLength = 0; GLboolean isShader = glIsShader(obj); GLboolean isProgramPipeline = glIsProgramPipeline(obj); GLboolean isProgram = glIsProgram(obj); if (isShader) { OGRE_CHECK_GL_ERROR(glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &infologLength)); } else if (isProgramPipeline && Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { //FIXME Crashes on NVIDIA? See GL3+ GSoC forum // posts around 2013-11-25. OGRE_CHECK_GL_ERROR(glGetProgramPipelineiv(obj, GL_INFO_LOG_LENGTH, &infologLength)); } else if (isProgram) { OGRE_CHECK_GL_ERROR(glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &infologLength)); } // No info log available. // if (infologLength <= 1) if (infologLength < 1) { return logMessage; } GLint charsWritten = 0; char * infoLog = new char [infologLength]; infoLog[0] = 0; if (isShader) { OGRE_CHECK_GL_ERROR(glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog)); } else if (isProgramPipeline && Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { OGRE_CHECK_GL_ERROR(glGetProgramPipelineInfoLog(obj, infologLength, &charsWritten, infoLog)); } else if (isProgram) { OGRE_CHECK_GL_ERROR(glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog)); } if (strlen(infoLog) > 0) { logMessage += "\n" + String(infoLog); } delete [] infoLog; if (logMessage.size() > 0) { // Remove empty lines from the end of the log. while (logMessage[logMessage.size() - 1] == '\n') { logMessage.erase(logMessage.size() - 1, 1); } LogManager::getSingleton().logMessage(logMessage); } return logMessage; }
bool Shader::initialiserTypeShader(GLuint &shader, GLenum type, std::string const &source) { // Génération de l'objet OpenGL Shader if(type == GL_VERTEX_SHADER) shader = glCreateShader(type); else if(type == GL_FRAGMENT_SHADER) shader = glCreateShader(GL_FRAGMENT_SHADER); else { glDeleteShader(shader); return false; } // Ouverture du fichier source std::string codeSource, ligneCodeSource; std::ifstream fichierSource(source.c_str()); // On test l'ouverture du fichier if(!fichierSource) { std::cout << "Erreur le fichier : " << source << " n'existe pas" << std::endl; glDeleteShader(shader); return false; } // Si le fichier existe et qu'il est ouvert, alors on peut lire son contenu while(getline(fichierSource, ligneCodeSource)) { codeSource += ligneCodeSource + '\n'; } fichierSource.close(); // Compilation du shader GLint erreurCompilation(0), tailleErreur(0); const GLchar* chaineCodeSource = codeSource.c_str(); glShaderSource(shader, 1, &chaineCodeSource, NULL); glCompileShader(shader); // Vérification de la compilation glGetShaderiv(shader, GL_COMPILE_STATUS, &erreurCompilation); if(erreurCompilation != GL_TRUE) { // Récupération de la taille de l'erreur glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &tailleErreur); // Allocation d'une chaine de caractères char *erreur = new char[tailleErreur + 1]; erreur[tailleErreur] = '\0'; // Récupération de l'erreur glGetShaderInfoLog(shader, tailleErreur, &tailleErreur, erreur); // Affichage de l'erreur std::cout << "Erreur de compilation du shader (" << type << ") " << erreur << std::endl; // On libère la mémoire et on retourne false delete[] erreur; return false; } // Tout s'est bien passé on retourne true return true; }
GLuint LoadShaders(const char* vsPath, const char* fsPath) { GLuint VertexShader = glCreateShader(GL_VERTEX_SHADER); GLuint FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); std::string VertexShaderCode; std::ifstream VertexShaderStream(vsPath, std::ios::in); if( VertexShaderStream.good() ) { std::string Line = ""; while(getline(VertexShaderStream, Line)) VertexShaderCode += "\n" + Line; VertexShaderStream.close(); } else std::cout << "Error reading the vertex-shader." << std::endl; std::string FragmentShaderCode; std::ifstream FragmentShaderStream(fsPath, std::ios::in); if( FragmentShaderStream.good() ) { std::string Line = ""; while(getline(FragmentShaderStream, Line)) FragmentShaderCode += "\n" + Line; FragmentShaderStream.close(); } else std::cout << "Error reading the fragment-shader." << std::endl; GLint Result = GL_FALSE; int InfoLogLength; std::cout << "Compiling Shader: " << vsPath << std::endl; char const* VertexSourcePointer = VertexShaderCode.c_str(); glShaderSource(VertexShader, 1, &VertexSourcePointer, NULL); glCompileShader(VertexShader); glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &Result); glGetShaderiv(VertexShader, GL_INFO_LOG_LENGTH, &InfoLogLength); char* vsError = new char[InfoLogLength]; glGetShaderInfoLog(VertexShader, InfoLogLength, NULL, vsError); //if(!vsError) std::cout << "Vertex-shader error message: " << vsError << std::endl; delete [] vsError; std::cout << "Compiling Shader: " << fsPath << std::endl; char const * FragmentSourcePointer = FragmentShaderCode.c_str(); glShaderSource(FragmentShader, 1, &FragmentSourcePointer, NULL); glCompileShader(FragmentShader); glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &Result); glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH, &InfoLogLength); char* fsError = new char[InfoLogLength]; glGetShaderInfoLog(FragmentShader, InfoLogLength, NULL, fsError); // if(!fsError) std::cout << "Fragment-shader error message: " << fsError << std::endl; delete [] fsError; std::cout << "Linking program." << std::endl; GLuint Program = glCreateProgram(); glAttachShader(Program, VertexShader); glAttachShader(Program, FragmentShader); glLinkProgram(Program); glGetProgramiv(Program, GL_LINK_STATUS, &Result); glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength); InfoLogLength = InfoLogLength < 1 ? 1 : InfoLogLength; char* programError = new char[InfoLogLength]; glGetProgramInfoLog(Program, InfoLogLength, NULL, programError); // if(!programError) std::cout << "Program-linking error message: " << programError << std::endl; delete [] programError; glDeleteShader(VertexShader); glDeleteShader(FragmentShader); return Program; }
// load shaders GLuint loadShader(const char *vertex_path, const char *fragment_path) { // create shaders GLuint vertShader = glCreateShader(GL_VERTEX_SHADER); GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER); // read shaders std::string vertShaderStr = readFile(vertex_path); std::string fragShaderStr = readFile(fragment_path); const char *vertShaderSrc = vertShaderStr.c_str(); const char *fragShaderSrc = fragShaderStr.c_str(); // hold results GLint result = GL_FALSE; int logLength; // compile vertex shader glShaderSource(vertShader, 1, &vertShaderSrc, NULL); glCompileShader(vertShader); // check vertex shader glGetShaderiv(vertShader, GL_COMPILE_STATUS, &result); // failed compile if(!result) { glGetShaderiv(vertShader, GL_INFO_LOG_LENGTH, &logLength); std::vector<char> vertShaderError((logLength > 1) ? logLength : 1); glGetShaderInfoLog(vertShader, logLength, NULL, &vertShaderError[0]); std::cerr << "[F] FAILED TO COMPILE VERTEX SHADER!" << &vertShaderError[0] << std::endl; return false; } // compile fragment shader glShaderSource(fragShader, 1, &fragShaderSrc, NULL); glCompileShader(fragShader); // check fragment shader glGetShaderiv(fragShader, GL_COMPILE_STATUS, &result); // failed compile if(!result) { glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength); std::vector<char> fragShaderError((logLength > 1) ? logLength : 1); glGetShaderInfoLog(fragShader, logLength, NULL, &fragShaderError[0]); std::cerr << "[F] FAILED TO COMPILE FRAGMENT SHADER!" << &fragShaderError[0] << std::endl; return false; } // create program and link with shaders GLuint program = glCreateProgram(); glAttachShader(program, vertShader); glAttachShader(program, fragShader); glLinkProgram(program); // check program status glGetProgramiv(program, GL_LINK_STATUS, &result); // failed program if(!result) { glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); std::vector<char> programError( (logLength > 1) ? logLength : 1 ); glGetProgramInfoLog(program, logLength, NULL, &programError[0]); std::cerr << "[F] THE SHADER PROGRAM FAILED TO LINK" << &programError[0] << std::endl; return false; } // delete shaders after attachment glDeleteShader(vertShader); glDeleteShader(fragShader); // return program with shaders return program; }
int CShaderObject::GenCSProgram(const char* computeShader, const char** Uniforms, int UniformsArraySize, const char** Textures, int TextureArraySize) { int i; GLuint program = glCreateProgram(); GLuint cs = glCreateShader(GL_COMPUTE_SHADER); glShaderSource(cs, 1, &(computeShader), 0); glCompileShader(cs); GLint compiled = 0; glGetShaderiv(cs, GL_COMPILE_STATUS, &compiled); if (!compiled) { GLint infoLen = 0; glGetShaderiv(cs, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen) { char* buf = new char[infoLen]; if (buf) { glGetShaderInfoLog(cs, infoLen, NULL, buf); //LOGI("Shader log:\n%s\n", buf); delete[] buf; } } return 0; } glAttachShader(program, cs); // can be deleted since the program will keep a reference glDeleteShader(cs); glLinkProgram(program); // check if program linked GLint success = 0; glGetProgramiv(program, GL_LINK_STATUS, &success); if (!success) { GLint bufLength = 0; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); if (bufLength) { char* buf = new char[bufLength]; if (buf) { glGetProgramInfoLog(program, bufLength, NULL, buf); //LOGI("Could not link program:\n%s\n", buf); delete [] buf; } } glDeleteProgram(program); program = 0; } //get location of uniform from string Uniforms[i] for (i=0; i<UniformsArraySize; i++) { auiLocation[i] = glGetUniformLocation(program, Uniforms[i]); } err = glGetError(); int sid; //set the sampler2D named by string Textures[i] to texture i for (i=0; i<TextureArraySize; i++) { sid = glGetUniformLocation(program, Textures[i]); glUniform1i(sid, i); } pid = program; return pid; }
//////////////////////////////////////////////////////////////////////////////// //! //////////////////////////////////////////////////////////////////////////////// GLuint compileGLSLprogram(const char *vertex_shader_src, const char *fragment_shader_src) { GLuint v, f, p = 0; p = glCreateProgram(); if (vertex_shader_src) { v = glCreateShader(GL_VERTEX_SHADER); glShaderSource(v, 1, &vertex_shader_src, NULL); glCompileShader(v); // check if shader compiled GLint compiled = 0; glGetShaderiv(v, GL_COMPILE_STATUS, &compiled); if (!compiled) { //#ifdef NV_REPORT_COMPILE_ERRORS char temp[256] = ""; glGetShaderInfoLog( v, 256, NULL, temp); //shrLog("Vtx Compile failed:\n%s\n", temp); //#endif glDeleteShader( v); return 0; } else glAttachShader(p,v); } if (fragment_shader_src) { f = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(f, 1, &fragment_shader_src, NULL); glCompileShader(f); // check if shader compiled GLint compiled = 0; glGetShaderiv(f, GL_COMPILE_STATUS, &compiled); if (!compiled) { //#ifdef NV_REPORT_COMPILE_ERRORS char temp[256] = ""; glGetShaderInfoLog(f, 256, NULL, temp); //shrLog("frag Compile failed:\n%s\n", temp); //#endif glDeleteShader(f); return 0; } else glAttachShader(p,f); } glLinkProgram(p); int infologLength = 0; int charsWritten = 0; glGetProgramiv(p, GL_INFO_LOG_LENGTH, (GLint *)&infologLength); if (infologLength > 0) { char *infoLog = (char *)malloc(infologLength); glGetProgramInfoLog(p, infologLength, (GLsizei *)&charsWritten, infoLog); //shrLog("Shader compilation error: %s\n", infoLog); free(infoLog); } return p; }
_Bool gl_init(void) { GLuint vertshader, fragshader; GLint status; const GLchar *data; vertshader = glCreateShader(GL_VERTEX_SHADER); if(!vertshader) { debug("glCreateShader() failed (vert)\n"); return 0; } data = &vertex_shader[0]; glShaderSource(vertshader, 1, &data, NULL); glCompileShader(vertshader); glGetShaderiv(vertshader, GL_COMPILE_STATUS, &status); if(!status) { #ifdef DEBUG debug("glCompileShader() failed (vert):\n%s\n", data); GLint infologsize = 0; glGetShaderiv(vertshader, GL_INFO_LOG_LENGTH, &infologsize); if(infologsize) { char* infolog = malloc(infologsize); glGetShaderInfoLog(vertshader, infologsize, NULL, (GLbyte*)infolog); debug("Infolog: %s\n", infolog); free(infolog); } #endif return 0; } fragshader = glCreateShader(GL_FRAGMENT_SHADER); if(!fragshader) { return 0; } data = &fragment_shader[0]; glShaderSource(fragshader, 1, &data, NULL); glCompileShader(fragshader); glGetShaderiv(fragshader, GL_COMPILE_STATUS, &status); if(!status) { #ifdef DEBUG debug("glCompileShader failed (frag):\n%s\n", data); GLint infologsize = 0; glGetShaderiv(fragshader, GL_INFO_LOG_LENGTH, &infologsize); if(infologsize) { char* infolog = malloc(infologsize); glGetShaderInfoLog(fragshader, infologsize, NULL, (GLbyte*)infolog); debug("Infolog: %s\n", infolog); free(infolog); } #endif return 0; } prog = glCreateProgram(); glAttachShader(prog, vertshader); glAttachShader(prog, fragshader); glBindAttribLocation(prog, 0, "pos"); glBindAttribLocation(prog, 1, "tex"); glLinkProgram(prog); glGetProgramiv(prog, GL_LINK_STATUS, &status); if(!status) { #ifdef DEBUG debug("glLinkProgram failed\n"); GLint infologsize = 0; glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &infologsize); if(infologsize) { char* infolog = malloc(infologsize); glGetShaderInfoLog(prog, infologsize, NULL, (GLbyte*)infolog); debug("Infolog: %s\n", infolog); free(infolog); } #endif return 0; } glUseProgram(prog); matrix = glGetUniformLocation(prog, "matrix"); k = glGetUniformLocation(prog, "k"); k2 = glGetUniformLocation(prog, "k2"); samp = glGetUniformLocation(prog, "samp"); debug("uniforms: %i %i %i\n", matrix, k, samp); GLint zero = 0; float one[] = {1.0, 1.0, 1.0}; glUniform1iv(samp, 1, &zero); glUniform3fv(k2, 1, one); uint8_t wh = {255}; glGenTextures(1, &white); glBindTexture(GL_TEXTURE_2D, white); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &wh); // glVertexAttribPointer(0, 2, GL_SHORT, GL_FALSE, sizeof(VERTEX2D), &quads[0]); glVertexAttribPointer(1, 2, GL_UNSIGNED_SHORT, GL_FALSE, sizeof(VERTEX2D), &quads[0].vertex[0].tx); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); //Alpha blending glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); // glPixelStorei(GL_UNPACK_ALIGNMENT, 1); #ifndef NO_OPENGL_ES uint8_t i = 0; uint16_t ii = 0; do { quad_indices[ii] = i + 0; quad_indices[ii + 1] = i + 1; quad_indices[ii + 2] = i + 3; quad_indices[ii + 3] = i + 3; quad_indices[ii + 4] = i + 1; quad_indices[ii + 5] = i + 2; i += 4; ii += 6; } while(i); #endif glGenTextures(countof(bitmap), bitmap); svg_draw(0); loadfonts(); float vec[4]; vec[0] = -(float)utox_window_width / 2.0; vec[1] = -(float)utox_window_height / 2.0; vec[2] = 2.0 / (float)utox_window_width; vec[3] = -2.0 / (float)utox_window_height; glUniform4fv(matrix, 1, vec); ui_size(utox_window_width, utox_window_height); glViewport(0, 0, utox_window_width, utox_window_height); redraw(); return 1; }
static GLuint LoadProgram(const char* vsKey, const char* tcsKey, const char* tesKey, const char* gsKey, const char* fsKey) { GLchar spew[256]; GLint compileSuccess; GLuint programHandle = glCreateProgram(); const char* vsSource = pezGetShader(vsKey); pezCheck(vsSource != 0, "Can't find vshader: %s\n", vsKey); GLuint vsHandle = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vsHandle, 1, &vsSource, 0); glCompileShader(vsHandle); glGetShaderiv(vsHandle, GL_COMPILE_STATUS, &compileSuccess); glGetShaderInfoLog(vsHandle, sizeof(spew), 0, spew); pezCheck(compileSuccess, "Can't compile vshader:\n%s", spew); glAttachShader(programHandle, vsHandle); if (tcsKey) { const char* tcsSource = pezGetShader(tcsKey); pezCheck(tcsSource != 0, "Can't find tcshader: %s\n", tcsKey); GLuint tcsHandle = glCreateShader(GL_TESS_CONTROL_SHADER); glShaderSource(tcsHandle, 1, &tcsSource, 0); glCompileShader(tcsHandle); glGetShaderiv(tcsHandle, GL_COMPILE_STATUS, &compileSuccess); glGetShaderInfoLog(tcsHandle, sizeof(spew), 0, spew); pezCheck(compileSuccess, "Can't compile tcshader:\n%s", spew); glAttachShader(programHandle, tcsHandle); } if (tesKey) { const char* tesSource = pezGetShader(tesKey); pezCheck(tesSource != 0, "Can't find teshader: %s\n", tesKey); GLuint tesHandle = glCreateShader(GL_TESS_EVALUATION_SHADER); glShaderSource(tesHandle, 1, &tesSource, 0); glCompileShader(tesHandle); glGetShaderiv(tesHandle, GL_COMPILE_STATUS, &compileSuccess); glGetShaderInfoLog(tesHandle, sizeof(spew), 0, spew); pezCheck(compileSuccess, "Can't compile teshader:\n%s", spew); glAttachShader(programHandle, tesHandle); } if (gsKey) { const char* gsSource = pezGetShader(gsKey); pezCheck(gsSource != 0, "Can't find gshader: %s\n", gsKey); GLuint gsHandle = glCreateShader(GL_GEOMETRY_SHADER); glShaderSource(gsHandle, 1, &gsSource, 0); glCompileShader(gsHandle); glGetShaderiv(gsHandle, GL_COMPILE_STATUS, &compileSuccess); glGetShaderInfoLog(gsHandle, sizeof(spew), 0, spew); pezCheck(compileSuccess, "Can't compile gshader:\n%s", spew); glAttachShader(programHandle, gsHandle); } if (fsKey) { const char* fsSource = pezGetShader(fsKey); pezCheck(fsSource != 0, "Can't find fshader: %s\n", fsKey); GLuint fsHandle = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fsHandle, 1, &fsSource, 0); glCompileShader(fsHandle); glGetShaderiv(fsHandle, GL_COMPILE_STATUS, &compileSuccess); glGetShaderInfoLog(fsHandle, sizeof(spew), 0, spew); pezCheck(compileSuccess, "Can't compile fshader:\n%s", spew); glAttachShader(programHandle, fsHandle); } glBindAttribLocation(programHandle, PositionSlot, "Position"); glBindAttribLocation(programHandle, NormalSlot, "Normal"); glBindAttribLocation(programHandle, OcclusionSlot, "Occlusion"); glLinkProgram(programHandle); GLint linkSuccess; glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess); glGetProgramInfoLog(programHandle, sizeof(spew), 0, spew); pezCheck(linkSuccess, "Can't link shaders:\n%s", spew); glUseProgram(programHandle); return programHandle; }
void Shader::create(const std::string _vertexFileName, const std::string& _fragmentFileName) { clear(); assert(!_vertexFileName.empty() && !_fragmentFileName.empty()); // Vertex Shader Loading unsigned int vertexShader; std::ifstream fileVs; fileVs.open(_vertexFileName.c_str(), std::ios::binary); assert(fileVs.is_open()); if(fileVs.is_open()) { fileVs.seekg(0, std::ios::end); unsigned int fileSize = (unsigned int)(fileVs.tellg()); assert(fileSize != 0); fileVs.seekg(std::ios::beg); char *bufferVs = new char[fileSize+1]; fileVs.read(bufferVs, fileSize); fileVs.close(); bufferVs[fileSize] = '\0'; /////////////////////////////////////////////////////////////////// vertexShader = glCreateShader(GL_VERTEX_SHADER); assert(vertexShader != 0); glShaderSource(vertexShader, 1, (const char **)(&bufferVs), NULL); glCompileShader(vertexShader); delete [] bufferVs; //Get Compilation Information int compiled; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compiled); if(compiled == 0) { int length; glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &length); char *str = new char[length]; glGetShaderInfoLog(vertexShader, length, NULL, str); std::cerr << "Vertex shader error " << str << std::endl; delete [] str; assert(false); return; } } else { std::cerr << "Didn't succeed to open the vertex shader file!" << std::endl; assert(false); return; } // Fragment Shader Loading unsigned int fragmentShader; std::ifstream fileFs; fileFs.open(_fragmentFileName.c_str(), std::ios::binary); assert(fileFs.is_open()); if(fileFs.is_open()) { fileFs.seekg(0, std::ios::end); unsigned int fileSize = (unsigned int)(fileFs.tellg()); assert(fileSize != 0); fileFs.seekg(std::ios::beg); char *bufferFs = new char[fileSize+1]; fileFs.read(bufferFs, fileSize); fileFs.close(); bufferFs[fileSize] = '\0'; /////////////////////////////////////////////////////////////////// fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); assert(fragmentShader != 0); glShaderSource(fragmentShader, 1, (const char **)(&bufferFs), NULL); glCompileShader(fragmentShader); delete [] bufferFs; //Get Compilation Information int compiled; glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compiled); if(compiled == 0) { int length; glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &length); char *str = new char[length]; glGetShaderInfoLog(fragmentShader, length, NULL, str); std::cerr << "Fragment shader Error " << str << std::endl; delete [] str; assert(false); return; } } else { std::cerr << "Didn't succeed to open the fragment shader file!" << std::endl; assert(false); return; } //Bind Vertex and Fragment programObj_ = glCreateProgram(); assert(programObj_ != 0); glAttachShader(programObj_, vertexShader); glAttachShader(programObj_, fragmentShader); glDeleteShader(vertexShader); glDeleteShader(fragmentShader); glLinkProgram(programObj_); //Get Linker Information int linked; glGetProgramiv(programObj_, GL_LINK_STATUS, &linked); if(linked == 0) { int length; glGetProgramiv(programObj_, GL_INFO_LOG_LENGTH, &length); char *str = new char[length]; glGetProgramInfoLog(programObj_, length, NULL, str); std::cerr << "Linker error " << str << std::endl; delete [] str; clear(); assert(false); } }
///////////////////////////////////////////////////////////////// // Load a pair of shaders, compile, and link together. Specify the complete // file path for each shader. Note, there is no support for // just loading say a vertex program... you have to do both. GLuint gltLoadShaderPair(const char *szVertexProg, const char *szFragmentProg, bool loadFromFile) { // Temporary Shader objects GLuint hVertexShader; GLuint hFragmentShader; GLuint hReturn = 0; GLint testVal; // Create shader objects hVertexShader = glCreateShader(GL_VERTEX_SHADER); hFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); if (loadFromFile) { if(gltLoadShaderFile(szVertexProg, hVertexShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } if(gltLoadShaderFile(szFragmentProg, hFragmentShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } } else { gltLoadShaderSrc(vertexShader, hVertexShader); gltLoadShaderSrc(fragmentShader, hFragmentShader); } // Compile them glCompileShader(hVertexShader); glCompileShader(hFragmentShader); // Check for errors glGetShaderiv(hVertexShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { char temp[256] = ""; glGetShaderInfoLog( hVertexShader, 256, NULL, temp); fprintf( stderr, "Compile failed:\n%s\n", temp); assert(0); exit(0); glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } glGetShaderiv(hFragmentShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { char temp[256] = ""; glGetShaderInfoLog( hFragmentShader, 256, NULL, temp); fprintf( stderr, "Compile failed:\n%s\n", temp); assert(0); exit(0); glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } // Link them - assuming it works... hReturn = glCreateProgram(); glAttachShader(hReturn, hVertexShader); glAttachShader(hReturn, hFragmentShader); glLinkProgram(hReturn); // These are no longer needed glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); // Make sure link worked too glGetProgramiv(hReturn, GL_LINK_STATUS, &testVal); if(testVal == GL_FALSE) { glDeleteProgram(hReturn); return (GLuint)NULL; } return hReturn; }
// Create a GLSL program object from vertex and fragment shader files GLuint InitShader(const char* vShaderFile, const char* fShaderFile) { struct Shader { const char* filename; GLenum type; GLchar* source; } shaders[2] = { { vShaderFile, GL_VERTEX_SHADER, NULL }, { fShaderFile, GL_FRAGMENT_SHADER, NULL } }; GLuint program = glCreateProgram(); for ( int i = 0; i < 2; ++i ) { Shader& s = shaders[i]; s.source = readShaderSource( s.filename ); if ( shaders[i].source == NULL ) { std::cerr << "Failed to read " << s.filename << std::endl; exit( EXIT_FAILURE ); } GLuint shader = glCreateShader( s.type ); glShaderSource( shader, 1, (const GLchar**) &s.source, NULL ); glCompileShader( shader ); GLint compiled; glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ); if ( !compiled ) { std::cerr << s.filename << " failed to compile:" << std::endl; GLint logSize; glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logSize ); char* logMsg = new char[logSize]; glGetShaderInfoLog( shader, logSize, NULL, logMsg ); std::cerr << logMsg << std::endl; delete [] logMsg; exit( EXIT_FAILURE ); } delete [] s.source; glAttachShader( program, shader ); } /* link and error check */ glLinkProgram(program); GLint linked; glGetProgramiv( program, GL_LINK_STATUS, &linked ); if ( !linked ) { std::cerr << "Shader program failed to link" << std::endl; GLint logSize; glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logSize); char* logMsg = new char[logSize]; glGetProgramInfoLog( program, logSize, NULL, logMsg ); std::cerr << logMsg << std::endl; delete [] logMsg; exit( EXIT_FAILURE ); } /* use program object */ glUseProgram(program); return program; }
int CShaderObject::GenProgram(const char* vertexShader, const char* fragmentShader, const char** Attribs, int AttribsArraySize, const char** Uniforms, int UniformsArraySize, const char** Textures, int TextureArraySize) { if (Initialized) return -1; int i; pid = glCreateProgram(); GLuint vs = glCreateShader(GL_VERTEX_SHADER); GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(vs, 1, &vertexShader, 0); glShaderSource(fs, 1, &fragmentShader, 0); glCompileShader(vs); GLint compiled = 0; glGetShaderiv(vs, GL_COMPILE_STATUS, &compiled); if (!compiled) { GLint infoLen = 0; glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen) { char* buf = new char[infoLen]; if (buf) { glGetShaderInfoLog(vs, infoLen, NULL, buf); //LOGI("Shader log:\n%s\n", buf); delete[] buf; } } return 0; } glAttachShader(pid, vs); glDeleteShader(vs); glCompileShader(fs); glGetShaderiv(fs, GL_COMPILE_STATUS, &compiled); if (!compiled) { GLint infoLen = 0; glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen) { char* buf = new char[infoLen]; if (buf) { glGetShaderInfoLog(fs, infoLen, NULL, buf); //LOGI("Shader log:\n%s\n", buf); delete[] buf; } } return 0; } glAttachShader(pid, fs); glDeleteShader(fs); glLinkProgram(pid); // check if program linked GLint success = 0; glGetProgramiv(pid, GL_LINK_STATUS, &success); if (!success) { GLint bufLength = 0; glGetProgramiv(pid, GL_INFO_LOG_LENGTH, &bufLength); if (bufLength) { char* buf = new char[bufLength]; if (buf) { glGetProgramInfoLog(pid, bufLength, NULL, buf); delete [] buf; } } glDeleteProgram(pid); pid = 0; } if (!pid) return -1; glUseProgram(pid); //bind the vertex attribute from string Attribs[i] to location i for (i = 0; i < AttribsArraySize; ++i) { glBindAttribLocation(pid, i, Attribs[i]); } //get location of uniform from string Uniforms[i] for (i=0; i<UniformsArraySize; i++) { auiLocation[i] = glGetUniformLocation(pid, Uniforms[i]); } int sid; //set the sampler2D named by string Textures[i] to texture i for (i=0; i<TextureArraySize; i++) { sid = glGetUniformLocation(pid, Textures[i]); glUniform1i(sid, i); } Initialized = 1; return 0; }
/* Function to load Shaders - Use it as it is */ GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path) { // Create the shaders GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); // Read the Vertex Shader code from the file std::string VertexShaderCode; std::ifstream VertexShaderStream(vertex_file_path, std::ios::in); if(VertexShaderStream.is_open()) { std::string Line = ""; while(getline(VertexShaderStream, Line)) VertexShaderCode += "\n" + Line; VertexShaderStream.close(); } // Read the Fragment Shader code from the file std::string FragmentShaderCode; std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in); if(FragmentShaderStream.is_open()){ std::string Line = ""; while(getline(FragmentShaderStream, Line)) FragmentShaderCode += "\n" + Line; FragmentShaderStream.close(); } GLint Result = GL_FALSE; int InfoLogLength; // Compile Vertex Shader printf("Compiling shader : %s\n", vertex_file_path); char const * VertexSourcePointer = VertexShaderCode.c_str(); glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL); glCompileShader(VertexShaderID); // Check Vertex Shader glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); std::vector<char> VertexShaderErrorMessage(InfoLogLength); glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]); // Compile Fragment Shader printf("Compiling shader : %s\n", fragment_file_path); char const * FragmentSourcePointer = FragmentShaderCode.c_str(); glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL); glCompileShader(FragmentShaderID); // Check Fragment Shader glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); std::vector<char> FragmentShaderErrorMessage(InfoLogLength); glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]); // Link the program fprintf(stdout, "Linking program\n"); GLuint ProgramID = glCreateProgram(); glAttachShader(ProgramID, VertexShaderID); glAttachShader(ProgramID, FragmentShaderID); glLinkProgram(ProgramID); // Check the program glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); std::vector<char> ProgramErrorMessage( max(InfoLogLength, int(1)) ); glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); fprintf(stdout, "%s\n", &ProgramErrorMessage[0]); glDeleteShader(VertexShaderID); glDeleteShader(FragmentShaderID); return ProgramID; }
// pass in pointers so we can free the memory in the gpu later void setup_polygons(GLuint *vertex_attribute_obj, GLuint *element_buffer, GLuint *vertex_buffer, GLuint *v_shader, GLuint *f_shader, GLuint *shader_program, int height) { glewInit(); // calculate OpenGL point for 50px away from the top float top = ((height / 2.0f - 50) / (height / 2.0f)); // create vertices simple triangle float vertices[] = { //position //texture coordinates -1.0f, top , 0.0f, 0.0f, // top left 1.0f, top , 1.0f, 0.0f, // top right 1.0f, -1.0f, 1.0f, 1.0f, // bottom-right -1.0f, -1.0f, 0.0f, 1.0f // bottom-left }; glDeleteBuffers(1, vertex_attribute_obj); glDeleteBuffers(1, vertex_buffer); // create vertex array object for storing shader and attribute data glGenVertexArrays(1, vertex_attribute_obj); glBindVertexArray(*vertex_attribute_obj); // create vertex buffer glGenBuffers(1, vertex_buffer); // generate one buffer // make this buffer the "active" buffer glBindBuffer(GL_ARRAY_BUFFER, *vertex_buffer); // put vertices into the buffer glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // create element buffer GLuint elements[] = { 0, 1, 2, 2, 3, 0 }; glGenBuffers(1, element_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *element_buffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW); // create vertex shader *v_shader = glCreateShader(GL_VERTEX_SHADER); // load shader source into GPU glShaderSource(*v_shader, 1, &vertex_shader, NULL); // compile the shader glCompileShader(*v_shader); // check if shader compiled correctly GLint status; glGetShaderiv(*v_shader, GL_COMPILE_STATUS, &status); if(status != GL_TRUE) { puts("Error compiling vertex shader"); // get error log from shader char buffer[512]; glGetShaderInfoLog(*v_shader, 512, NULL, buffer); printf("%s\n", buffer); } // same thing for fragment shader *f_shader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(*f_shader, 1, &fragment_shader, NULL); glCompileShader(*f_shader); glGetShaderiv(*f_shader, GL_COMPILE_STATUS, &status); if(status != GL_TRUE) { puts("Error compiling fragment shader"); // get error log from shader char buffer[512]; glGetShaderInfoLog(*f_shader, 512, NULL, buffer); printf("%s\n", buffer); } // combine shaders into a program *shader_program = glCreateProgram(); glAttachShader(*shader_program, *v_shader); glAttachShader(*shader_program, *f_shader); /*glBindFragDataLocation(*shader_program, 0, "outColor");*/ // link the program glLinkProgram(*shader_program); // tell opengl to use this program glUseProgram(*shader_program); // get position of the input position in vertex_shader GLint posAttribute = glGetAttribLocation(*shader_program, "position"); // always 0 since it's the first and only arg // (arg_position, number of values for that arg, type for each component, // should they be normalized?, distance (in bytes) between each position attribute, // offset from start of array for first attribute value) glVertexAttribPointer(posAttribute, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0); // enable attribute array glEnableVertexAttribArray(posAttribute); GLint texAttrib = glGetAttribLocation(*shader_program, "texCoord"); glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), (void*)(2*sizeof(float))); glEnableVertexAttribArray(texAttrib); }
/* rune_DrawChar renders the given rune at char position (x, y) */ void rune_DrawChar(Rune *rune, uint32_t x, uint32_t y) { const GLchar *vs = "#version 150\n" "in vec2 pos;\n" "in vec2 texco;\n" "out vec2 out_texco;\n" "uniform sampler2D tex;\n" "uniform mat4 mvp;\n" "void main()\n" "{\n" " out_texco = texco;\n" " gl_Position = mvp * vec4(pos, 0.0, 1.0);\n" "}\n"; const GLchar *fs = "#version 150\n" "in vec2 out_texco;\n" "uniform sampler2D tex;\n" "void main()\n" "{\n" " vec4 color = texture(tex, out_texco);\n" " gl_FragColor = color;\n" "}\n"; static GLuint vao = 0; static GLuint vbo = 0; static GLuint ibo = 0; static GLfloat vertices[4 * 4] = { /* 4 vertices. format: x-y-u-v */ 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, }; static GLshort indices[3 * 2] = { /* 2 triangles */ 0, 1, 2, 0, 3, 2 }; static Mat4x4 mvp; static GLuint mvpUniform; static GLuint texUniform; static GLuint shader; static GLuint sampler; GLenum err; GLint compiled, linked; CharRune *r; GLfloat u, v; r = (CharRune*)rune; /* load texture */ if(r->texture == 0){ r->texture = latin1_to_texture(r->id); glGenSamplers(1, &sampler); glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f); } /* create shader program */ if(shader == 0){ GLuint frag, vert; GLint len; /* vertex shader */ vert = glCreateShader(GL_VERTEX_SHADER); len = strlen(vs); glShaderSource(vert, 1, &vs, &len); glCompileShader(vert); glGetShaderiv(vert, GL_COMPILE_STATUS, &compiled); if(compiled == GL_FALSE){ GLint logSz; GLchar *log; glGetShaderiv(vert, GL_INFO_LOG_LENGTH, &logSz); log = malloc(logSz * sizeof(GLchar)); glGetShaderInfoLog(vert, logSz, &logSz, log); puts("error: vertex shader compilation failed"); puts(log); free(log); } /* fragment shader */ frag = glCreateShader(GL_FRAGMENT_SHADER); len = strlen(fs); glShaderSource(frag, 1, &fs, &len); glCompileShader(frag); glGetShaderiv(frag, GL_COMPILE_STATUS, &compiled); if(compiled == GL_FALSE){ GLint logSz; GLchar *log; glGetShaderiv(vert, GL_INFO_LOG_LENGTH, &logSz); log = malloc(logSz * sizeof(GLchar)); glGetShaderInfoLog(vert, logSz, &logSz, log); puts("error: fragment shader compilation failed"); puts(log); free(log); } /* link shaders */ shader = glCreateProgram(); glAttachShader(shader, vert); glAttachShader(shader, frag); glBindAttribLocation(shader, 0, "pos"); glBindAttribLocation(shader, 1, "texco"); glLinkProgram(shader); glGetProgramiv(shader, GL_LINK_STATUS, &linked); if(linked == GL_FALSE){ GLint logSz; GLchar *log; glGetProgramiv(shader, GL_INFO_LOG_LENGTH, &logSz); log = malloc(logSz * sizeof(GLchar)); glGetProgramInfoLog(shader, logSz, &logSz, log); puts(log); free(log); } /* get the uniforms */ mvpUniform = glGetUniformLocation(shader, "mvp"); mat4x4_orthographic(&mvp, 0.0f, 80.0f, 0.0f, 40.0f, -1.0f, 1.0f); texUniform = glGetUniformLocation(shader, "tex"); } /* create vertex attribute object */ if(vao == 0){ glGenVertexArrays(1, &vao); glGenBuffers(1, &vbo); glGenBuffers(1, &ibo); /* vertices */ glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 4 * 4, vertices, GL_STATIC_DRAW); /* indices */ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLshort) * 6, indices, GL_STATIC_DRAW); } /* update VBO */ r->id = 1; u = 1.0f / 16.0f * (r->id % 16); v = 1.0f / 16.0f * (r->id / 16); vertices[0] = x; vertices[1] = y; //vertices[2] = u; //vertices[3] = v; vertices[0+4] = x + rune->w; vertices[1+4] = y; //vertices[2+4] = u+(1.0f/16.0f); //vertices[3+4] = v; vertices[0+8] = x + rune->w; vertices[1+8] = y + rune->h; //vertices[2+8] = u+(1.0f/16.0f); //vertices[3+8] = v+(1.0f/16.0f); vertices[0+12] = x; vertices[1+12] = y + rune->h; //vertices[2+12] = u; //vertices[3+12] = v+(1.0f/16.0f); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 4 * 4, vertices, GL_STATIC_DRAW); /* draw */ glUseProgram(shader); glUniformMatrix4fv(mvpUniform, 1, 0, ((GLfloat*)&mvp)); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, r->texture); glUniform1i(texUniform, 0); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*4, (void*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*4, (void*)8); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)0); }
GLuint ShaderLoader::loadShader() { GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); //Read Shader std::string strVertexShader = loadFile(pathVertexShader); std::string strFragmentShader = loadFile(pathFragmentShader); const char* cStrVertexShader = strVertexShader.c_str(); const char* cStrFragmentShader = strFragmentShader.c_str(); GLint result = GL_FALSE; int logLength; //Compile Vertex Shader glShaderSource(vertexShader, 1, &cStrVertexShader, NULL); glCompileShader(vertexShader); //Check Vertex Shader glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &result); glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength); std::vector<char> vertexShaderError((logLength > 1) ? logLength : 1); if(logLength > 1) { glGetShaderInfoLog(vertexShader, logLength, NULL, &vertexShaderError[0]); std::cerr << &vertexShaderError[0] << std::endl; } //Compile Fragment Shader glShaderSource(fragmentShader, 1, &cStrFragmentShader, NULL); glCompileShader(fragmentShader); //Check Fragment Shader glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &result); glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &logLength); std::vector<char> fragmentShaderError((logLength > 1) ? logLength : 1); if(logLength > 1) { glGetShaderInfoLog(fragmentShader, logLength, NULL, &fragmentShaderError[0]); std::cerr << &fragmentShaderError[0] << std::endl; } //Link Program GLuint program = glCreateProgram(); glAttachShader(program, vertexShader); glAttachShader(program, fragmentShader); glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &result); glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); std::vector<char> programError( (logLength > 1) ? logLength : 1); if(logLength > 1) { glGetProgramInfoLog(program, logLength, NULL, &programError[0]); std::cerr << &programError[0] << std::endl; } //Return Program return program; }
int compile_and_link_shader(ShaderGLSL & shader, int typeMask, const char * sourceBuffer, int bufferSize) { // Create program object shader.program = glCreateProgram(); //Handle Vertex Shader GLuint vertexShaderObject ; if (typeMask & ShaderGLSL::VERTEX_SHADER) { // Create shader object for vertex shader vertexShaderObject = glCreateShader(GL_VERTEX_SHADER); // Add #define VERTEX to buffer const char * sc[3] = { "#version 150\n", "#define VERTEX\n", sourceBuffer}; glShaderSource(vertexShaderObject, 3, sc, NULL); // Compile shader glCompileShader(vertexShaderObject); // Get error log size and print it eventually int logLength; glGetShaderiv(vertexShaderObject, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 1) { char * log = new char[logLength]; glGetShaderInfoLog(vertexShaderObject, logLength, &logLength, log); fprintf(stderr, "Error in compiling vertex shader : %s", log); fprintf(stderr, "%s\n%s\n%s", sc[0], sc[1], sc[2]); delete[] log; } // If an error happend quit int status; glGetShaderiv(vertexShaderObject, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) return -1; //Attach shader to program glAttachShader(shader.program, vertexShaderObject); } // Handle Geometry shader GLuint geometryShaderObject ; if (typeMask & ShaderGLSL::GEOMETRY_SHADER) { // Create shader object for Geometry shader geometryShaderObject = glCreateShader(GL_GEOMETRY_SHADER); // Add #define Geometry to buffer const char * sc[3] = { "#version 150\n", "#define GEOMETRY\n", sourceBuffer}; glShaderSource(geometryShaderObject, 3, sc, NULL); // Compile shader glCompileShader(geometryShaderObject); // Get error log size and print it eventually int logLength; glGetShaderiv(geometryShaderObject, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 1) { char * log = new char[logLength]; glGetShaderInfoLog(geometryShaderObject, logLength, &logLength, log); fprintf(stderr, "Error in compiling Geometry shader : %s \n", log); fprintf(stderr, "%s\n%s\n%s", sc[0], sc[1], sc[2]); delete[] log; } // If an error happend quit int status; glGetShaderiv(geometryShaderObject, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) return -1; //Attach shader to program glAttachShader(shader.program, geometryShaderObject); } // Handle Fragment shader GLuint fragmentShaderObject ; if (typeMask && ShaderGLSL::FRAGMENT_SHADER) { // Create shader object for fragment shader fragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER); // Add #define fragment to buffer const char * sc[3] = { "#version 150\n", "#define FRAGMENT\n", sourceBuffer}; glShaderSource(fragmentShaderObject, 3, sc, NULL); // Compile shader glCompileShader(fragmentShaderObject); // Get error log size and print it eventually int logLength; glGetShaderiv(fragmentShaderObject, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 1) { char * log = new char[logLength]; glGetShaderInfoLog(fragmentShaderObject, logLength, &logLength, log); fprintf(stderr, "Error in compiling fragment shader : %s \n", log); fprintf(stderr, "%s\n%s\n%s", sc[0], sc[1], sc[2]); delete[] log; } // If an error happend quit int status; glGetShaderiv(fragmentShaderObject, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) return -1; //Attach shader to program glAttachShader(shader.program, fragmentShaderObject); } // Bind attribute location glBindAttribLocation(shader.program, 0, "VertexPosition"); glBindAttribLocation(shader.program, 1, "VertexNormal"); glBindAttribLocation(shader.program, 2, "VertexTexCoord"); glBindFragDataLocation(shader.program, 0, "Color"); glBindFragDataLocation(shader.program, 1, "Normal"); // Link attached shaders glLinkProgram(shader.program); // Clean if (typeMask & ShaderGLSL::VERTEX_SHADER) { glDeleteShader(vertexShaderObject); } if (typeMask && ShaderGLSL::GEOMETRY_SHADER) { glDeleteShader(fragmentShaderObject); } if (typeMask && ShaderGLSL::FRAGMENT_SHADER) { glDeleteShader(fragmentShaderObject); } // Get link error log size and print it eventually int logLength; glGetProgramiv(shader.program, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 1) { char * log = new char[logLength]; glGetProgramInfoLog(shader.program, logLength, &logLength, log); fprintf(stderr, "Error in linking shaders : %s \n", log); delete[] log; } int status; glGetProgramiv(shader.program, GL_LINK_STATUS, &status); if (status == GL_FALSE) return -1; return 0; }
int main(int argc, char *argv[]) { auto t_start = std::chrono::high_resolution_clock::now(); GLfloat directionx, directiony, directionz; directionx = 0.0f; directiony = 0.0f; directionz = 1.0f; GLboolean quit = GL_FALSE; GLenum errorValue; // Initialize SDL if (SDL_Init(SDL_INIT_VIDEO) < 0) { std::cerr << "SDL video initialization failed! Error: " << SDL_GetError() << std::endl; quit = GL_TRUE; SDL_Delay(5000); } SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_Window* window = SDL_CreateWindow("OpenGL tutorial", 100, 100, width, height, SDL_WINDOW_OPENGL); SDL_GLContext context = SDL_GL_CreateContext(window); // Initialize GLEW glewExperimental = GL_TRUE; glewInit(); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after GLEW init: " << errorValue << std::endl; } // Create Vertex Array Objects, don't bind yet /* VAOs are used to store all of the links between the vertex attributes and VBOs with raw vertex data. Since VBOs are just containers for the raw data that the graphics card reads and manipulates, the meaning and usage of the data has to be specified for each VBO & shader program. This might be quite cumbersome, if many shader programs are used, since the layout of the attributes would have to be specified every time. This is wheree VAOs come in: they can be used to store the links between VBO and the specified attributes. This way, a new VAO can be bound for each different shader program, which can then be changed easily at will by just calling glUseProgram(shaderProg1);. The graphics card then knows how to use the raw data in the VBO, since its usage and meaning has been specified beforehand and the links between VBOs and attributes has been saved to the VAO. As soon as VAO has been bound, all glVertexAttribPointer calls store the information to that VAO. */ GLuint vaoCube, vaoQuad; glGenVertexArrays(1, &vaoCube); glGenVertexArrays(1, &vaoQuad); // Create a Vertex Buffer Objects and upload vertex data /* VBOs are used to upload the vertex data to the graphics card. glGenBuffers(); creates a VBO, which can then be made active by binding it with glBindBuffer();. When the VBO has been set as active by binding it, the vertex data can be loaded to it with glBufferData();. Note that VBO/OpenGL doesn't know what the data means or is used for, it's just raw data. The usage of the data has to be specified, meaning which indices in the data correspond to which attribute (pos, color, texcoord, etc.). */ GLuint vboCube, vboQuad; glGenBuffers(1, &vboCube); glGenBuffers(1, &vboQuad); glBindBuffer(GL_ARRAY_BUFFER, vboCube); glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, vboQuad); glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after VBOs: " << errorValue << std::endl; } // Generate shader programs GLuint sceneVertexShader, sceneFragmentShader, sceneShaderProgram; createShaderprogram(sceneVertexSource, sceneFragmentSource, sceneVertexShader, sceneFragmentShader, sceneShaderProgram); GLuint screenVertexShader, screenFragmentShader, screenShaderProgram; createShaderprogram(screenVertexSource, screenFragmentSource, screenVertexShader, screenFragmentShader, screenShaderProgram); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after generating shader programs: " << errorValue << std::endl; } // Specify the layout of the vertex data (bind vertex arrays) /* Since OpenGL doesn't know how the attributes of the vertices are specified in the arrays containing the vertex information (position, color, texture coordinates), they need to be specified by the user. Each attribute also saves the VBO that's been bound to the current GL_ARRAY_BUFFER. This means different VBOs can be used for each attribute if so desired. Only calls after a VAO has been bound will "stick" to it. As soon as VAO has been bound, all glVertexAttribPointer calls store the information to that VAO. See more complete explanation of VAO above. */ glBindVertexArray(vaoCube); glBindBuffer(GL_ARRAY_BUFFER, vboCube); specifySceneVertexAttributes(sceneShaderProgram); glBindVertexArray(vaoQuad); glBindBuffer(GL_ARRAY_BUFFER, vboQuad); specifyScreenVertexAttributes(screenShaderProgram); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after specifying the layout of vertex data: " << errorValue << std::endl; } // Load textures GLuint texKitten = loadTexture("sample.png"); GLuint texPuppy = loadTexture("sample2.png"); glUseProgram(sceneShaderProgram); glUniform1i(glGetUniformLocation(sceneShaderProgram, "texKitten"), 0); glUniform1i(glGetUniformLocation(sceneShaderProgram, "texPuppy"), 1); glUseProgram(screenShaderProgram); glUniform1i(glGetUniformLocation(screenShaderProgram, "texFramebuffer"), 0); GLint uniModel = glGetUniformLocation(sceneShaderProgram, "model"); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after loading textures: " << errorValue << std::endl; } // Create frame buffer GLuint frameBuffer; glGenFramebuffers(1, &frameBuffer); glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after creating a frame buffer: " << errorValue << std::endl; } // Create texture to hold color buffer GLuint texColorBuffer; glGenTextures(1, &texColorBuffer); glBindTexture(GL_TEXTURE_2D, texColorBuffer); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColorBuffer, 0); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after color buffer texture creation: " << errorValue << std::endl; } // Create Renderbuffer Object to hold depth and stencil buffers GLuint rboDepthStencil; glGenRenderbuffers(1, &rboDepthStencil); glBindRenderbuffer(GL_RENDERBUFFER, rboDepthStencil); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rboDepthStencil); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after RBO: " << errorValue << std::endl; } /* Set up projection: View matrix: First vector gives the position of the camera Second vector gives the point where the camera is centered or looking at Third vector defines "up", here up is the z-axis, xy-plane is the "ground" */ glm::mat4 view = glm::lookAt( glm::vec3(2.5f, 2.5f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f) ); glUseProgram(sceneShaderProgram); GLint uniView = glGetUniformLocation(sceneShaderProgram, "view"); glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view)); // Projection matrix glm::mat4 proj = glm::perspective(glm::radians(45.0f), GLfloat(width) / GLfloat(height), 1.0f, 10.0f); GLint uniProj = glGetUniformLocation(sceneShaderProgram, "proj"); glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj)); GLint uniColor = glGetUniformLocation(sceneShaderProgram, "overrideColor"); // Final error check will write errors (if any are encountered at this point) to file GLint status, status2, status3, status4, OpenGLError; OpenGLError = glGetError(); GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); glGetShaderiv(sceneVertexShader, GL_COMPILE_STATUS, &status); glGetShaderiv(sceneFragmentShader, GL_COMPILE_STATUS, &status2); glGetShaderiv(screenVertexShader, GL_COMPILE_STATUS, &status3); glGetShaderiv(screenFragmentShader, GL_COMPILE_STATUS, &status4); if ( OpenGLError != 0 || status == 0 || status2 == 0 || status3 == 0 || status4 == 0 || frameBufferStatus != GL_FRAMEBUFFER_COMPLETE) { char buffer1[512], buffer2[512], buffer3[512], buffer4[512]; glGetShaderInfoLog(sceneVertexShader, 512, NULL, buffer1); glGetShaderInfoLog(sceneFragmentShader, 512, NULL, buffer2); glGetShaderInfoLog(screenVertexShader, 512, NULL, buffer3); glGetShaderInfoLog(screenFragmentShader, 512, NULL, buffer4); std::ofstream errorOutput; GLchar* errorOutFilename = "shader_errors.txt"; errorOutput.open(errorOutFilename); errorOutput << "GL_Error: " << OpenGLError << "\n Scene vertex shader status: " << status << "\n Scene vertex shader log: " << buffer1 << "\n Scene fragment shader status: " << status2 << "\n Scene fragment shader log: " << buffer2 << "\n Screen vertex shader status: " << status3 << "\n Screen vertex shader log: " << buffer3 << "\n Screen fragment shader status: " << status4 << "\n Screen fragment shader log: " << buffer4 << "\n Frame buffer status: " << frameBufferStatus << "\n OpenGL version: " << glGetString(GL_VERSION); errorOutput.close(); std::cerr << "An error has occured with shaders or frame buffer! See " << errorOutFilename << " for more info!\n Terminating program in 10s!" << std::endl; SDL_Delay(10000); quit = GL_TRUE; } SDL_Event e; while (!quit) { while (SDL_PollEvent(&e) != 0) { if (e.type == SDL_QUIT) { quit = GL_TRUE; } else if (e.type == SDL_KEYDOWN) { switch (e.key.keysym.sym) { case SDLK_RETURN: directionx = 1.0f; directiony = 0.0f; directionz = 0.0f; break; case SDLK_SPACE: directionx = 0.0f; directiony = 1.0f; directionz = 0.0f; break; case SDLK_LCTRL: directionx = 0.0f; directiony = 0.0f; directionz = 1.0f; default: directionx = 0.0f; directiony = 0.0f; directionz = 1.0f; break; } } } // Bind framebuffer and draw 3D scene glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); glBindVertexArray(vaoCube); glEnable(GL_DEPTH_TEST); glUseProgram(sceneShaderProgram); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texKitten); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texPuppy); // Clear screen to greenish glClearColor(0.15f, 0.7f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Calculate transformation auto t_now = std::chrono::high_resolution_clock::now(); float time = std::chrono::duration_cast<std::chrono::duration<float>>(t_now - t_start).count(); glm::mat4 model; model = glm::rotate(model, time * glm::radians(180.f), glm::vec3(directionx, directiony, directionz)); glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model)); // Draw cube glDrawArrays(GL_TRIANGLES, 0, 36); glEnable(GL_STENCIL_TEST); // Draw floor glStencilFunc(GL_ALWAYS, 1, 0xFF); // Set any stencil to 1 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glStencilMask(0xFF); // Write to stencil buffer glDepthMask(GL_FALSE); // Don't write to depth buffer glClear(GL_STENCIL_BUFFER_BIT); // Clear stencil buffer (0 by default) glDrawArrays(GL_TRIANGLES, 36, 6); // Draw cube reflection glStencilFunc(GL_EQUAL, 1, 0xFF); // Pass test if stencil value is 1 glStencilMask(0x00); // Don't write anything to stencil buffer glDepthMask(GL_TRUE); // Write to depth buffer model = glm::scale(glm::translate(model, glm::vec3(0, 0, -1)), glm::vec3(1, 1, -1)); glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model)); glUniform3f(uniColor, 0.3f, 0.3f, 0.3f); glDrawArrays(GL_TRIANGLES, 0, 36); glUniform3f(uniColor, 1.0f, 1.0f, 1.0f); glDisable(GL_STENCIL_TEST); // Bind default framebuffer and draw contents of our framebuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindVertexArray(vaoQuad); glDisable(GL_DEPTH_TEST); glUseProgram(screenShaderProgram); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texColorBuffer); glDrawArrays(GL_TRIANGLES, 0, 6); // Swap buffers SDL_GL_SwapWindow(window); } glDeleteRenderbuffers(1, &rboDepthStencil); glDeleteTextures(1, &texColorBuffer); glDeleteFramebuffers(1, &frameBuffer); glDeleteTextures(1, &texKitten); glDeleteTextures(1, &texPuppy); glDeleteProgram(screenShaderProgram); glDeleteShader(screenFragmentShader); glDeleteShader(screenVertexShader); glDeleteProgram(sceneShaderProgram); glDeleteShader(sceneFragmentShader); glDeleteShader(sceneVertexShader); glDeleteBuffers(1, &vboCube); glDeleteBuffers(1, &vboQuad); glDeleteVertexArrays(1, &vaoCube); glDeleteVertexArrays(1, &vaoQuad); SDL_GL_DeleteContext(context); SDL_Quit(); return 0; }
GLuint LoadShaders(ShaderInfo* shaders) { if (shaders == NULL) { return 0; } GLuint program = glCreateProgram(); ShaderInfo* entry = shaders; while (entry->type != GL_NONE) { GLuint shader = glCreateShader(entry->type); entry->shader = shader; const GLchar* source = ReadShader(entry->filename); if (source == NULL) { for (entry = shaders; entry->type != GL_NONE; ++entry) { glDeleteShader(entry->shader); entry->shader = 0; } return 0; } glShaderSource(shader, 1, &source, NULL); delete[] source; glCompileShader(shader); GLint compiled; glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); if (!compiled) { #ifdef _DEBUG GLsizei len; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len); GLchar* log = new GLchar[len + 1]; glGetShaderInfoLog(shader, len, &len, log); std::cerr << "Shader compilation failed: " << log << std::endl; delete[] log; #endif /* DEBUG */ return 0; } glAttachShader(program, shader); ++entry; } glLinkProgram(program); GLint linked; glGetProgramiv(program, GL_LINK_STATUS, &linked); if (!linked) { #ifdef _DEBUG GLsizei len; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len); GLchar* log = new GLchar[len + 1]; glGetProgramInfoLog(program, len, &len, log); std::cerr << "Shader linking failed: " << log << std::endl; delete[] log; #endif /* DEBUG */ for (entry = shaders; entry->type != GL_NONE; ++entry) { glDeleteShader(entry->shader); entry->shader = 0; } return 0; } return program; }
bool GLSLShader_vinit(GLSLShader * self, const char * vshaderSource, size_t vshaderLength, const char * fshaderSource, size_t fshaderLength, va_list args) { GLint shaderLength; GLuint vertexShader, fragmentShader; const char * attribName; GLuint attribLocation; #ifdef DEBUG GLint logLength; #endif call_super(init, self); self->dispose = GLSLShader_dispose; self->getUniformLocation = GLSLShader_getUniformLocation; self->activate = GLSLShader_activate; self->deactivate = GLSLShader_deactivate; self->validate = GLSLShader_validate; self->program = glCreateProgram(); vertexShader = glCreateShader(GL_VERTEX_SHADER); fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); shaderLength = vshaderLength; glShaderSource(vertexShader, 1, (const GLchar **) &vshaderSource, &shaderLength); glCompileShader(vertexShader); #ifdef DEBUG glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 0) { GLchar * log = malloc(logLength); glGetShaderInfoLog(vertexShader, logLength, &logLength, log); if (logLength > 0) { // Surprisingly enough, this is not always true! In the glgraphics test harness, Windows gives me 1 the first time, and 0 the second... fprintf(stderr, "Vertex shader compile log:\n%s\n", log); } free(log); } #endif shaderLength = fshaderLength; glShaderSource(fragmentShader, 1, (const GLchar **) &fshaderSource, &shaderLength); glCompileShader(fragmentShader); #ifdef DEBUG glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 0) { GLchar * log = malloc(logLength); glGetShaderInfoLog(fragmentShader, logLength, &logLength, log); if (logLength > 0) { fprintf(stderr, "Fragment shader compile log:\n%s\n", log); } free(log); } #endif glAttachShader(self->program, vertexShader); glAttachShader(self->program, fragmentShader); for (attribName = va_arg(args, const char *); attribName != NULL; attribName = va_arg(args, const char *)) { attribLocation = va_arg(args, GLuint); glBindAttribLocation(self->program, attribLocation, attribName); } glLinkProgram(self->program); #ifdef DEBUG glGetProgramiv(self->program, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 0) { GLchar * log = malloc(logLength); glGetProgramInfoLog(self->program, logLength, &logLength, log); if (logLength > 0) { fprintf(stderr, "Program link log:\n%s\n", log); } free(log); } #endif glDeleteShader(vertexShader); glDeleteShader(fragmentShader); return true; }
static GLProgram* createShaders(const char *vertexShaderText, const char *fragShaderText, int texCount) { GLProgram *glProgram = NULL; GLint stat; #define BUFFER_SIZE 256 char log[BUFFER_SIZE]; GLsizei logSize; glProgram = calloc(1, sizeof(GLProgram)); if (!glProgram) return NULL; glProgram->vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(glProgram->vertexShader, 1, (const char **) &vertexShaderText, NULL); glCompileShader(glProgram->vertexShader); glGetShaderiv(glProgram->vertexShader, GL_COMPILE_STATUS, &stat); if (!stat) { glGetShaderInfoLog(glProgram->vertexShader, BUFFER_SIZE, &logSize, log); ERROR(" vertex shader fail to compile!: %s", log); free(glProgram); return NULL; } glProgram->fragShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(glProgram->fragShader, 1, (const char **) &fragShaderText, NULL); glCompileShader(glProgram->fragShader); glGetShaderiv(glProgram->fragShader, GL_COMPILE_STATUS, &stat); if (!stat) { glGetShaderInfoLog(glProgram->fragShader, BUFFER_SIZE, &logSize, log); ERROR(" fragment shader fail to compile!: %s", log); free(glProgram); return NULL; } glProgram->program = glCreateProgram(); glAttachShader(glProgram->program, glProgram->fragShader); glAttachShader(glProgram->program, glProgram->vertexShader); glLinkProgram(glProgram->program); glGetProgramiv(glProgram->program, GL_LINK_STATUS, &stat); if (!stat) { glGetProgramInfoLog(glProgram->program, BUFFER_SIZE, &logSize, log); printf("Shader fail to link!: %s\n", log); free(glProgram); return NULL; } glUseProgram(glProgram->program); glProgram->texCount = texCount; glProgram->attrPosition = glGetAttribLocation(glProgram->program, "pos"); glProgram->attrTexCoord = glGetAttribLocation(glProgram->program, "texcoord"); glProgram->uniformTex[0] = glGetUniformLocation(glProgram->program, "tex0"); // glProgram->uniformTex[1] = glGetUniformLocation(glProgram->program, "tex1"); // glProgram->uniformTex[2] = glGetUniformLocation(glProgram->program, "tex2"); INFO("Attrib pos at %d\n", glProgram->attrPosition); INFO("Attrib texcoord at %d\n", glProgram->attrTexCoord); INFO("texture (0, %d), (1, %d), (2, %d) \n", glProgram->uniformTex[0], glProgram->uniformTex[1], glProgram->uniformTex[2]); return glProgram; }
void Poh::gLib::Shader::glibShader::Build(Poh::gLib::Application::itfApplication * _application, const char * VertexShaderSource, const char * FragmentShaderSource) { if (_application->MakeContextCurrent() != 0) { throw glibException(GLIB_ERROR_TYPE_SHADER | OPENGL_CONTEXT_ERROR); } if (_shader != 0) { } if (glewInit() != GLEW_OK) { throw glibException(GLIB_ERROR_TYPE_SHADER | OPENGL_CONTEXT_ERROR); } _shader = glCreateProgram(); if (_shader == 0) { throw glibException(GLIB_ERROR_TYPE_SHADER | OPENGL_SHADER_OVERRIDE_ERROR); } GLint success = 0; success = 0; GLuint _vShr = glCreateShader(GL_VERTEX_SHADER); glShaderSource(_vShr, 1, &VertexShaderSource, 0); glCompileShader(_vShr); glGetShaderiv(_vShr, GL_COMPILE_STATUS, &success); if (success != GL_TRUE) { GLint len = 0; glGetShaderiv(_vShr, GL_INFO_LOG_LENGTH, &success); GLchar * log = new GLchar[len]{}; glGetShaderInfoLog(_vShr, len, 0, log); delete[] log; } success = 0; GLuint _fShr = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(_fShr, 1, &FragmentShaderSource, 0); glCompileShader(_fShr); glGetShaderiv(_fShr, GL_COMPILE_STATUS, &success); if (success != GL_TRUE) { GLint len = 0; glGetShaderiv(_fShr, GL_INFO_LOG_LENGTH, &success); GLchar * log = new GLchar[len]{}; glGetShaderInfoLog(_fShr, len, 0, log); delete[] log; } glAttachShader(_shader, _vShr); glAttachShader(_shader, _fShr); glLinkProgram(_shader); success = 0; glGetProgramiv(_shader, GL_LINK_STATUS, &success); if (success != GL_TRUE) { GLint len = 0; glGetProgramiv(_shader, GL_INFO_LOG_LENGTH, &success); GLchar * log = new GLchar[len]{}; glGetProgramInfoLog(_shader, len, 0, log); delete[] log; } glDeleteShader(_vShr); glDeleteShader(_fShr); glGenBuffers(1, &_vbo); glGenVertexArrays(1, &_vao); }
Effect* Effect::createFromSource(const char* vshPath, const char* vshSource, const char* fshPath, const char* fshSource, const char* defines) { GP_ASSERT(vshSource); GP_ASSERT(fshSource); const unsigned int SHADER_SOURCE_LENGTH = 3; const GLchar* shaderSource[SHADER_SOURCE_LENGTH]; char* infoLog = NULL; GLuint vertexShader; GLuint fragmentShader; GLuint program; GLint length; GLint success; // Compile vertex shader. std::string definesStr = (defines == NULL) ? "" : defines; #ifdef OPENGL_ES if (defines && strlen(defines) != 0) definesStr += "\n"; definesStr+= OPENGL_ES_DEFINE; #endif shaderSource[0] = definesStr.c_str(); shaderSource[1] = "\n"; shaderSource[2] = vshSource; GL_ASSERT( vertexShader = glCreateShader(GL_VERTEX_SHADER) ); GL_ASSERT( glShaderSource(vertexShader, SHADER_SOURCE_LENGTH, shaderSource, NULL) ); GL_ASSERT( glCompileShader(vertexShader) ); GL_ASSERT( glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success) ); if (success != GL_TRUE) { GL_ASSERT( glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &length) ); if (length > 0) { infoLog = new char[length]; GL_ASSERT( glGetShaderInfoLog(vertexShader, length, NULL, infoLog) ); infoLog[length-1] = '\0'; } GP_ERROR("Compile failed for vertex shader '%s' with error '%s'.", vshPath == NULL ? "NULL" : vshPath, infoLog == NULL ? "" : infoLog); SAFE_DELETE_ARRAY(infoLog); // Clean up. GL_ASSERT( glDeleteShader(vertexShader) ); return NULL; } // Compile the fragment shader. shaderSource[2] = fshSource; GL_ASSERT( fragmentShader = glCreateShader(GL_FRAGMENT_SHADER) ); GL_ASSERT( glShaderSource(fragmentShader, SHADER_SOURCE_LENGTH, shaderSource, NULL) ); GL_ASSERT( glCompileShader(fragmentShader) ); GL_ASSERT( glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success) ); if (success != GL_TRUE) { GL_ASSERT( glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &length) ); if (length > 0) { infoLog = new char[length]; GL_ASSERT( glGetShaderInfoLog(fragmentShader, length, NULL, infoLog) ); infoLog[length-1] = '\0'; } GP_ERROR("Compile failed for fragment shader (%s): %s", fshPath == NULL ? "NULL" : fshPath, infoLog == NULL ? "" : infoLog); SAFE_DELETE_ARRAY(infoLog); // Clean up. GL_ASSERT( glDeleteShader(vertexShader) ); GL_ASSERT( glDeleteShader(fragmentShader) ); return NULL; } // Link program. GL_ASSERT( program = glCreateProgram() ); GL_ASSERT( glAttachShader(program, vertexShader) ); GL_ASSERT( glAttachShader(program, fragmentShader) ); GL_ASSERT( glLinkProgram(program) ); GL_ASSERT( glGetProgramiv(program, GL_LINK_STATUS, &success) ); // Delete shaders after linking. GL_ASSERT( glDeleteShader(vertexShader) ); GL_ASSERT( glDeleteShader(fragmentShader) ); // Check link status. if (success != GL_TRUE) { GL_ASSERT( glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length) ); if (length > 0) { infoLog = new char[length]; GL_ASSERT( glGetProgramInfoLog(program, length, NULL, infoLog) ); infoLog[length-1] = '\0'; } GP_ERROR("Linking program failed (%s,%s): %s", vshPath == NULL ? "NULL" : vshPath, fshPath == NULL ? "NULL" : fshPath, infoLog == NULL ? "" : infoLog); SAFE_DELETE_ARRAY(infoLog); // Clean up. GL_ASSERT( glDeleteProgram(program) ); return NULL; } // Create and return the new Effect. Effect* effect = new Effect(); effect->_program = program; // Query and store vertex attribute meta-data from the program. // NOTE: Rather than using glBindAttribLocation to explicitly specify our own // preferred attribute locations, we're going to query the locations that were // automatically bound by the GPU. While it can sometimes be convenient to use // glBindAttribLocation, some vendors actually reserve certain attribute indices // and thereore using this function can create compatibility issues between // different hardware vendors. GLint activeAttributes; GL_ASSERT( glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &activeAttributes) ); if (activeAttributes > 0) { GL_ASSERT( glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &length) ); if (length > 0) { GLchar* attribName = new GLchar[length + 1]; GLint attribSize; GLenum attribType; GLint attribLocation; for (int i = 0; i < activeAttributes; ++i) { // Query attribute info. GL_ASSERT( glGetActiveAttrib(program, i, length, NULL, &attribSize, &attribType, attribName) ); attribName[length] = '\0'; // Query the pre-assigned attribute location. GL_ASSERT( attribLocation = glGetAttribLocation(program, attribName) ); // Assign the vertex attribute mapping for the effect. effect->_vertexAttributes[attribName] = attribLocation; } SAFE_DELETE_ARRAY(attribName); } } // Query and store uniforms from the program. GLint activeUniforms; GL_ASSERT( glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &activeUniforms) ); if (activeUniforms > 0) { GL_ASSERT( glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &length) ); if (length > 0) { GLchar* uniformName = new GLchar[length + 1]; GLint uniformSize; GLenum uniformType; GLint uniformLocation; unsigned int samplerIndex = 0; for (int i = 0; i < activeUniforms; ++i) { // Query uniform info. GL_ASSERT( glGetActiveUniform(program, i, length, NULL, &uniformSize, &uniformType, uniformName) ); uniformName[length] = '\0'; // null terminate if (uniformSize > 1 && length > 3) { // This is an array uniform. I'm stripping array indexers off it since GL does not // seem to be consistent across different drivers/implementations in how it returns // array uniforms. On some systems it will return "u_matrixArray", while on others // it will return "u_matrixArray[0]". char* c = strrchr(uniformName, '['); if (c) { *c = '\0'; } } // Query the pre-assigned uniform location. GL_ASSERT( uniformLocation = glGetUniformLocation(program, uniformName) ); Uniform* uniform = new Uniform(); uniform->_effect = effect; uniform->_name = uniformName; uniform->_location = uniformLocation; uniform->_type = uniformType; uniform->_index = uniformType == GL_SAMPLER_2D ? (samplerIndex++) : 0; effect->_uniforms[uniformName] = uniform; } SAFE_DELETE_ARRAY(uniformName); } } return effect; }
GLuint CreateProgram(const char* VertexShader, const char* FragmentShader) { Text sourceVert, sourceFrag; //Load Vertex Shader sourceVert.readTexFile(VertexShader); const char* vpString = sourceVert.getContent(); //Load Fragment Shader sourceFrag.readTexFile(FragmentShader); const char* fpString = sourceFrag.getContent(); GLuint programHandle = glCreateProgram(); GLint compileSuccess; GLchar compilerSpew[256]; //Attach Vertex Shader GLuint vsHandle = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vsHandle, 1, &vpString, 0); glCompileShader(vsHandle); glGetShaderiv(vsHandle, GL_COMPILE_STATUS, &compileSuccess); glGetShaderInfoLog(vsHandle, sizeof(compilerSpew), 0, compilerSpew); if (!compileSuccess) { std::cout<<"Failed to compile/attach"; } else { std::cout<<"Succeded to compile/attach"; } glAttachShader(programHandle, vsHandle); //Attach Fragment Shader GLuint fsHandle = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fsHandle, 1, &fpString, 0); glCompileShader(fsHandle); glAttachShader(programHandle, fsHandle); glGetShaderiv(fsHandle, GL_COMPILE_STATUS, &compileSuccess); glGetShaderInfoLog(fsHandle, sizeof(compilerSpew), 0, compilerSpew); if (!compileSuccess) { std::cout<<"Failed to compile/attach"; } else { std::cout<<"Succeded to compile/attach"; } glLinkProgram(programHandle); GLint linkSuccess; glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess); glGetProgramInfoLog(programHandle, sizeof(compilerSpew), 0, compilerSpew); if (!linkSuccess) { std::cout<<"Failed to compile/attach"; } else { std::cout<<"Succeded to compile/attach"; } return programHandle; }
bool LoadShader() { if (sg_loaded) return true; // compile shaders unsigned int vertexShaderID = Compile(RENDERER_VERTEX_SHADER_FILE, GL_VERTEX_SHADER); if (0 == vertexShaderID) return false; unsigned int fragmentShaderID = Compile(RENDERER_FRAGMENT_SHADER_FILE, GL_FRAGMENT_SHADER); if (0 == fragmentShaderID) return false; // attach shaders sg_shaderID = glCreateProgram(); glAttachShader(sg_shaderID, vertexShaderID); glAttachShader(sg_shaderID, fragmentShaderID); // note attribute and output locations glBindAttribLocation(sg_shaderID, 0, "vertexPosition"); glBindAttribLocation(sg_shaderID, 1, "vertexNormal"); glBindAttribLocation(sg_shaderID, 2, "vertexTextureUV"); glBindFragDataLocation(sg_shaderID, 0, "fragmentColor"); // link program glLinkProgram(sg_shaderID); // cleanup glDeleteShader(vertexShaderID); glDeleteShader(fragmentShaderID); // check for success GLint success = GL_FALSE; glGetProgramiv(sg_shaderID, GL_LINK_STATUS, &success); // if successful, if (GL_TRUE == success) { // start finding and setting uniform values glUseProgram(sg_shaderID); sg_modelLocation = glGetUniformLocation(sg_shaderID, "model"); sg_projectionViewLocation = glGetUniformLocation(sg_shaderID, "projectionView"); sg_diffuseColorLocation = glGetUniformLocation(sg_shaderID, "diffuseColor"); sg_specularColorLocation = glGetUniformLocation(sg_shaderID, "specularColor"); sg_hasTextureLocation = glGetUniformLocation(sg_shaderID, "hasTexture"); sg_textureLocation = glGetUniformLocation(sg_shaderID, "texture"); sg_cameraPositionLocation = glGetUniformLocation(sg_shaderID, "cameraPosition"); sg_ambientLightLocation = glGetUniformLocation(sg_shaderID, "lightAmbient"); char buffer[50]; for (unsigned int i = 0; i < RENDERER_MAX_LIGHTS; ++i) { sprintf_s(buffer, "lights[%d].color", i); sg_lightColorLocations[i] = glGetUniformLocation(sg_shaderID, buffer); sprintf_s(buffer, "lights[%d].direction", i); sg_lightDirectionLocations[i] = glGetUniformLocation(sg_shaderID, buffer); sprintf_s(buffer, "lights[%d].position", i); sg_lightPositionLocations[i] = glGetUniformLocation(sg_shaderID, buffer); sprintf_s(buffer, "lights[%d].power", i); sg_lightPowerLocations[i] = glGetUniformLocation(sg_shaderID, buffer); sprintf_s(buffer, "lights[%d].attenuation", i); sg_lightAttenuationLocations[i] = glGetUniformLocation(sg_shaderID, buffer); sprintf_s(buffer, "lights[%d].angle", i); sg_lightAngleLocations[i] = glGetUniformLocation(sg_shaderID, buffer); sprintf_s(buffer, "lights[%d].blur", i); sg_lightBlurLocations[i] = glGetUniformLocation(sg_shaderID, buffer); } sg_lightCountLocation = glGetUniformLocation(sg_shaderID, "lightCount"); // loading successful! sg_loaded = true; return true; } // otherwise, get the size of the error log int logSize = 0; glGetShaderiv(sg_shaderID, GL_INFO_LOG_LENGTH, &logSize); // copy the error log char* log = new char[logSize]; glGetShaderInfoLog(sg_shaderID, logSize, 0, log); // print the error log printf("Error linking shader:\n%s\n", log); // cleanup delete[] log; glDeleteProgram(sg_shaderID); sg_shaderID = 0; // indicate failure sg_loaded = false; return false; }
/* ‘ункци¤ инициализации шейдерной программы. * ј–√”ћ≈Ќ“џ: * - имена файлов вершинного и фрагментного шейдеров: * CHAR *VSFileName, *FSFileName; * ¬ќ«¬–јўј≈ћќ≈ «Ќј„≈Ќ»≈: * (UINT) - идентификатор загруженной и скомпилированной * программы или 0 при ошибке. */ UINT AS4_ShadProgInit( CHAR *VSFileName, CHAR *FSFileName ) { CHAR *txt; UINT shv, shf, prg; INT res, len; static CHAR Buf[1000]; /* »нициализируем вершинный шейдер */ if ((txt = LoadFile(VSFileName)) == NULL) { if (!AS4_Anim.mute) Beep(800, 500); return 0; } if ((shv = glCreateShader(GL_VERTEX_SHADER)) == 0) { if (!AS4_Anim.mute) Beep(800, 500); free(txt); return 0; } /* закрепл¤ем текст */ glShaderSource(shv, 1, &txt, NULL); free(txt); /* компилируем шейдер */ glCompileShader(shv); glGetShaderiv(shv, GL_COMPILE_STATUS, &res); if (res != 1) { if (!AS4_Anim.mute) Beep(800, 500); glGetShaderInfoLog(shv, sizeof(Buf), &len, Buf); glDeleteShader(shv); return 0; } /* »нициализируем фрагментный шейдер */ if ((txt = LoadFile(FSFileName)) == NULL) { if (!AS4_Anim.mute) Beep(800, 500); glDeleteShader(shv); return 0; } if ((shf = glCreateShader(GL_FRAGMENT_SHADER)) == 0) { if (!AS4_Anim.mute) Beep(800, 500); glDeleteShader(shv); free(txt); return 0; } /* закрепл¤ем текст */ glShaderSource(shf, 1, &txt, NULL); free(txt); /* компилируем шейдер */ glCompileShader(shf); glGetShaderiv(shf, GL_COMPILE_STATUS, &res); if (res != 1) { if (!AS4_Anim.mute) Beep(800, 500); glGetShaderInfoLog(shf, sizeof(Buf), &len, Buf); glDeleteShader(shf); glDeleteShader(shv); return 0; } /* »нициализируем программу - набор шейдеров */ if ((prg = glCreateProgram()) == 0) { if (!AS4_Anim.mute) Beep(1000, 500); glDeleteShader(shf); glDeleteShader(shv); return 0; } /* присоедин¤ем к программе шейдера */ glAttachShader(prg, shv); glAttachShader(prg, shf); /* компонуем программу */ glLinkProgram(prg); glGetProgramiv(prg, GL_LINK_STATUS, &res); if (res != 1) { if (!AS4_Anim.mute) Beep(1000, 500); glGetProgramInfoLog(prg, sizeof(Buf), &len, Buf); glDetachShader(prg, shv); glDetachShader(prg, shf); glDeleteShader(shv); glDeleteShader(shf); glDeleteProgram(prg); return 0; } return prg; } /* End of 'AS4_ShadProgInit' function */