GLuint GLSLProgram::compileProgram(const char *vsource, const char *gsource, const char *fsource, GLenum gsInput, GLenum gsOutput) { GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); GLint compiled = 0; glShaderSource(vertexShader, 1, &vsource, 0); glShaderSource(fragmentShader, 1, &fsource, 0); glCompileShader(vertexShader); if (checkCompileStatus(vertexShader, &compiled) == 0) { printf("<compileProgram compilation error with vertexShader>:\n"); printf("%s\n", vsource); return 0; } glCompileShader(fragmentShader); if (checkCompileStatus(fragmentShader, &compiled) == 0) { printf("<compileProgram compilation error with fragmentShader>:\n"); printf("%s\n", fsource); return 0; } GLuint program = glCreateProgram(); glAttachShader(program, vertexShader); glAttachShader(program, fragmentShader); if (gsource) { GLuint geomShader = glCreateShader(GL_GEOMETRY_SHADER_EXT); glShaderSource(geomShader, 1, &gsource, 0); glCompileShader(geomShader); glGetShaderiv(geomShader, GL_COMPILE_STATUS, (GLint *)&compiled); if (checkCompileStatus(geomShader, &compiled) == 0) { printf("<compileProgram compilation error with geomShader>:\n"); printf("%s\n", gsource); return 0; } glAttachShader(program, geomShader); glProgramParameteriEXT(program, GL_GEOMETRY_INPUT_TYPE_EXT, gsInput); glProgramParameteriEXT(program, GL_GEOMETRY_OUTPUT_TYPE_EXT, gsOutput); glProgramParameteriEXT(program, GL_GEOMETRY_VERTICES_OUT_EXT, 4); } glLinkProgram(program); // check if program linked GLint success = 0; glGetProgramiv(program, GL_LINK_STATUS, &success); if (!success) { char temp[1024]; glGetProgramInfoLog(program, 1024, 0, temp); fprintf(stderr, "Failed to link program:\n%s\n", temp); glDeleteProgram(program); program = 0; exit(EXIT_FAILURE); } return program; }
/** * Takes a description of shader program, compiles it and gets the locations * of uniforms and attributes. * * @param p The shader program state. * @return Zero if successful. */ int raspitexutil_build_shader_program(RASPITEXUTIL_SHADER_PROGRAM_T *p) { GLint status; int i = 0; char log[1024]; int logLen = 0; vcos_assert(p); vcos_assert(p->vertex_source); vcos_assert(p->fragment_source); if (! (p && p->vertex_source && p->fragment_source)) goto fail; p->vs = p->fs = 0; p->vs = glCreateShader(GL_VERTEX_SHADER); glShaderSource(p->vs, 1, &p->vertex_source, NULL); glCompileShader(p->vs); glGetShaderiv(p->vs, GL_COMPILE_STATUS, &status); if (! status) { glGetShaderInfoLog(p->vs, sizeof(log), &logLen, log); vcos_log_error("Program info log %s", log); goto fail; } p->fs = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(p->fs, 1, &p->fragment_source, NULL); glCompileShader(p->fs); glGetShaderiv(p->fs, GL_COMPILE_STATUS, &status); if (! status) { glGetShaderInfoLog(p->fs, sizeof(log), &logLen, log); vcos_log_error("Program info log %s", log); goto fail; } p->program = glCreateProgram(); glAttachShader(p->program, p->vs); glAttachShader(p->program, p->fs); glLinkProgram(p->program); glGetProgramiv(p->program, GL_LINK_STATUS, &status); if (! status) { vcos_log_error("Failed to link shader program"); glGetProgramInfoLog(p->program, sizeof(log), &logLen, log); vcos_log_error("Program info log %s", log); goto fail; } for (i = 0; i < SHADER_MAX_ATTRIBUTES; ++i) { if (! p->attribute_names[i]) break; p->attribute_locations[i] = glGetAttribLocation(p->program, p->attribute_names[i]); if (p->attribute_locations[i] == -1) { vcos_log_error("Failed to get location for attribute %s", p->attribute_names[i]); goto fail; } else { vcos_log_trace("Attribute for %s is %d", p->attribute_names[i], p->attribute_locations[i]); } } for (i = 0; i < SHADER_MAX_UNIFORMS; ++i) { if (! p->uniform_names[i]) break; p->uniform_locations[i] = glGetUniformLocation(p->program, p->uniform_names[i]); if (p->uniform_locations[i] == -1) { vcos_log_error("Failed to get location for uniform %s", p->uniform_names[i]); goto fail; } else { vcos_log_trace("Uniform for %s is %d", p->uniform_names[i], p->uniform_locations[i]); } } return 0; fail: vcos_log_error("%s: Failed to build shader program", VCOS_FUNCTION); if (p) { glDeleteProgram(p->program); glDeleteShader(p->fs); glDeleteShader(p->vs); } return -1; }
GLuint OpenGL_CompileProgram(const char* vertexShader, const char* fragmentShader) { // generate objects GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER); GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); GLuint programID = glCreateProgram(); // compile vertex shader glShaderSource(vertexShaderID, 1, &vertexShader, NULL); glCompileShader(vertexShaderID); #if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL) GLint Result = GL_FALSE; char stringBuffer[1024]; GLsizei stringBufferUsage = 0; glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &Result); glGetShaderInfoLog(vertexShaderID, 1024, &stringBufferUsage, stringBuffer); if (Result && stringBufferUsage) { // not nice } else if (!Result) { // not nice } else { // not nice } bool shader_errors = !Result; #endif // compile fragment shader glShaderSource(fragmentShaderID, 1, &fragmentShader, NULL); glCompileShader(fragmentShaderID); #if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL) glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &Result); glGetShaderInfoLog(fragmentShaderID, 1024, &stringBufferUsage, stringBuffer); if (Result && stringBufferUsage) { // not nice } else if (!Result) { // not nice } else { // not nice } shader_errors |= !Result; #endif // link them glAttachShader(programID, vertexShaderID); glAttachShader(programID, fragmentShaderID); glLinkProgram(programID); #if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL) glGetProgramiv(programID, GL_LINK_STATUS, &Result); glGetProgramInfoLog(programID, 1024, &stringBufferUsage, stringBuffer); if (Result && stringBufferUsage) { // not nice } else if (!Result && !shader_errors) { // not nice } #endif // cleanup glDeleteShader(vertexShaderID); glDeleteShader(fragmentShaderID); return programID; }
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(); } else { printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path); getchar(); return 0; } // 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); if (InfoLogLength > 0) { std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1); glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); printf("%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); if (InfoLogLength > 0) { std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1); glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); printf("%s\n", &FragmentShaderErrorMessage[0]); } // Link the program printf("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); if (InfoLogLength > 0) { std::vector<char> ProgramErrorMessage(InfoLogLength + 1); glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); printf("%s\n", &ProgramErrorMessage[0]); } glDeleteShader(VertexShaderID); glDeleteShader(FragmentShaderID); return ProgramID; }
void YsGLSLCompileAndLinkVertexAndFragmentShader( GLuint programId, GLuint vertexShaderId, const int nVertexShaderProgLine,const char * const vertexShaderProg[], GLuint fragmentShaderId, const int nFragShaderProgLine,const char * const fragShaderProg[]) { const int errMsgLen=1024; char errMsg[1024]; int compileSta=99999,infoLogLength=99999,acquiredErrMsgLen=99999; int linkSta=99999; char *vertexShaderProgramLinear=MakeLinearString(nYSGLSL_header,YSGLSL_header,nVertexShaderProgLine,vertexShaderProg); char *fragmentShaderProgramLinear=MakeLinearString(nYSGLSL_header,YSGLSL_header,nFragShaderProgLine,fragShaderProg); /* The following two function call is supposed to be allowed by the OpenGL specification. However, the OpenGL driver of VirtualBox 4.3.20 Linux Guest is bugged, and it only reads the first line. Needs a trick. glShaderSource( vertexShaderId, nVertexShaderProgLine,(const char **)vertexShaderProg, NULL); // Last NULL assumes each line is C string glShaderSource( fragmentShaderId, nFragShaderProgLine,(const char **)fragShaderProg, NULL); // Last NULL assumes each line is C string */ glShaderSource(vertexShaderId,1,&vertexShaderProgramLinear,NULL); glShaderSource(fragmentShaderId,1,&fragmentShaderProgramLinear,NULL); glCompileShader(vertexShaderId); glGetShaderiv(vertexShaderId,GL_COMPILE_STATUS,&compileSta); glGetShaderiv(vertexShaderId,GL_INFO_LOG_LENGTH,&infoLogLength); glGetShaderInfoLog(vertexShaderId,errMsgLen-1,&acquiredErrMsgLen,errMsg); printf("Compile Status %d Info Log Length %d Error Message Length %d\n",compileSta,infoLogLength,acquiredErrMsgLen); if(GL_TRUE!=compileSta) { int i; printf("Error Message: \n%s\n",errMsg); for(i=0; i<nYSGLSL_header; ++i) { printf("%3d: %s",i+1,YSGLSL_header[i]); } for(i=0; i<nVertexShaderProgLine; ++i) { printf("%3d: %s",i+nYSGLSL_header,vertexShaderProg[i]); } printf("\n"); } glCompileShader(fragmentShaderId); glGetShaderiv(fragmentShaderId,GL_COMPILE_STATUS,&compileSta); glGetShaderiv(fragmentShaderId,GL_INFO_LOG_LENGTH,&infoLogLength); glGetShaderInfoLog(fragmentShaderId,errMsgLen-1,&acquiredErrMsgLen,errMsg); printf("Compile Status %d Info Log Length %d Error Message Length %d\n",compileSta,infoLogLength,acquiredErrMsgLen); if(GL_TRUE!=compileSta) { int i; printf("Error Message: \n%s\n",errMsg); for(i=0; i<nYSGLSL_header; ++i) { printf("%3d: %s",i+1,YSGLSL_header[i]); } for(i=0; i<nFragShaderProgLine; ++i) { printf("%3d: %s",i+nYSGLSL_header+1,fragShaderProg[i]); } printf("\n"); } { // http://stackoverflow.com/questions/10771926/glvertexattrib4f-not-working-in-os-x-but-works-fine-in-ios // In MacOSX, generic attribute (given by glVertexAttrib??) cannot be used for attribute location 0. // And, stupidly MacOSX's OpenGL may assign location 0 to an attribute that may be given as a location 0. // Therefore, the location needs to be given explicitly for the attributes that may be given as a generic attrib. // 2014/08/24 // This explicit binding solved Flat 3D renderer problem. However, it didn't solve MonoColorPerPix and MonoColorPerVtx 3D renderers. // Looks like I cannot count on generic attribute in Mac OSX. (Just like point sprite.) int attribLoc=1; int i; for(i=0; i<nVertexShaderProgLine; ++i) { int j; int isAttrib=0; for(j=0; 0!=vertexShaderProg[i][j]; ++j) { if(' '!=vertexShaderProg[i][j] && '\t'!=vertexShaderProg[i][j]) { if(0==strncmp(vertexShaderProg[i]+j,"attribute",9)) { isAttrib=1; } break; } } if(0!=isAttrib) { char attribName[256]={0}; int semiColonPos=-1; for(j=(int)strlen(vertexShaderProg[i])-1; 0<=j; --j) { if(';'==vertexShaderProg[i][j]) { semiColonPos=j; } if(0<=semiColonPos && (' '==vertexShaderProg[i][j] || '\t'==vertexShaderProg[i][j])) { strncpy(attribName,vertexShaderProg[i]+j+1,semiColonPos-j-1); break; } } if(0!=attribName[0]) { if(0==strcmp("texCoord",attribName) || 0==strcmp("color",attribName) || 0==strcmp("colorIn",attribName)) { printf("Attrib Name=%s -> %d\n",attribName,attribLoc); glBindAttribLocation(programId,attribLoc,attribName); ++attribLoc; } else if(0==strcmp("vertex",attribName)) { printf("Attrib Name=%s -> %d\n",attribName,0); glBindAttribLocation(programId,0,attribName); } else { printf("Attrib Name=%s\n",attribName); } } } } } glAttachShader(programId,vertexShaderId); glAttachShader(programId,fragmentShaderId); glLinkProgram(programId); glGetProgramiv(programId,GL_LINK_STATUS,&linkSta); glGetProgramiv(programId,GL_INFO_LOG_LENGTH,&infoLogLength); glGetProgramInfoLog(programId,errMsgLen-1,&acquiredErrMsgLen,errMsg); printf("Link Status %d Info Log Length %d Error Message Length %d\n",linkSta,infoLogLength,acquiredErrMsgLen); if(GL_TRUE!=linkSta) { printf("Error Message: \n%s\n",errMsg); } free(vertexShaderProgramLinear); free(fragmentShaderProgramLinear); }
static unsigned int setup_shader(const char *vertex_shader, const char *fragment_shader) { GLuint vs=glCreateShader(GL_VERTEX_SHADER); glShaderSource(vs, 1, (const GLchar**)&vertex_shader, nullptr); glCompileShader(vs); int status, maxLength; char *infoLog=nullptr; glGetShaderiv(vs, GL_COMPILE_STATUS, &status); if(status==GL_FALSE) { glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &maxLength); /* The maxLength includes the NULL character */ infoLog = new char[maxLength]; glGetShaderInfoLog(vs, maxLength, &maxLength, infoLog); fprintf(stderr, "Vertex Shader Error: %s\n", infoLog); /* Handle the error in an appropriate way such as displaying a message or writing to a log file. */ /* In this simple program, we'll just leave */ delete [] infoLog; return 0; } GLuint fs=glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fs, 1, (const GLchar**)&fragment_shader, nullptr); glCompileShader(fs); glGetShaderiv(fs, GL_COMPILE_STATUS, &status); if(status==GL_FALSE) { glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &maxLength); /* The maxLength includes the NULL character */ infoLog = new char[maxLength]; glGetShaderInfoLog(fs, maxLength, &maxLength, infoLog); fprintf(stderr, "Fragment Shader Error: %s\n", infoLog); /* Handle the error in an appropriate way such as displaying a message or writing to a log file. */ /* In this simple program, we'll just leave */ delete [] infoLog; return 0; } unsigned int program=glCreateProgram(); // Attach our shaders to our program glAttachShader(program, vs); glAttachShader(program, fs); glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &status); if(status==GL_FALSE) { glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); /* The maxLength includes the NULL character */ infoLog = new char[maxLength]; glGetProgramInfoLog(program, maxLength, NULL, infoLog); glGetProgramInfoLog(program, maxLength, &maxLength, infoLog); fprintf(stderr, "Link Error: %s\n", infoLog); /* Handle the error in an appropriate way such as displaying a message or writing to a log file. */ /* In this simple program, we'll just leave */ delete [] infoLog; return 0; } return program; }
bool FShader::Load(const char * name, const char * vert_prog_lump, const char * frag_prog_lump, const char * proc_prog_lump, const char * defines) { static char buffer[10000]; FString error; int i_lump = Wads.CheckNumForFullName("shaders/glsl/shaderdefs.i", 0); if (i_lump == -1) I_Error("Unable to load 'shaders/glsl/shaderdefs.i'"); FMemLump i_data = Wads.ReadLump(i_lump); int vp_lump = Wads.CheckNumForFullName(vert_prog_lump, 0); if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump); FMemLump vp_data = Wads.ReadLump(vp_lump); int fp_lump = Wads.CheckNumForFullName(frag_prog_lump, 0); if (fp_lump == -1) I_Error("Unable to load '%s'", frag_prog_lump); FMemLump fp_data = Wads.ReadLump(fp_lump); // // The following code uses GetChars on the strings to get rid of terminating 0 characters. Do not remove or the code may break! // FString vp_comb; assert(GLRenderer->mLights != NULL); // On the shader side there is no difference between LM_DEFERRED and LM_DIRECT, it only decides how the buffer is initialized. unsigned int lightbuffertype = GLRenderer->mLights->GetBufferType(); unsigned int lightbuffersize = GLRenderer->mLights->GetBlockSize(); if (lightbuffertype == GL_UNIFORM_BUFFER) { // This differentiation is for some Intel drivers which fail on #extension, so use of #version 140 is necessary if (gl.glslversion < 1.4f) { vp_comb.Format("#version 130\n#extension GL_ARB_uniform_buffer_object : require\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize); } else { vp_comb.Format("#version 140\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize); } } else { vp_comb = "#version 400 core\n#extension GL_ARB_shader_storage_buffer_object : require\n#define SHADER_STORAGE_LIGHTS\n"; } if (gl.buffermethod == BM_DEFERRED) { vp_comb << "#define USE_QUAD_DRAWER\n"; } vp_comb << defines << i_data.GetString().GetChars(); FString fp_comb = vp_comb; vp_comb << vp_data.GetString().GetChars() << "\n"; fp_comb << fp_data.GetString().GetChars() << "\n"; if (proc_prog_lump != NULL) { if (*proc_prog_lump != '#') { int pp_lump = Wads.CheckNumForFullName(proc_prog_lump); if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump); FMemLump pp_data = Wads.ReadLump(pp_lump); if (pp_data.GetString().IndexOf("ProcessTexel") < 0) { // this looks like an old custom hardware shader. // We need to replace the ProcessTexel call to make it work. fp_comb.Substitute("vec4 frag = ProcessTexel();", "vec4 frag = Process(vec4(1.0));"); } fp_comb << pp_data.GetString().GetChars(); fp_comb.Substitute("gl_TexCoord[0]", "vTexCoord"); // fix old custom shaders. if (pp_data.GetString().IndexOf("ProcessLight") < 0) { int pl_lump = Wads.CheckNumForFullName("shaders/glsl/func_defaultlight.fp"); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders/glsl/func_defaultlight.fp"); FMemLump pl_data = Wads.ReadLump(pl_lump); fp_comb << "\n" << pl_data.GetString().GetChars(); } } else { // Proc_prog_lump is not a lump name but the source itself (from generated shaders) fp_comb << proc_prog_lump + 1; } } if (gl.flags & RFL_NO_CLIP_PLANES) { // On ATI's GL3 drivers we have to disable gl_ClipDistance because it's hopelessly broken. // This will cause some glitches and regressions but is the only way to avoid total display garbage. vp_comb.Substitute("gl_ClipDistance", "//"); } hVertProg = glCreateShader(GL_VERTEX_SHADER); hFragProg = glCreateShader(GL_FRAGMENT_SHADER); FGLDebug::LabelObject(GL_SHADER, hVertProg, vert_prog_lump); FGLDebug::LabelObject(GL_SHADER, hFragProg, frag_prog_lump); int vp_size = (int)vp_comb.Len(); int fp_size = (int)fp_comb.Len(); const char *vp_ptr = vp_comb.GetChars(); const char *fp_ptr = fp_comb.GetChars(); glShaderSource(hVertProg, 1, &vp_ptr, &vp_size); glShaderSource(hFragProg, 1, &fp_ptr, &fp_size); glCompileShader(hVertProg); glCompileShader(hFragProg); hShader = glCreateProgram(); FGLDebug::LabelObject(GL_PROGRAM, hShader, name); glAttachShader(hShader, hVertProg); glAttachShader(hShader, hFragProg); glBindAttribLocation(hShader, VATTR_VERTEX, "aPosition"); glBindAttribLocation(hShader, VATTR_TEXCOORD, "aTexCoord"); glBindAttribLocation(hShader, VATTR_COLOR, "aColor"); glBindAttribLocation(hShader, VATTR_VERTEX2, "aVertex2"); glBindAttribLocation(hShader, VATTR_NORMAL, "aNormal"); glBindFragDataLocation(hShader, 0, "FragColor"); glBindFragDataLocation(hShader, 1, "FragFog"); glBindFragDataLocation(hShader, 2, "FragNormal"); glLinkProgram(hShader); glGetShaderInfoLog(hVertProg, 10000, NULL, buffer); if (*buffer) { error << "Vertex shader:\n" << buffer << "\n"; } glGetShaderInfoLog(hFragProg, 10000, NULL, buffer); if (*buffer) { error << "Fragment shader:\n" << buffer << "\n"; } glGetProgramInfoLog(hShader, 10000, NULL, buffer); if (*buffer) { error << "Linking:\n" << buffer << "\n"; } int linked; glGetProgramiv(hShader, GL_LINK_STATUS, &linked); if (linked == 0) { // only print message if there's an error. I_Error("Init Shader '%s':\n%s\n", name, error.GetChars()); } muDesaturation.Init(hShader, "uDesaturationFactor"); muFogEnabled.Init(hShader, "uFogEnabled"); muPalLightLevels.Init(hShader, "uPalLightLevels"); muTextureMode.Init(hShader, "uTextureMode"); muCameraPos.Init(hShader, "uCameraPos"); muLightParms.Init(hShader, "uLightAttr"); muClipSplit.Init(hShader, "uClipSplit"); muColormapStart.Init(hShader, "uFixedColormapStart"); muColormapRange.Init(hShader, "uFixedColormapRange"); muLightIndex.Init(hShader, "uLightIndex"); muFogColor.Init(hShader, "uFogColor"); muDynLightColor.Init(hShader, "uDynLightColor"); muObjectColor.Init(hShader, "uObjectColor"); muObjectColor2.Init(hShader, "uObjectColor2"); muGlowBottomColor.Init(hShader, "uGlowBottomColor"); muGlowTopColor.Init(hShader, "uGlowTopColor"); muGlowBottomPlane.Init(hShader, "uGlowBottomPlane"); muGlowTopPlane.Init(hShader, "uGlowTopPlane"); muSplitBottomPlane.Init(hShader, "uSplitBottomPlane"); muSplitTopPlane.Init(hShader, "uSplitTopPlane"); muClipLine.Init(hShader, "uClipLine"); muFixedColormap.Init(hShader, "uFixedColormap"); muInterpolationFactor.Init(hShader, "uInterpolationFactor"); muClipHeight.Init(hShader, "uClipHeight"); muClipHeightDirection.Init(hShader, "uClipHeightDirection"); muAlphaThreshold.Init(hShader, "uAlphaThreshold"); muTimer.Init(hShader, "timer"); lights_index = glGetUniformLocation(hShader, "lights"); fakevb_index = glGetUniformLocation(hShader, "fakeVB"); projectionmatrix_index = glGetUniformLocation(hShader, "ProjectionMatrix"); viewmatrix_index = glGetUniformLocation(hShader, "ViewMatrix"); modelmatrix_index = glGetUniformLocation(hShader, "ModelMatrix"); texturematrix_index = glGetUniformLocation(hShader, "TextureMatrix"); vertexmatrix_index = glGetUniformLocation(hShader, "uQuadVertices"); texcoordmatrix_index = glGetUniformLocation(hShader, "uQuadTexCoords"); normalviewmatrix_index = glGetUniformLocation(hShader, "NormalViewMatrix"); normalmodelmatrix_index = glGetUniformLocation(hShader, "NormalModelMatrix"); quadmode_index = glGetUniformLocation(hShader, "uQuadMode"); if (!gl.legacyMode && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) { int tempindex = glGetUniformBlockIndex(hShader, "LightBufferUBO"); if (tempindex != -1) glUniformBlockBinding(hShader, tempindex, LIGHTBUF_BINDINGPOINT); } glUseProgram(hShader); if (quadmode_index > 0) glUniform1i(quadmode_index, 0); // set up other texture units (if needed by the shader) for (int i = 2; i<16; i++) { char stringbuf[20]; mysnprintf(stringbuf, 20, "texture%d", i); int tempindex = glGetUniformLocation(hShader, stringbuf); if (tempindex > 0) glUniform1i(tempindex, i - 1); } glUseProgram(0); return !!linked; }
/** * Create program and store shader handle in SdkEnv * Return: * 0 OK * -1 ERROR */ static int createProgram(SdkEnv *env, const char* vertexSource, const char* fragSource) { VALIDATE_NOT_NULL3(env, vertexSource, fragSource); // Make sure to reset them env->handle.program = 0; env->handle.vertShader = 0; env->handle.fragShader = 0; int program = 0; int vertShader = 0; int fragShader = 0; do { vertShader = loadShader(GL_VERTEX_SHADER, vertexSource); if (!vertShader) { LogE("Failed load vertex shader\n"); break; } fragShader = loadShader(GL_FRAGMENT_SHADER, fragSource); if (!fragShader) { LogE("Failed load fragment sahder\n"); break; } // Mark to delete, fre automaticlly when do not use any longer //glDeleteShader(vertShader); //glDeleteShader(fragShader); program = glCreateProgram(); if (!program) { LogE("Failed create program\n"); break; } glAttachShader(program, vertShader); glAttachShader(program, fragShader); glLinkProgram(program); GLint linkStatus = GL_FALSE; glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); GLint len; if (!linkStatus) { memset(sLogBuff, 0, LOG_BUFF_SIZE); glGetProgramInfoLog(program, LOG_BUFF_SIZE, &len, sLogBuff); if (len > 0) { Log("link error log:%s\n", sLogBuff); } else { LogE("Failed get link log\n"); } break; } glValidateProgram (program); GLint success; glGetProgramiv (program, GL_VALIDATE_STATUS, &success); if (!success) { memset (sLogBuff, 0, LOG_BUFF_SIZE); glGetProgramInfoLog (program, LOG_BUFF_SIZE, &len, sLogBuff); if (len > 0) { Log("program is invalidate:%s\n", sLogBuff); } else { LogE("Failed get program status\n"); } break; } env->handle.program = program; env->handle.vertShader = vertShader; env->handle.fragShader = fragShader; return 0; } while (0); if (program) { glDeleteProgram(program); } if (vertShader) { glDeleteShader(vertShader); } if (fragShader) { glDeleteShader(fragShader); } return -1; }
// The MAIN function, from here we start the application and run the game loop int main() { std::cout << "Starting GLFW context, OpenGL 3.3" << std::endl; // Init GLFW glfwInit(); // Set all the required options for GLFW glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Create a GLFWwindow object that we can use for GLFW's functions GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); glfwMakeContextCurrent(window); // Set the required callback functions glfwSetKeyCallback(window, key_callback); // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions glewExperimental = GL_TRUE; // Initialize GLEW to setup the OpenGL Function pointers glewInit(); // Define the viewport dimensions glViewport(0, 0, WIDTH, HEIGHT); std::string vertexshader = getFileContent("test_vs.glsl"); vertexShaderSource = (GLchar *) vertexshader.c_str(); std::string fragmentshader = getFileContent("test_fs.glsl"); fragmentShaderSource = (GLchar *) fragmentshader.c_str(); // Build and compile our shader program // Vertex shader GLint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); // Check for compile time errors GLint success; GLchar infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } // Fragment shader GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); // Check for compile time errors glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } // Link shaders GLint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); // Check for linking errors glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); // Set up vertex data (and buffer(s)) and attribute pointers //GLfloat vertices[] = { // // First triangle // 0.5f, 0.5f, // Top Right // 0.5f, -0.5f, // Bottom Right // -0.5f, 0.5f, // Top Left // // Second triangle // 0.5f, -0.5f, // Bottom Right // -0.5f, -0.5f, // Bottom Left // -0.5f, 0.5f // Top Left //}; GLfloat vertices[] = { 0.5f, 0.5f, 0.0f, // Top Right 0.5f, -0.5f, 0.0f, // Bottom Right -0.5f, -0.5f, 0.0f, // Bottom Left -0.5f, 0.5f, 0.0f, // Top Left -0.5f, -1.0f, 0.0f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f }; GLuint indices[] = { // Note that we start from 0! 0, 1, 3, // First Triangle 1, 2, 3, // Second Triangle 4, 5, 6 }; GLuint VBO, VAO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs), remember: do NOT unbind the EBO, keep it bound to this VAO // Uncommenting this call will result in wireframe polygons. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //other option //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Game loop while (!glfwWindowShouldClose(window)) { // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); // Render // Clear the colorbuffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // Draw our first triangle glUseProgram(shaderProgram); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 9); //glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_INT, 0); glBindVertexArray(0); // Swap the screen buffers glfwSwapBuffers(window); } // Properly de-allocate all resources once they've outlived their purpose glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate(); return 0; }
bool Shader::compile() { char buffer[1024]; // Vertex shader vertShaderHandle = glCreateShader(GL_VERTEX_SHADER); const GLchar* vs = vertSource.c_str(); const GLint vsLen = vertSource.length(); glShaderSource(vertShaderHandle, 1, &vs, &vsLen); glCompileShader(vertShaderHandle); // check vertex shader compile status if (!isShaderStatusGood(vertShaderHandle, GL_COMPILE_STATUS, buffer)) { anyErrors = true; return false; } // geometry shader geomShaderHandle = glCreateShader(GL_GEOMETRY_SHADER); const GLchar* gs = geomSource.c_str(); const GLint gsLen = geomSource.length(); glShaderSource(geomShaderHandle, 1, &gs, &gsLen); glCompileShader(geomShaderHandle); // check geometry shader compile status if (!isShaderStatusGood(geomShaderHandle, GL_COMPILE_STATUS, buffer)) { anyErrors = true; return false; } // fragment shader fragShaderHandle = glCreateShader(GL_FRAGMENT_SHADER); const GLchar* fs = fragSource.c_str(); const GLint fsLen = fragSource.length(); glShaderSource(fragShaderHandle, 1, &fs, &fsLen); glCompileShader(fragShaderHandle); // check vertex shader compile status if (!isShaderStatusGood(fragShaderHandle, GL_COMPILE_STATUS, buffer)) { anyErrors = true; return false; } // create and link full pipeline shaderProgHandle = glCreateProgram(); glAttachShader(shaderProgHandle, vertShaderHandle); if (typeFlags & GEOM_SHADER) { glAttachShader(shaderProgHandle, geomShaderHandle); } glAttachShader(shaderProgHandle, fragShaderHandle); glLinkProgram(shaderProgHandle); // remember that a call to glUseProgram will still need to be done // check program link status GLint status; glGetProgramiv(shaderProgHandle, GL_LINK_STATUS, &status); if (status == GL_FALSE) { GLint length; glGetProgramiv(shaderProgHandle, GL_INFO_LOG_LENGTH, &length); GLchar *info = new GLchar[length]; glGetProgramInfoLog(shaderProgHandle, length, NULL, info); std::cout << "glLinkProgram failed: \n" << info << std::endl; delete [] info; } //glDetachShader(shaderProgHandle, vertShaderHandle); //glDetachShader(shaderProgHandle, fragShaderHandle); //glDeleteShader(vertShaderHandle); //glDeleteShader(fragShaderHandle); compiled = true; return true; }
Shader::Shader(const GLchar *vertexSourcePath, const GLchar * fragmentSourcePath){ std::string vertexCode; std::string fragmentCode; try { std::ifstream vShaderFile(vertexSourcePath); std::ifstream fShaderFile(fragmentSourcePath); std::stringstream vShaderStream, fShaderStream; vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); vShaderFile.close(); fShaderFile.close(); vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); } catch (std::exception e) { std::cout << "ERROR: READ SHADER FILE FAILED." << std::endl; } const GLchar *vShaderCode = vertexCode.c_str(); const GLchar *fShaderCode = fragmentCode.c_str(); GLuint vertex, fragment; GLint success; GLchar infoLog[512]; //¶¥µã×ÅÉ«Æ÷ vertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex, 1, &vShaderCode, NULL); glCompileShader(vertex); glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertex, 512, NULL, infoLog); std::cout << "ERROR :SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment, 1, &fShaderCode, NULL); glCompileShader(fragment); glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragment, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } this->Program = glCreateProgram(); glAttachShader(this->Program, vertex); glAttachShader(this->Program, fragment); glLinkProgram(this->Program); glGetProgramiv(this->Program, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(this->Program, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } glDeleteShader(vertex); glDeleteShader(fragment); }
int main() { // Init GLFW glfwInit(); // Set all the required options for GLFW glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Assignment1", nullptr, nullptr); if (window == nullptr) { std::cout << "Failed to created GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSetKeyCallback(window, key_callback); glewExperimental = GL_TRUE; glewInit(); if (glewInit() != GLEW_OK) { std::cout << "Failed to initialized GLEW" << std::endl; return -1; } int width, height; glfwGetFramebufferSize(window, &width, &height); glViewport(0, 0, width, height); glEnable(GL_DEPTH_TEST); GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); GLint success; GLchar infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } // Fragment shader GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); // Check for compile time errors glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } // Link shaders GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); // Check for linking errors glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); GLfloat vertices[] = { 0.5f, 0.5f, 0.5f, //0 0.5f, -0.5f, 0.5f, //1 -0.5f, 0.5f, 0.5f, //2 -0.5f, -0.5f, 0.5f, //3 0.5f, 0.5f, -0.5f, //4 0.5f, -0.5f, -0.5f, //5 -0.5f, 0.5f, -0.5f,//6 -0.5f, -0.5f, -0.5f,//7 }; GLuint indices[] = { 0, 1, 2, //front 2, 1, 3, 0, 4, 5, //right 1, 0, 5, 4, 5, 7, //back 4, 7, 6, 2, 3, 6, //left 3, 6, 7, 0, 2, 4, //top 2, 4, 6, 1, 5, 7, //bottom 1, 7, 3, }; GLuint VBO, VAO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs), remember: do NOT unbind the EBO, keep it bound to this VAO projection = glm::perspective(45.0f, 1.0f, 0.1f, 20.0f); view = glm::lookAt(glm::vec3(0, 10, zoom), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); //model2 = glm::translate(model2, glm::vec3(3, 0, 4)); //model2 = glm::mat4(); // Uncommenting this call will result in wireframe polygons. //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // Game loop // Clear the colorbuffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); while (!glfwWindowShouldClose(window)) { // Render glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glBindVertexArray(VAO); // Draw our first triangle glUseProgram(shaderProgram); glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, &(projection)[0][0]); glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE, &(view)[0][0]); glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, &(model1)[0][0]); //blue glUniform4fv(glGetUniformLocation(shaderProgram, "myColor"), 1, &(glm::vec4(0, 0, 1, 1))[0]); //glDrawArrays(GL_TRIANGLES, 0, 6); if (!points) { glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); } if (points) { glDrawElements(GL_POINTS, 36, GL_UNSIGNED_INT,0); glEnable(GL_PROGRAM_POINT_SIZE); glPointSize(5.0); } glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, &(model2)[0][0]); //red glUniform4fv(glGetUniformLocation(shaderProgram, "myColor"), 1, &(glm::vec4(1, 0, 0, 1))[0]); if (!points) { glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); } if (points) { glDrawElements(GL_POINTS, 36, GL_UNSIGNED_INT, 0); glEnable(GL_PROGRAM_POINT_SIZE); glPointSize(5.0); } glBindVertexArray(0); if(lines){ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } if (fill) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } // Swap the screen buffers glfwSwapBuffers(window); // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); model1 = glm::rotate(model1, 0.001f, glm::vec3(0, 1, 0)); glm::mat3 conv; ang -= 0.001f; conv[0] = glm::vec3(cos(ang), 0 , sin(ang)); conv[1] = glm::vec3(0,1,0); conv[2] = glm::vec3(-sin(ang), 0, cos(ang)); glm::vec3 rotVec = glm::vec3(3, 0, 4); rotVec = conv * rotVec; //model2 = glm::translate(glm::scale(glm::mat4(), model2[0][0] * glm::vec3(1,1,1)), rotVec); model2 = glm::scale(glm::translate(glm::mat4() , rotVec), glm::vec3(redB, redB, redB)); //model2 = glm::translate(model2); view = glm::lookAt(glm::vec3(0, zoom, 10), glm::vec3(0, 0, 0), glm::vec3(0, up, 0)); //model2 = glm::scale(glm::translate(glm::mat4(), glm::vec3(-sin(ang), 0, cos(ang))),glm::vec3(redB,redB,redB)); //model2 = glm::rotate(model2, 0.001f, glm::vec3(0, 1, 0)); //model1 = glm::rotate(model1, 0.001f, glm::vec3(0, 1, 0)); //model2 = glm::translate(model2, rotVec); //model2 = glm::rotate(model2, 0.001f, glm::vec3(0, 1, 0)); //model2 = glm::translate(model2, glm::vec3(3, 0, 4)); } glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); glfwTerminate(); return 0; }
GLuint load_concat_shaders(const char *shader_directory, const char *vertex_header, int nvertex_files, const char *vertex_file_path[], const char *fragment_header, int nfragment_files, const char *fragment_file_path[]) { GLuint program_id = 0; int i; /* Create the shaders */ GLuint vertex_shader_id = glCreateShader(GL_VERTEX_SHADER); GLuint fragment_shader_id = glCreateShader(GL_FRAGMENT_SHADER); int nvertex_shader = 0; char *vertex_shader_filename[nvertex_files + 1]; GLchar *vertex_shader_code[nvertex_files + 1]; int nfragment_shader = 0; char *fragment_shader_filename[nfragment_files + 1]; GLchar *fragment_shader_code[nfragment_files + 1]; /* Build the Vertex Shader code */ if (vertex_header) { vertex_shader_filename[nvertex_shader] = strdup("string_vertex_header"); vertex_shader_code[nvertex_shader] = strdup(vertex_header); nvertex_shader++; } for (i = 0; i < nvertex_files; i++) { char *file_shader_code = read_file(shader_directory, vertex_file_path[i]); if (!file_shader_code) { printf("Can't open vertex shader '%s'\n", vertex_file_path[i]); goto cleanup; } vertex_shader_filename[nvertex_shader] = strdup(vertex_file_path[i]); vertex_shader_code[nvertex_shader] = file_shader_code; nvertex_shader++; } /* Read the Fragment Shader code from the file */ if (fragment_header) { fragment_shader_filename[nfragment_shader] = strdup("string_fragment_header"); fragment_shader_code[nfragment_shader] = strdup(fragment_header); nfragment_shader++; } for (i = 0; i < nfragment_files; i++) { char *file_shader_code = read_file(shader_directory, fragment_file_path[i]); if (!file_shader_code) { printf("Can't open fragment shader '%s'\n", fragment_file_path[i]); goto cleanup; } fragment_shader_filename[nfragment_shader] = strdup(fragment_file_path[i]); fragment_shader_code[nfragment_shader] = file_shader_code; nfragment_shader++; } GLint result = GL_FALSE; int info_log_length; /* Compile Vertex Shader */ glShaderSource(vertex_shader_id, nvertex_shader, (const GLchar **)&vertex_shader_code[0], NULL); glCompileShader(vertex_shader_id); /* Check Vertex Shader */ glGetShaderiv(vertex_shader_id, GL_COMPILE_STATUS, &result); if (result == GL_FALSE) { printf("Vertex shader compile error in files:\n"); for (i = 0; i < nvertex_shader; i++) { printf(" %d: \"%s\"\n", i, vertex_shader_filename[i]); } glGetShaderiv(vertex_shader_id, GL_INFO_LOG_LENGTH, &info_log_length); if (info_log_length > 0) { GLchar error_message[info_log_length + 1]; glGetShaderInfoLog(vertex_shader_id, info_log_length, NULL, &error_message[0]); printf("Error:\n%s\n", error_message); } else { printf("error: unknown\n"); } goto cleanup; } /* Compile Fragment Shader */ glShaderSource(fragment_shader_id, nfragment_shader, (const GLchar **)&fragment_shader_code[0], NULL); glCompileShader(fragment_shader_id); /* Check Fragment Shader */ glGetShaderiv(fragment_shader_id, GL_COMPILE_STATUS, &result); if (result == GL_FALSE) { printf("Fragment shader compile error in files:\n"); for (i = 0; i < nfragment_shader; i++) { printf(" %d: \"%s\"\n", i, fragment_shader_filename[i]); } glGetShaderiv(fragment_shader_id, GL_INFO_LOG_LENGTH, &info_log_length); if (info_log_length > 0) { char error_message[info_log_length + 1]; glGetShaderInfoLog(fragment_shader_id, info_log_length, NULL, &error_message[0]); printf("Error:\n%s\n", error_message); } else { printf("error: unknown\n"); } goto cleanup; } /* Link the program */ program_id = glCreateProgram(); glAttachShader(program_id, vertex_shader_id); glAttachShader(program_id, fragment_shader_id); glLinkProgram(program_id); /* Check the program */ glGetProgramiv(program_id, GL_LINK_STATUS, &result); if (result == GL_FALSE) { printf("Shader link error in files:\n"); for (i = 0; i < nvertex_shader; i++) { printf(" vert %d: \"%s\"\n", i, vertex_shader_filename[i]); } for (i = 0; i < nfragment_shader; i++) { printf(" frag %d: \"%s\"\n", i, fragment_shader_filename[i]); } glGetProgramiv(program_id, GL_INFO_LOG_LENGTH, &info_log_length); if (info_log_length > 0) { GLchar error_message[info_log_length + 1]; glGetProgramInfoLog(program_id, info_log_length, NULL, &error_message[0]); printf("Error:\n%s\n", error_message); glDeleteProgram(program_id); program_id = 0; } else { printf("error: unknown\n"); } goto cleanup; } cleanup: glDeleteShader(vertex_shader_id); glDeleteShader(fragment_shader_id); for (i = 0; i < nvertex_shader; i++) { free(vertex_shader_filename[i]); free(vertex_shader_code[i]); } for (i = 0; i < nfragment_shader; i++) { free(fragment_shader_filename[i]); free(fragment_shader_code[i]); } return program_id; }
LinkedShader::LinkedShader(Shader *vs, Shader *fs, u32 vertType, bool useHWTransform, LinkedShader *previous) : useHWTransform_(useHWTransform), program(0), dirtyUniforms(0) { program = glCreateProgram(); vs_ = vs; glAttachShader(program, vs->shader); glAttachShader(program, fs->shader); // Bind attribute locations to fixed locations so that they're // the same in all shaders. We use this later to minimize the calls to // glEnableVertexAttribArray and glDisableVertexAttribArray. glBindAttribLocation(program, ATTR_POSITION, "position"); glBindAttribLocation(program, ATTR_TEXCOORD, "texcoord"); glBindAttribLocation(program, ATTR_NORMAL, "normal"); glBindAttribLocation(program, ATTR_W1, "w1"); glBindAttribLocation(program, ATTR_W2, "w2"); glBindAttribLocation(program, ATTR_COLOR0, "color0"); glBindAttribLocation(program, ATTR_COLOR1, "color1"); #ifndef USING_GLES2 if (gl_extensions.ARB_blend_func_extended) { // Dual source alpha glBindFragDataLocationIndexed(program, 0, 0, "fragColor0"); glBindFragDataLocationIndexed(program, 0, 1, "fragColor1"); } else if (gl_extensions.VersionGEThan(3, 3, 0)) { glBindFragDataLocation(program, 0, "fragColor0"); } #endif glLinkProgram(program); GLint linkStatus = GL_FALSE; glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); if (linkStatus != GL_TRUE) { GLint bufLength = 0; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); if (bufLength) { char* buf = new char[bufLength]; glGetProgramInfoLog(program, bufLength, NULL, buf); #ifdef ANDROID ELOG("Could not link program:\n %s", buf); #endif ERROR_LOG(G3D, "Could not link program:\n %s", buf); ERROR_LOG(G3D, "VS:\n%s", vs->source().c_str()); ERROR_LOG(G3D, "FS:\n%s", fs->source().c_str()); Reporting::ReportMessage("Error in shader program link: info: %s / fs: %s / vs: %s", buf, fs->source().c_str(), vs->source().c_str()); #ifdef SHADERLOG OutputDebugStringUTF8(buf); OutputDebugStringUTF8(vs->source().c_str()); OutputDebugStringUTF8(fs->source().c_str()); #endif delete [] buf; // we're dead! } // Prevent a buffer overflow. numBones = 0; return; } INFO_LOG(G3D, "Linked shader: vs %i fs %i", (int)vs->shader, (int)fs->shader); u_tex = glGetUniformLocation(program, "tex"); u_proj = glGetUniformLocation(program, "u_proj"); u_proj_through = glGetUniformLocation(program, "u_proj_through"); u_texenv = glGetUniformLocation(program, "u_texenv"); u_fogcolor = glGetUniformLocation(program, "u_fogcolor"); u_fogcoef = glGetUniformLocation(program, "u_fogcoef"); u_alphacolorref = glGetUniformLocation(program, "u_alphacolorref"); u_alphacolormask = glGetUniformLocation(program, "u_alphacolormask"); u_stencilReplaceValue = glGetUniformLocation(program, "u_stencilReplaceValue"); u_fbotex = glGetUniformLocation(program, "fbotex"); u_blendFixA = glGetUniformLocation(program, "u_blendFixA"); u_blendFixB = glGetUniformLocation(program, "u_blendFixB"); u_fbotexSize = glGetUniformLocation(program, "u_fbotexSize"); // Transform u_view = glGetUniformLocation(program, "u_view"); u_world = glGetUniformLocation(program, "u_world"); u_texmtx = glGetUniformLocation(program, "u_texmtx"); if (vertTypeGetWeightMask(vertType) != GE_VTYPE_WEIGHT_NONE) numBones = TranslateNumBones(vertTypeGetNumBoneWeights(vertType)); else numBones = 0; #ifdef USE_BONE_ARRAY u_bone = glGetUniformLocation(program, "u_bone"); #else for (int i = 0; i < 8; i++) { char name[10]; sprintf(name, "u_bone%i", i); u_bone[i] = glGetUniformLocation(program, name); } #endif // Lighting, texturing u_ambient = glGetUniformLocation(program, "u_ambient"); u_matambientalpha = glGetUniformLocation(program, "u_matambientalpha"); u_matdiffuse = glGetUniformLocation(program, "u_matdiffuse"); u_matspecular = glGetUniformLocation(program, "u_matspecular"); u_matemissive = glGetUniformLocation(program, "u_matemissive"); u_uvscaleoffset = glGetUniformLocation(program, "u_uvscaleoffset"); u_texclamp = glGetUniformLocation(program, "u_texclamp"); u_texclampoff = glGetUniformLocation(program, "u_texclampoff"); for (int i = 0; i < 4; i++) { char temp[64]; sprintf(temp, "u_lightpos%i", i); u_lightpos[i] = glGetUniformLocation(program, temp); sprintf(temp, "u_lightdir%i", i); u_lightdir[i] = glGetUniformLocation(program, temp); sprintf(temp, "u_lightatt%i", i); u_lightatt[i] = glGetUniformLocation(program, temp); sprintf(temp, "u_lightangle%i", i); u_lightangle[i] = glGetUniformLocation(program, temp); sprintf(temp, "u_lightspotCoef%i", i); u_lightspotCoef[i] = glGetUniformLocation(program, temp); sprintf(temp, "u_lightambient%i", i); u_lightambient[i] = glGetUniformLocation(program, temp); sprintf(temp, "u_lightdiffuse%i", i); u_lightdiffuse[i] = glGetUniformLocation(program, temp); sprintf(temp, "u_lightspecular%i", i); u_lightspecular[i] = glGetUniformLocation(program, temp); } attrMask = 0; if (-1 != glGetAttribLocation(program, "position")) attrMask |= 1 << ATTR_POSITION; if (-1 != glGetAttribLocation(program, "texcoord")) attrMask |= 1 << ATTR_TEXCOORD; if (-1 != glGetAttribLocation(program, "normal")) attrMask |= 1 << ATTR_NORMAL; if (-1 != glGetAttribLocation(program, "w1")) attrMask |= 1 << ATTR_W1; if (-1 != glGetAttribLocation(program, "w2")) attrMask |= 1 << ATTR_W2; if (-1 != glGetAttribLocation(program, "color0")) attrMask |= 1 << ATTR_COLOR0; if (-1 != glGetAttribLocation(program, "color1")) attrMask |= 1 << ATTR_COLOR1; availableUniforms = 0; if (u_proj != -1) availableUniforms |= DIRTY_PROJMATRIX; if (u_proj_through != -1) availableUniforms |= DIRTY_PROJTHROUGHMATRIX; if (u_texenv != -1) availableUniforms |= DIRTY_TEXENV; if (u_alphacolorref != -1) availableUniforms |= DIRTY_ALPHACOLORREF; if (u_alphacolormask != -1) availableUniforms |= DIRTY_ALPHACOLORMASK; if (u_fogcolor != -1) availableUniforms |= DIRTY_FOGCOLOR; if (u_fogcoef != -1) availableUniforms |= DIRTY_FOGCOEF; if (u_texenv != -1) availableUniforms |= DIRTY_TEXENV; if (u_uvscaleoffset != -1) availableUniforms |= DIRTY_UVSCALEOFFSET; if (u_texclamp != -1) availableUniforms |= DIRTY_TEXCLAMP; if (u_world != -1) availableUniforms |= DIRTY_WORLDMATRIX; if (u_view != -1) availableUniforms |= DIRTY_VIEWMATRIX; if (u_texmtx != -1) availableUniforms |= DIRTY_TEXMATRIX; if (u_stencilReplaceValue != -1) availableUniforms |= DIRTY_STENCILREPLACEVALUE; if (u_blendFixA != -1 || u_blendFixB != -1 || u_fbotexSize != -1) availableUniforms |= DIRTY_SHADERBLEND; // Looping up to numBones lets us avoid checking u_bone[i] for (int i = 0; i < numBones; i++) { if (u_bone[i] != -1) availableUniforms |= DIRTY_BONEMATRIX0 << i; } if (u_ambient != -1) availableUniforms |= DIRTY_AMBIENT; if (u_matambientalpha != -1) availableUniforms |= DIRTY_MATAMBIENTALPHA; if (u_matdiffuse != -1) availableUniforms |= DIRTY_MATDIFFUSE; if (u_matemissive != -1) availableUniforms |= DIRTY_MATEMISSIVE; if (u_matspecular != -1) availableUniforms |= DIRTY_MATSPECULAR; for (int i = 0; i < 4; i++) { if (u_lightdir[i] != -1 || u_lightspecular[i] != -1 || u_lightpos[i] != -1) availableUniforms |= DIRTY_LIGHT0 << i; } glUseProgram(program); // Default uniform values glUniform1i(u_tex, 0); glUniform1i(u_fbotex, 1); // The rest, use the "dirty" mechanism. dirtyUniforms = DIRTY_ALL; use(vertType, previous); }
// Reads, compiles, links and returns a shader from the given paths GLuint loadShader(const std::string &vertexPath, const std::string &fragmentPath) { cout << "Loading shader program with shaders:" << endl; cout << " Vertex: " << std::filesystem::canonical(vertexPath) << endl; cout << " Fragment: " << std::filesystem::canonical(fragmentPath) << endl; // Read our shaders into the appropriate buffers std::ifstream vs_file(vertexPath); std::string vertexSource{ std::istreambuf_iterator<char>(vs_file), std::istreambuf_iterator<char>() }; std::ifstream fs_file(fragmentPath); std::string fragmentSource{ std::istreambuf_iterator<char>(fs_file), std::istreambuf_iterator<char>() }; #if 0 DIR* vertFile = opendir(vertexPath.c_str()); if (vertFile == nullptr) { glutil::fatal_error("Vertex file not found."); } DIR* fragFile = opendir(fragmentPath.c_str()); if (fragFile == nullptr) { glutil::fatal_error("Fragment file not found."); } #endif // 0 #if 1 const char *vs = vertexSource.c_str(); const char *fs = fragmentSource.c_str(); cout << "Vertex shader:" << endl << vs << endl << endl << "Fragment shader:" << endl << fs << endl; #endif // 0 // Create an empty vertex shader handle GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); // Send the vertex shader source code to GL // Note that std::string's .c_str is NULL character terminated. const GLchar *source = (const GLchar *)vertexSource.c_str(); glShaderSource(vertexShader, 1, &source, NULL); // Compile the vertex shader glCompileShader(vertexShader); GLint isCompiled = 0; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled); if (isCompiled == GL_FALSE) { GLint maxLength = 0; glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength); // The maxLength includes the NULL character std::vector<GLchar> infoLog(maxLength); glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &infoLog[0]); // We don't need the shader anymore. glDeleteShader(vertexShader); // Time to use the infoLog. for (unsigned int i = 0; i < infoLog.size(); i++) { std::cerr << infoLog[i]; } std::cerr << endl; // In this simple program, we'll just leave return -1; } // Create an empty fragment shader handle GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Send the fragment shader source code to GL // Note that std::string's .c_str is NULL character terminated. source = (const GLchar *)fragmentSource.c_str(); glShaderSource(fragmentShader, 1, &source, NULL); // Compile the fragment shader glCompileShader(fragmentShader); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled); if (isCompiled == GL_FALSE) { GLint maxLength = 0; glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength); // The maxLength includes the NULL character std::vector<GLchar> infoLog(maxLength); glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &infoLog[0]); // We don't need the shader anymore. glDeleteShader(fragmentShader); // Either of them. Don't leak shaders. glDeleteShader(vertexShader); // Time to use the infoLog. for (unsigned int i = 0; i < infoLog.size(); i++) { std::cerr << infoLog[i]; } std::cerr << endl; // In this simple program, we'll just leave return -1; } // Vertex and fragment shaders are successfully compiled. // Now time to link them together into a program. // Get a program object. GLuint program = glCreateProgram(); // Attach our shaders to our program glAttachShader(program, vertexShader); glAttachShader(program, fragmentShader); // Link our program glLinkProgram(program); // Note the different functions here: glGetProgram* instead of glGetShader*. GLint isLinked = 0; glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked); if (isLinked == GL_FALSE) { GLint maxLength = 0; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); // The maxLength includes the NULL character std::vector<GLchar> infoLog(maxLength); glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]); // We don't need the program anymore. glDeleteProgram(program); // Don't leak shaders either. glDeleteShader(vertexShader); glDeleteShader(fragmentShader); // Time to use the infoLog. for (unsigned int i = 0; i < infoLog.size(); i++) { std::cerr << infoLog[i]; } std::cerr << endl; // In this simple program, we'll just leave return -1; } GLint maxLength = 0; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); if (maxLength > 0) { // The maxLength includes the NULL character std::vector<GLchar> infoLog(maxLength); glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]); for (unsigned int i = 0; i < infoLog.size(); i++) { std::cerr << infoLog[i]; } std::cerr << endl; } // Detach shaders after a successful link. glDetachShader(program, vertexShader); glDetachShader(program, fragmentShader); cout << "Shader loaded." << endl; return program; }
// The MAIN function, from here we start the application and run the game loop int main4() { // Init GLFW glfwInit(); // Set all the required options for GLFW glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Create a GLFWwindow object that we can use for GLFW's functions GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); glfwMakeContextCurrent(window); // Set the required callback functions glfwSetKeyCallback(window, key_callback); // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions glewExperimental = GL_TRUE; // Initialize GLEW to setup the OpenGL Function pointers glewInit(); // Define the viewport dimensions glViewport(0, 0, WIDTH, HEIGHT); // Build and compile our shader program // Vertex shader GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); // Check for compile time errors GLint success; GLchar infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } // Fragment shader GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); // Check for compile time errors glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } // Link shaders GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); // Check for linking errors glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); // Set up vertex data (and buffer(s)) and attribute pointers GLfloat vertices[] = { // Positions 0.5f, -0.5f, 0.0f, // Bottom Right -0.5f, -0.5f, 0.0f, // Bottom Left 0.0f, 0.5f, 0.0f // Top }; GLuint VBO, VAO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glBindVertexArray(0); // Unbind VAO // Game loop while (!glfwWindowShouldClose(window)) { // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); // Render // Clear the colorbuffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // Be sure to activate the shader glUseProgram(shaderProgram); // Update the uniform color GLfloat timeValue = glfwGetTime(); GLfloat greenValue = (sin(timeValue) / 2) + 0.5; GLint vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor"); glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f); // Draw the triangle glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 3); glBindVertexArray(0); // Swap the screen buffers glfwSwapBuffers(window); } // Properly de-allocate all resources once they've outlived their purpose glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate(); return 0; }
// Create a GLSL program object from vertex and fragment shader files GLuint Painter::init_shader(const char* vShaderFile, const char* fShaderFile, const char* outputAttributeName, const char* gShaderFile) { struct Shader { const char* filename; GLenum type; GLchar* source; }; std::vector<Shader> shaders = { { vShaderFile, GL_VERTEX_SHADER, NULL }, { fShaderFile, GL_FRAGMENT_SHADER, NULL } }; if(gShaderFile) { shaders.push_back({ gShaderFile, GL_GEOMETRY_SHADER, NULL }); } GLuint program = glCreateProgram(); for ( int i = 0; i < shaders.size(); ++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 output */ glBindFragDataLocation(program, 0, outputAttributeName); /* 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; }
////////////////////////////////////////////////////////////////////////// // loads only a vertex and pixel shader from text files unsigned int AIE::LoadShader(unsigned int a_uiInputAttributeCount, const char** a_aszInputAttributes, unsigned int a_uiOutputAttributeCount, const char** a_aszOutputAttributes, const char* a_szVertexShader, const char* a_szPixelShader, const char* a_szGeometryShader /* = nullptr */, const char* a_szTessellationControlShader /* = nullptr */, const char* a_szTessellationEvaluationShader /* = nullptr */) { GLint iSuccess; GLchar acLog[256]; // load files into char buffers char* vsSource = FileToBuffer(a_szVertexShader); char* fsSource = FileToBuffer(a_szPixelShader); char* gsSource = a_szGeometryShader == nullptr ? nullptr : FileToBuffer(a_szGeometryShader); char* tcsSource = a_szTessellationControlShader == nullptr ? nullptr : FileToBuffer(a_szTessellationControlShader); char* tesSource = a_szTessellationEvaluationShader == nullptr ? nullptr : FileToBuffer(a_szTessellationEvaluationShader); // must have vertex and pixel if (vsSource == nullptr || fsSource == nullptr) { return 0; } // create 2 shader handles GLuint vsHandle = glCreateShader(GL_VERTEX_SHADER); GLuint fsHandle = glCreateShader(GL_FRAGMENT_SHADER); GLuint gsHandle = 0; GLuint tcsHandle = 0; GLuint tesHandle = 0; // compile vertex shader and log errors glShaderSource(vsHandle, 1, (const char**)&vsSource, 0); glCompileShader(vsHandle); glGetShaderiv(vsHandle, GL_COMPILE_STATUS, &iSuccess); glGetShaderInfoLog(vsHandle, sizeof(acLog), 0, acLog); if (iSuccess == GL_FALSE) { printf("Error: Failed to compile vertex shader!\n"); printf(acLog); printf("\n"); return 0; } // compile pixel shader and log errors glShaderSource(fsHandle, 1, (const char**)&fsSource, 0); glCompileShader(fsHandle); glGetShaderiv(fsHandle, GL_COMPILE_STATUS, &iSuccess); glGetShaderInfoLog(fsHandle, sizeof(acLog), 0, acLog); if (iSuccess == GL_FALSE) { printf("Error: Failed to compile pixel shader!\n"); printf(acLog); printf("\n"); return 0; } if (gsSource != nullptr) { gsHandle = glCreateShader(GL_GEOMETRY_SHADER); // compile geometry shader and log errors glShaderSource(gsHandle, 1, (const char**)&gsSource, 0); glCompileShader(gsHandle); glGetShaderiv(gsHandle, GL_COMPILE_STATUS, &iSuccess); glGetShaderInfoLog(gsHandle, sizeof(acLog), 0, acLog); if (iSuccess == GL_FALSE) { printf("Error: Failed to compile geometry shader!\n"); printf(acLog); printf("\n"); return 0; } } if (tesSource != nullptr && tcsSource != nullptr) { tesHandle = glCreateShader(GL_TESS_EVALUATION_SHADER); tcsHandle = glCreateShader(GL_TESS_CONTROL_SHADER); // compile tessellation control shader and log errors glShaderSource(tcsHandle, 1, (const char**)&tcsSource, 0); glCompileShader(tcsHandle); glGetShaderiv(tcsHandle, GL_COMPILE_STATUS, &iSuccess); glGetShaderInfoLog(tcsHandle, sizeof(acLog), 0, acLog); if (iSuccess == GL_FALSE) { printf("Error: Failed to compile tessellation control shader!\n"); printf(acLog); printf("\n"); return 0; } // compile tessellation evaluation shader and log errors glShaderSource(tesHandle, 1, (const char**)&tesSource, 0); glCompileShader(tesHandle); glGetShaderiv(tesHandle, GL_COMPILE_STATUS, &iSuccess); glGetShaderInfoLog(tesHandle, sizeof(acLog), 0, acLog); if (iSuccess == GL_FALSE) { printf("Error: Failed to compile tessellation evaluation shader!\n"); printf(acLog); printf("\n"); return 0; } } // create a shader program and attach the shaders to it GLuint uiProgramHandle = glCreateProgram(); glAttachShader(uiProgramHandle, vsHandle); glAttachShader(uiProgramHandle, fsHandle); if (gsHandle != 0) glAttachShader(uiProgramHandle, gsHandle); if (tcsHandle != 0) glAttachShader(uiProgramHandle, tcsHandle); if (tesHandle != 0) glAttachShader(uiProgramHandle, tesHandle); // specify vertex input attributes for ( unsigned int i = 0 ; i < a_uiInputAttributeCount ; ++i ) glBindAttribLocation(uiProgramHandle, i, a_aszInputAttributes[i]); // specify pixel shader outputs for ( unsigned int i = 0 ; i < a_uiOutputAttributeCount ; ++i ) glBindFragDataLocation(uiProgramHandle, i, a_aszOutputAttributes[i]); // link the program together and log errors glLinkProgram(uiProgramHandle); glGetProgramiv(uiProgramHandle, GL_LINK_STATUS, &iSuccess); glGetProgramInfoLog(uiProgramHandle, sizeof(acLog), 0, acLog); if (iSuccess == GL_FALSE) { printf("Error: Failed to link shader program!\n"); printf(acLog); printf("\n"); return 0; } glUseProgram(uiProgramHandle); delete vsSource; delete fsSource; if (gsSource != nullptr) delete gsSource; if (tcsSource != nullptr) delete tcsSource; if (tesSource != nullptr) delete tesSource; return uiProgramHandle; }
// // Initialise les shader & program object // bool EsgiShader::Create() { // Cree le program object m_ProgramObject = glCreateProgram(); if (m_ProgramObject == 0) { return false; } if (m_VertexShader) { glAttachShader(m_ProgramObject, m_VertexShader); } if (m_FragmentShader) { glAttachShader(m_ProgramObject, m_FragmentShader); } #ifdef GL_GEOMETRY_SHADER if (m_GeometryShader) { glAttachShader(m_ProgramObject, m_GeometryShader); } #endif // callback permettant d'effectuer des operations avant le linkage if (m_PreLinkCallback) { m_PreLinkCallback(); } // Liage des shaders dans le programme glLinkProgram(m_ProgramObject); GLint linked = 0; GLint infoLen = 0; // verification du statut du linkage glGetProgramiv(m_ProgramObject, GL_LINK_STATUS, &linked); if (!linked) { glGetProgramiv(m_ProgramObject, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { char* infoLog = (char *)malloc(sizeof(char) * infoLen); glGetProgramInfoLog(m_ProgramObject, infoLen, NULL, infoLog); GL_PRINT("Erreur de lien du programme:\n%s\n", infoLog); free(infoLog); } glDeleteProgram(m_ProgramObject); return false; } #if defined(_DEBUG) || defined(DEBUG) // ne pas utiliser glValidateProgram() au runtime. // techniquement il faudrait appeler glValidateProgram() dans le contexte // d'utilisation du shader et non a sa creation pour verifier que toutes les // conditions d'execution sont bien remplies glValidateProgram(m_ProgramObject); glGetProgramiv(m_ProgramObject, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { char* infoLog = (char *)malloc(sizeof(char) * infoLen); glGetProgramInfoLog(m_ProgramObject, infoLen, NULL, infoLog); GL_PRINT("Resultat de la validation du programme:\n%s\n", infoLog); free(infoLog); } #endif return true; }
void InitializeOpenGL(int i, int p, GLuint pro) { #ifdef __APPLE__ printf("Testing the init \n"); #endif //LOGD("Initialization Started"); GLuint vertexShader; GLuint fragmentShader; #ifdef __APPLE__ printf("Test %d\n", GL_VERTEX_SHADER); #endif vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr); fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr); if(pro == 0){ programObject = glCreateProgram(); if(programObject == 0){ #ifdef __APPLE__ printf("Invalid program returned \n"); #else LOGD("Invalid program returned"); #endif } } else{ programObject = pro; } glAttachShader(programObject, vertexShader); glAttachShader(programObject, fragmentShader); glEnable(GL_DEPTH_TEST); glBindAttribLocation(programObject, 0, "vPosition"); glLinkProgram(programObject); glUseProgram(programObject); textCoordLoc = glGetAttribLocation (programObject, "texPosition" ); sampler = glGetUniformLocation(programObject, "s_texture" ); GLint linked; glGetProgramiv(programObject, GL_LINK_STATUS, &linked); if (!linked) { // printf("Error linking program:\n"); GLint infoLen = 0; glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { #ifdef __APPLE__ char* infoLog = (char*)malloc(sizeof(char)*infoLen); glGetProgramInfoLog(programObject, infoLen, NULL, infoLog); printf("%s\n",infoLog); free(infoLog); #endif } glDeleteProgram(programObject); } else{ // printf("No linker error \n"); } glClearColor(1.0f, 1.0f, 0.0f, 1.0f); #ifdef __APPLE__ printf("Initialization Complete \n"); #else LOGD("Initialization Complete"); #endif }
bool COGLES2SLMaterialRenderer::linkProgram() { glLinkProgram( Program ); int status = 0; glGetProgramiv( Program, GL_LINK_STATUS, &status ); if ( !status ) { os::Printer::log( "GLSL shader program failed to link", ELL_ERROR ); // check error message and log it int maxLength = 0; GLsizei length; glGetProgramiv( Program, GL_INFO_LOG_LENGTH, &maxLength ); char *pInfoLog = new char[maxLength]; glGetProgramInfoLog( Program, maxLength, &length, pInfoLog ); os::Printer::log(pInfoLog, ELL_ERROR); delete [] pInfoLog; return false; } // get uniforms information int num = 0; glGetProgramiv( Program, GL_ACTIVE_UNIFORMS, &num ); int maxlen = 0; glGetProgramiv( Program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxlen ); if ( maxlen == 0 && num != 0 ) { os::Printer::log( "GLSL: failed to retrieve uniform information", ELL_ERROR ); return false; } c8 *buf = new c8[maxlen]; UniformInfo.clear(); UniformInfo.reallocate( num ); core::array<core::stringc> names( num ); core::array<SUniformInfo> uni( num ); for ( int i = 0; i < num; ++i ) { memset( buf, 0, maxlen ); GLint size; SUniformInfo ui; glGetActiveUniform( Program, i, maxlen, 0, &size, &ui.type, reinterpret_cast<char*>( buf ) ); ui.location = glGetUniformLocation( Program, buf ); uni.push_back( ui ); names.push_back( buf ); } delete [] buf; for ( int i = 0; i < UniformCount; ++i ) { int j; for ( j = 0; j < num; ++j ) { if ( names[j] == UniformStringTable[i] ) break; } if ( j < num ) { UniformInfo.push_back( uni[j] ); } else { wchar_t buf[512]; swprintf( buf, 512, L"Unable to find uniform : %S", UniformStringTable[i] ); os::Printer::log( buf, ELL_WARNING ); SUniformInfo blank; blank.location = -1; blank.type = GL_INVALID_ENUM; UniformInfo.push_back( blank ); } } return true; }
int main () { GLFWwindow* window = NULL; const GLubyte* renderer; const GLubyte* version; GLuint shader_programme; GLuint vao; // // Start OpenGL using helper libraries // -------------------------------------------------------------------------- if (!glfwInit ()) { fprintf (stderr, "ERROR: could not start GLFW3\n"); return 1; } // change to 3.2 if on Apple OS X glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint (GLFW_SAMPLES, msaa); window = glfwCreateWindow (gl_width, gl_height, "Textured Mesh", NULL, NULL); if (!window) { fprintf (stderr, "ERROR: opening OS window\n"); return 1; } glfwMakeContextCurrent (window); glewExperimental = GL_TRUE; glewInit (); /* get version info */ renderer = glGetString (GL_RENDERER); /* get renderer string */ version = glGetString (GL_VERSION); /* version as a string */ printf ("Renderer: %s\n", renderer); printf ("OpenGL version supported %s\n", version); int point_count = 0; // // Set up vertex buffers and vertex array object // -------------------------------------------------------------------------- { GLfloat* vp = NULL; // array of vertex points GLfloat* vn = NULL; // array of vertex normals (we haven't used these yet) GLfloat* vt = NULL; // array of texture coordinates (or these) //assert (load_obj_file ("cube.obj", vp, vt, vn, point_count)); assert (load_obj_file ("monkey.obj", vp, vt, vn, point_count)); GLuint points_vbo, texcoord_vbo, normal_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 3 * point_count, vp, GL_STATIC_DRAW); glGenBuffers (1, &texcoord_vbo); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 2 * point_count, vt, GL_STATIC_DRAW); glGenBuffers (1, &normal_vbo); glBindBuffer (GL_ARRAY_BUFFER, normal_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 3 * point_count, vn, GL_STATIC_DRAW); glGenVertexArrays (1, &vao); glBindVertexArray (vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (1); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (2); glBindBuffer (GL_ARRAY_BUFFER, normal_vbo); glVertexAttribPointer (2, 3, GL_FLOAT, GL_FALSE, 0, NULL); free (vp); free (vn); free (vt); } // // Load shaders from files // -------------------------------------------------------------------------- { char* vertex_shader_str; char* fragment_shader_str; // allocate some memory to store shader strings vertex_shader_str = (char*)malloc (81920); fragment_shader_str = (char*)malloc (81920); // load shader strings from text files assert (parse_file_into_str ("teapot.vert", vertex_shader_str, 81920)); assert (parse_file_into_str ("teapot.frag", fragment_shader_str, 81920)); GLuint vs, fs; vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vertex_shader_str, NULL); glShaderSource (fs, 1, (const char**)&fragment_shader_str, NULL); // free memory free (vertex_shader_str); free (fragment_shader_str); int params = -1; glCompileShader (vs); glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (teapot.vert) did not compile\n", vs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (vs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } glCompileShader (fs); glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (teapot.frag) did not compile\n", fs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (fs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } shader_programme = glCreateProgram (); glAttachShader (shader_programme, fs); glAttachShader (shader_programme, vs); glBindAttribLocation (shader_programme, 0, "vp"); glBindAttribLocation (shader_programme, 1, "vt"); glBindAttribLocation (shader_programme, 2, "vn"); glLinkProgram (shader_programme); glGetProgramiv (shader_programme, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: could not link shader programme GL index %u\n", shader_programme); int max_length = 2048; int actual_length = 0; char log[2048]; glGetProgramInfoLog (shader_programme, max_length, &actual_length, log); printf ("program info log for GL index %u\n%s\n", shader_programme, log); } /* TODO NOTE: you should check for errors and print logs after compiling and also linking shaders */ } // // Create some matrices // -------------------------------------------------------------------------- mat4 M, V, P; M = identity_mat4 ();//scale (identity_mat4 (), vec3 (0.05, 0.05, 0.05)); vec3 cam_pos (0.0, 5.0, 5.0); vec3 targ_pos (0.0, 0.0, 0.0); vec3 up = normalise (vec3 (0.0, 1.0, -1.0)); V = look_at (cam_pos, targ_pos, up); P = perspective (67.0f, (float)gl_width / (float)gl_height, 0.1, 10.0); int M_loc = glGetUniformLocation (shader_programme, "M"); int V_loc = glGetUniformLocation (shader_programme, "V"); int P_loc = glGetUniformLocation (shader_programme, "P"); int ol_loc = glGetUniformLocation (shader_programme, "ol_mode"); int sm_loc = glGetUniformLocation (shader_programme, "sm_shaded"); // send matrix values to shader immediately glUseProgram (shader_programme); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glUniformMatrix4fv (V_loc, 1, GL_FALSE, V.m); glUniformMatrix4fv (P_loc, 1, GL_FALSE, P.m); glUniform1f (ol_loc, 0.0f); glUniform1f (sm_loc, 0.0f); // // Start rendering // -------------------------------------------------------------------------- // tell GL to only draw onto a pixel if the fragment is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glDepthFunc (GL_LESS); // depth-testing is to use a "less than" function glEnable (GL_CULL_FACE); // enable culling of faces glCullFace (GL_BACK); glFrontFace (GL_CCW); glClearColor (0.04, 0.04, 0.75, 1.0); bool multi_pass = true; GLuint fb, c_tex, d_tex;; { // fb glGenFramebuffers (1, &fb); glBindFramebuffer (GL_FRAMEBUFFER, fb); glGenTextures (1, &c_tex); glGenTextures (1, &d_tex); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, c_tex); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, gl_width, gl_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, c_tex, 0); glBindTexture (GL_TEXTURE_2D, d_tex); glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, gl_width, gl_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, d_tex, 0); glBindFramebuffer (GL_FRAMEBUFFER, 0); } GLuint quad_vao; { float quad_pts[] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0}; GLuint quad_vbo; glGenBuffers (1, &quad_vbo); glGenVertexArrays (1, &quad_vao); glBindVertexArray (quad_vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, quad_vbo); glBufferData (GL_ARRAY_BUFFER, 8 * sizeof (float), quad_pts, GL_STATIC_DRAW); glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, 0, NULL); } GLuint post_sp; { char* vertex_shader_str; char* fragment_shader_str; // allocate some memory to store shader strings vertex_shader_str = (char*)malloc (81920); fragment_shader_str = (char*)malloc (81920); // load shader strings from text files assert (parse_file_into_str ("post.vert", vertex_shader_str, 81920)); assert (parse_file_into_str ("post.frag", fragment_shader_str, 81920)); GLuint vs, fs; vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vertex_shader_str, NULL); glShaderSource (fs, 1, (const char**)&fragment_shader_str, NULL); // free memory free (vertex_shader_str); free (fragment_shader_str); int params = -1; glCompileShader (vs); glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (post.vert) did not compile\n", vs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (vs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } glCompileShader (fs); glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (post.frag) did not compile\n", fs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (fs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } post_sp = glCreateProgram (); glAttachShader (post_sp, fs); glAttachShader (post_sp, vs); glBindAttribLocation (post_sp, 0, "vp"); glLinkProgram (post_sp); glGetProgramiv (post_sp, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: could not link shader programme GL index %u\n", post_sp); int max_length = 2048; int actual_length = 0; char log[2048]; glGetProgramInfoLog (post_sp, max_length, &actual_length, log); printf ("program info log for GL index %u\n%s\n", post_sp, log); } } double a = 0.0f; double prev = glfwGetTime (); while (!glfwWindowShouldClose (window)) { if (multi_pass) { glBindFramebuffer (GL_FRAMEBUFFER, fb); } glViewport (0, 0, gl_width, gl_height); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, 0); double curr = glfwGetTime (); double elapsed = curr - prev; prev = curr; glUseProgram (shader_programme); glBindVertexArray (vao); a += elapsed * 50.0f; //float ang = (float)sin (a); M = rotate_y_deg (identity_mat4 (), a); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glUniform1f (sm_loc, 1.0f); // smooth shaded or not (exception is flat-shaded, they might not be great // if non-cube anyway due to scaling) if (!multi_pass) { glFrontFace (GL_CW); glUniform1f (ol_loc, 1.0f); glDrawArrays (GL_TRIANGLES, 0, point_count); } glFrontFace (GL_CCW); glUniform1f (ol_loc, 0.0f); glDrawArrays (GL_TRIANGLES, 0, point_count); /* this just updates window events and keyboard input events (not used yet) */ if (multi_pass) { glFlush (); glFinish (); glBindFramebuffer (GL_FRAMEBUFFER, 0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, gl_width, gl_height); glUseProgram (post_sp); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, d_tex); glBindVertexArray (quad_vao); glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); } glfwPollEvents (); glfwSwapBuffers (window); } return 0; }
shader_loader::shader_loader(const char* vs_file_name, const char* fs_file_name){ FILE* vs_file = fopen(vs_file_name, "r"); FILE* fs_file = fopen(fs_file_name, "r"); GLuint vs_id = glCreateShader(GL_VERTEX_SHADER); GLuint fs_id = glCreateShader(GL_FRAGMENT_SHADER); std::string vs_code; std::string fs_code; std::ifstream vs_stream{ vs_file }; std::ifstream fs_stream{ fs_file }; if (vs_stream.is_open()){ std::string line = ""; while (std::getline(vs_stream, line)){ vs_code += "\n" + line; } vs_stream.close(); fclose(vs_file); } else{ printf("error - unable to open fstream to vs_file : %s\n", vs_file_name); exit(EXIT_SUCCESS); } if (fs_stream.is_open()){ std::string line = ""; while (std::getline(fs_stream, line)){ fs_code += "\n" + line; } fs_stream.close(); fclose(fs_file); } else{ printf("error - unable to open fstream to fs_file : %s\n", fs_file_name); exit(EXIT_SUCCESS); } GLint result = GL_FALSE; int info_log_len; printf("compiling vertex shader : %s\n", vs_file_name); const char* vs_ptr = vs_code.c_str(); glShaderSource(vs_id, 1, &vs_ptr, NULL); glCompileShader(vs_id); glGetShaderiv(vs_id, GL_COMPILE_STATUS, &result); glGetShaderiv(vs_id, GL_INFO_LOG_LENGTH, &info_log_len); char* vs_err = new char[info_log_len]; glGetShaderInfoLog(vs_id, info_log_len, NULL, vs_err); printf("%s\n", vs_err); printf("compiling fragment shader : %s\n", fs_file_name); const char* fs_ptr = fs_code.c_str(); glShaderSource(fs_id, 1, &fs_ptr, NULL); glCompileShader(fs_id); glGetShaderiv(fs_id, GL_COMPILE_STATUS, &result); glGetShaderiv(fs_id, GL_INFO_LOG_LENGTH, &info_log_len); char* fs_err = new char[info_log_len]; glGetShaderInfoLog(fs_id, info_log_len, NULL, fs_err); printf("%s\n", fs_err); printf("linking program\n"); program_id_ = glCreateProgram(); glAttachShader(program_id_, vs_id); glAttachShader(program_id_, fs_id); glLinkProgram(program_id_); glGetProgramiv(program_id_, GL_LINK_STATUS, &result); glGetProgramiv(program_id_, GL_INFO_LOG_LENGTH, &info_log_len); char* prg_err = new char[info_log_len]; glGetProgramInfoLog(program_id_, info_log_len, NULL, prg_err); printf("%s\n", prg_err); glDeleteShader(vs_id); glDeleteShader(fs_id); delete[] vs_err; delete[] fs_err; delete[] prg_err; }
CShader_GBuffer::CShader_GBuffer(std::string vs_path, std::string ps_path) { GLuint vsID = glCreateShader(GL_VERTEX_SHADER); GLuint psID = glCreateShader(GL_FRAGMENT_SHADER); std::string vsCode; std::ifstream vsStream(vs_path.c_str(), std::ios::in); if (vsStream.is_open()) { std::string line = ""; while (getline(vsStream, line)) { vsCode += "\n" + line; } vsStream.close(); } std::string psCode; std::ifstream psStream(ps_path.c_str(), std::ios::in); if (psStream.is_open()) { std::string line = ""; while (getline(psStream, line)) { psCode += "\n" + line; } psStream.close(); } GLint result = GL_FALSE; int logLength; // Compile vertex shader log(LOG_TYPE_DEFAULT, "Compiling Shader: " + vs_path + ".."); const char* vsPointer = vsCode.c_str(); glShaderSource(vsID, 1, &vsPointer, NULL); glCompileShader(vsID); // Check shader status glGetShaderiv(vsID, GL_COMPILE_STATUS, &result); if (!result) { glGetShaderiv(vsID, GL_INFO_LOG_LENGTH, &logLength); std::vector<char> vsError(logLength); glGetShaderInfoLog(vsID, logLength, NULL, &vsError[0]); if (vsError.size() - 1 >= 0) { vsError[vsError.size() - 1] = '\0'; } log(LOG_TYPE_ERROR, std::string((char*)&vsError[0])); } // Compile pixel shader log(LOG_TYPE_DEFAULT, "Compiling Shader: " + ps_path + ".."); const char* psPointer = psCode.c_str(); glShaderSource(psID, 1, &psPointer, NULL); glCompileShader(psID); // Check shader status glGetShaderiv(psID, GL_COMPILE_STATUS, &result); if (!result) { glGetShaderiv(psID, GL_INFO_LOG_LENGTH, &logLength); std::vector<char> psError(logLength); glGetShaderInfoLog(psID, logLength, NULL, &psError[0]); if (psError.size() - 1 >= 0) { psError[psError.size() - 1] = '\0'; } log(LOG_TYPE_ERROR, std::string((char*)&psError[0])); } // Link shader log(LOG_TYPE_DEFAULT, "Linking shader .."); GLuint shaderID = glCreateProgram(); glAttachShader(shaderID, vsID); glAttachShader(shaderID, psID); glLinkProgram(shaderID); // Check final shader glGetProgramiv(shaderID, GL_LINK_STATUS, &result); if (!result) { glGetProgramiv(shaderID, GL_INFO_LOG_LENGTH, &logLength); std::vector<char> shaderError(logLength); glGetProgramInfoLog(shaderID, logLength, NULL, &shaderError[0]); if (shaderError.size() - 1 >= 0) { shaderError[shaderError.size() - 1] = '\0'; } log(LOG_TYPE_ERROR, std::string((char*)&shaderError[0])); } // Clean up glDeleteShader(vsID); glDeleteShader(psID); // Save the ID m_Id = shaderID; }
void fhRenderProgram::Load() { if (!vertexShaderName[0] || !fragmentShaderName[0]) { return; } GlslShader vertexShader = R_LoadGlslShader( GL_VERTEX_SHADER, vertexShaderName ); if (!vertexShader.ident) { common->Warning( "failed to load GLSL vertex shader: %s", vertexShaderName ); return; } GlslShader fragmentShader = R_LoadGlslShader( GL_FRAGMENT_SHADER, fragmentShaderName ); if (!fragmentShader.ident) { common->Warning( "failed to load GLSL fragment shader: %s", fragmentShaderName ); return; } const GLuint program = glCreateProgram(); if (!program) { common->Warning( "failed to create GLSL program object" ); return; } vertexShader.attachToProgram( program ); fragmentShader.attachToProgram( program ); glLinkProgram( program ); GLint isLinked = 0; glGetProgramiv( program, GL_LINK_STATUS, &isLinked ); if (isLinked == GL_FALSE) { char buffer[1024]; GLsizei length; glGetProgramInfoLog( program, sizeof(buffer)-1, &length, &buffer[0] ); buffer[length] = '\0'; vertexShader.release(); fragmentShader.release(); glDeleteProgram( program ); common->Warning( "failed to link GLSL shaders to program: %s", &buffer[0] ); return; } if (ident) { glDeleteProgram( ident ); } if(program > 0) { uniformLocations[fhUniform::ModelMatrix] = glGetUniformLocation(program, "rpModelMatrix"); uniformLocations[fhUniform::ViewMatrix] = glGetUniformLocation(program, "rpViewMatrix"); uniformLocations[fhUniform::ModelViewMatrix] = glGetUniformLocation(program, "rpModelViewMatrix"); uniformLocations[fhUniform::ProjectionMatrix] = glGetUniformLocation(program, "rpProjectionMatrix"); uniformLocations[fhUniform::LocalLightOrigin] = glGetUniformLocation(program, "rpLocalLightOrigin"); uniformLocations[fhUniform::LocalViewOrigin] = glGetUniformLocation(program, "rpLocalViewOrigin"); uniformLocations[fhUniform::LightProjectionMatrixS] = glGetUniformLocation(program, "rpLightProjectionS"); uniformLocations[fhUniform::LightProjectionMatrixT] = glGetUniformLocation(program, "rpLightProjectionT"); uniformLocations[fhUniform::LightProjectionMatrixQ] = glGetUniformLocation(program, "rpLightProjectionQ"); uniformLocations[fhUniform::LightFallOff] = glGetUniformLocation(program, "rpLightFallOff"); uniformLocations[fhUniform::BumpMatrixS] = glGetUniformLocation(program, "rpBumpMatrixS"); uniformLocations[fhUniform::BumpMatrixT] = glGetUniformLocation(program, "rpBumpMatrixT"); uniformLocations[fhUniform::DiffuseMatrixS] = glGetUniformLocation( program, "rpDiffuseMatrixS" ); uniformLocations[fhUniform::DiffuseMatrixT] = glGetUniformLocation( program, "rpDiffuseMatrixT" ); uniformLocations[fhUniform::SpecularMatrixS] = glGetUniformLocation( program, "rpSpecularMatrixS" ); uniformLocations[fhUniform::SpecularMatrixT] = glGetUniformLocation( program, "rpSpecularMatrixT" ); uniformLocations[fhUniform::ColorModulate] = glGetUniformLocation( program, "rpColorModulate" ); uniformLocations[fhUniform::ColorAdd] = glGetUniformLocation( program, "rpColorAdd" ); uniformLocations[fhUniform::DiffuseColor] = glGetUniformLocation( program, "rpDiffuseColor" ); uniformLocations[fhUniform::SpecularColor] = glGetUniformLocation( program, "rpSpecularColor" ); uniformLocations[fhUniform::AmbientLight] = glGetUniformLocation(program, "rpAmbientLight"); uniformLocations[fhUniform::ShaderParm0] = glGetUniformLocation( program, "shaderParm0" ); uniformLocations[fhUniform::ShaderParm1] = glGetUniformLocation( program, "shaderParm1" ); uniformLocations[fhUniform::ShaderParm2] = glGetUniformLocation( program, "shaderParm2" ); uniformLocations[fhUniform::ShaderParm3] = glGetUniformLocation( program, "shaderParm3" ); uniformLocations[fhUniform::TextureMatrix0] = glGetUniformLocation( program, "textureMatrix0" ); uniformLocations[fhUniform::AlphaTestEnabled] = glGetUniformLocation( program, "rpAlphaTestEnabled" ); uniformLocations[fhUniform::AlphaTestThreshold] = glGetUniformLocation( program, "rpAlphaTestThreshold" ); uniformLocations[fhUniform::CurrentRenderSize] = glGetUniformLocation( program, "rpCurrentRenderSize" ); uniformLocations[fhUniform::ClipRange] = glGetUniformLocation( program, "rpClipRange" ); uniformLocations[fhUniform::DepthBlendMode] = glGetUniformLocation( program, "rpDepthBlendMode" ); uniformLocations[fhUniform::DepthBlendRange] = glGetUniformLocation( program, "rpDepthBlendRange" ); uniformLocations[fhUniform::PomMaxHeight] = glGetUniformLocation( program, "rpPomMaxHeight" ); uniformLocations[fhUniform::Shading] = glGetUniformLocation( program, "rpShading" ); uniformLocations[fhUniform::specularExp] = glGetUniformLocation( program, "rpSpecularExp" ); uniformLocations[fhUniform::ShadowMappingMode] = glGetUniformLocation( program, "rpShadowMappingMode" ); uniformLocations[fhUniform::SpotLightProjection] = glGetUniformLocation( program, "rpSpotlightProjection" ); uniformLocations[fhUniform::PointLightProjection] = glGetUniformLocation( program, "rpPointlightProjection" ); uniformLocations[fhUniform::GlobalLightOrigin] = glGetUniformLocation( program, "rpGlobalLightOrigin" ); uniformLocations[fhUniform::ShadowParams] = glGetUniformLocation( program, "rpShadowParams" ); uniformLocations[fhUniform::ShadowCoords] = glGetUniformLocation( program, "rpShadowCoords" ); uniformLocations[fhUniform::CascadeDistances] = glGetUniformLocation( program, "rpCascadeDistances" ); uniformLocations[fhUniform::ShadowMapSize] = glGetUniformLocation( program, "rpShadowMapSize" ); uniformLocations[fhUniform::InverseLightRotation] = glGetUniformLocation( program, "rpInverseLightRotation" ); uniformLocations[fhUniform::NormalMapEncoding] = glGetUniformLocation( program, "rpNormalMapEncoding" ); } else { for(int i=0; i<fhUniform::NUM; ++i) { uniformLocations[i] = -1; } } ident = program; }
///////////////////////////////////////////////////////////////// // Load a pair of shaders, compile, and link together. Specify the complete // source text for each shader. After the shader names, specify the number // of attributes, followed by the index and attribute name of each attribute GLuint gltLoadShaderPairWithAttributes(const char *szVertexProg, const char *szFragmentProg, ...) { // 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); // Load them. If fail clean up and return null // Vertex Program if(gltLoadShaderFile(szVertexProg, hVertexShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); fprintf(stderr, "The shader at %s could ot be found.\n", szVertexProg); return (GLuint)NULL; } // Fragment Program if(gltLoadShaderFile(szFragmentProg, hFragmentShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); fprintf(stderr,"The shader at %s could not be found.\n", szFragmentProg); return (GLuint)NULL; } // Compile them both glCompileShader(hVertexShader); glCompileShader(hFragmentShader); // Check for errors in vertex shader glGetShaderiv(hVertexShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { char infoLog[1024]; glGetShaderInfoLog(hVertexShader, 1024, NULL, infoLog); fprintf(stderr, "The shader at %s failed to compile with the following error:\n%s\n", szVertexProg, infoLog); glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } // Check for errors in fragment shader glGetShaderiv(hFragmentShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { char infoLog[1024]; glGetShaderInfoLog(hFragmentShader, 1024, NULL, infoLog); fprintf(stderr, "The shader at %s failed to compile with the following error:\n%s\n", szFragmentProg, infoLog); glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } // Create the final program object, and attach the shaders hReturn = glCreateProgram(); glAttachShader(hReturn, hVertexShader); glAttachShader(hReturn, hFragmentShader); // Now, we need to bind the attribute names to their specific locations // List of attributes va_list attributeList; va_start(attributeList, szFragmentProg); // Iterate over this argument list char *szNextArg; int iArgCount = va_arg(attributeList, int); // Number of attributes for(int i = 0; i < iArgCount; i++) { int index = va_arg(attributeList, int); szNextArg = va_arg(attributeList, char*); glBindAttribLocation(hReturn, index, szNextArg); } va_end(attributeList); // Attempt to link 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) { char infoLog[1024]; glGetProgramInfoLog(hReturn, 1024, NULL, infoLog); fprintf(stderr,"The programs %s and %s failed to link with the following errors:\n%s\n", szVertexProg, szFragmentProg, infoLog); glDeleteProgram(hReturn); return (GLuint)NULL; } // All done, return our ready to use shader program return hReturn; }
void sglGetProgramInfoLog(GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *infoLog) { glGetProgramInfoLog(shader, maxLength, length, infoLog); }
GLuint LoadShaders(const std::string &vertex_file_path,const std::string &fragment_file_path){ //std::cout << "load shaders" << std::endl; // 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.c_str(), std::ios::in); if (VertexShaderStream.is_open()){ std::string Line = ""; while(getline(VertexShaderStream, Line)) VertexShaderCode += "\n" + Line; VertexShaderStream.close(); } else { std::cerr << "ERROR: cannot open " << vertex_file_path << std::endl; exit(0); } // Read the Fragment Shader code from the file std::string FragmentShaderCode; std::ifstream FragmentShaderStream(fragment_file_path.c_str(), std::ios::in); if(FragmentShaderStream.is_open()){ std::string Line = ""; while(getline(FragmentShaderStream, Line)) FragmentShaderCode += "\n" + Line; FragmentShaderStream.close(); } else { std::cerr << "ERROR: cannot open " << vertex_file_path << std::endl; exit(0); } GLint Result = GL_FALSE; int InfoLogLength; // Compile Vertex Shader //std::cout << "Compiling shader : " << vertex_file_path << std::endl; 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); if ( InfoLogLength > 0 ){ std::vector<char> VertexShaderErrorMessage(InfoLogLength+1); glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); std::cerr << "VERTEX SHADER ERROR: " << std::string(VertexShaderErrorMessage.begin(), VertexShaderErrorMessage.end()) << std::endl; } // Compile Fragment Shader //std::cout << "Compiling shader : " << fragment_file_path << std::endl; 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); if ( InfoLogLength > 0 ){ std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1); glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); std::cerr << "FRAGMENT SHADER ERROR: " << std::string(FragmentShaderErrorMessage.begin(), FragmentShaderErrorMessage.end()) << std::endl; } // Link the program //std::cout << "Linking program" << std::endl; 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); if ( InfoLogLength > 0 ){ std::vector<char> ProgramErrorMessage(InfoLogLength+1); glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); std::cerr << "SHADER PROGRAM ERROR: " << std::string(ProgramErrorMessage.begin(), ProgramErrorMessage.end()) << std::endl; } glDeleteShader(VertexShaderID); glDeleteShader(FragmentShaderID); return ProgramID; }
bool CRhGLShaderProgram::BuildProgram(const GLchar* VertexShader, const GLchar* FragmentShader) { // Shaders MUST consist of both a vertex AND a fragment shader in 2.0... if ( (VertexShader == NULL) || (FragmentShader == NULL) ) return false; PreBuild(); GLuint hVsh = BuildShader( VertexShader, GL_VERTEX_SHADER ); GLuint hFsh = BuildShader( FragmentShader, GL_FRAGMENT_SHADER ); if ( (hVsh == 0) || (hFsh == 0) ) return false; m_hProgram = glCreateProgram(); if ( m_hProgram == 0 ) return false; glAttachShader( m_hProgram, hVsh ); glAttachShader( m_hProgram, hFsh ); // These bindings are forced here so that mesh drawing can enable the // appropriate vertex array based on the same binding values. // Note: These must be done before we attempt to link the program... // Note2: Rhino supports multiple textures but for now we'll only // provide for a single set of texture coordinates. glBindAttribLocation( m_hProgram, ATTRIB_VERTEX, "rglVertex" ); glBindAttribLocation( m_hProgram, ATTRIB_NORMAL, "rglNormal" ); glBindAttribLocation( m_hProgram, ATTRIB_TEXCOORD0, "rglTexCoord0" ); glBindAttribLocation( m_hProgram, ATTRIB_COLOR, "rglColor" ); glLinkProgram( m_hProgram ); GLint Success; glGetProgramiv( m_hProgram, GL_LINK_STATUS, &Success ); if ( Success == GL_FALSE ) { #if defined(_DEBUG) GLint logLength; glGetProgramiv( m_hProgram, GL_INFO_LOG_LENGTH, &logLength ); if (logLength > 0) { GLchar *log = (GLchar *)malloc(logLength); glGetProgramInfoLog( m_hProgram, logLength, &logLength, log); std::cout << "Program link log:\n" << log; free(log); } #endif glDetachShader( m_hProgram, hVsh ); glDetachShader( m_hProgram, hFsh ); glDeleteProgram( m_hProgram ); m_hProgram = 0; } glDeleteShader( hVsh ); glDeleteShader( hFsh ); if ( m_hProgram == 0 ) return false; PostBuild(); return true; }
void GLProgram::build( const char* vertsrc, const char* fragsrc, const char* geomsrc ) { GLuint vs = 0, fs = 0, gs = 0; GLint status = GL_TRUE; GLint loglen; std::string logbuf; if( !vertsrc || !fragsrc ) throw GLException( "Verter/Fragment shader source missing!\n" ); vs = glCreateShader( GL_VERTEX_SHADER ); if( !vs ) throw GLException("Vertex-Shader creation failed!\n"); glShaderSource( vs, 1, &vertsrc, NULL ); glCompileShader( vs ); glGetShaderiv( vs, GL_COMPILE_STATUS, &status ); if( status == GL_FALSE ) { glGetShaderiv( vs, GL_INFO_LOG_LENGTH, &loglen ); logbuf.resize( loglen ); glGetShaderInfoLog( vs, loglen, &loglen, &logbuf[ 0 ] ); glDeleteShader(vs); throw GLException("Vertex-Shader compilation error\n", logbuf ); } fs = glCreateShader( GL_FRAGMENT_SHADER ); if( !fs ) { glDeleteShader( vs ); throw GLException("Fragment-Shader creation failed!\n"); } glShaderSource( fs, 1, &fragsrc, NULL ); glCompileShader( fs ); glGetShaderiv( fs, GL_COMPILE_STATUS, &status ); if( status == GL_FALSE ) { glGetShaderiv( fs, GL_INFO_LOG_LENGTH, &loglen ); logbuf.resize( loglen ); glGetShaderInfoLog( fs, loglen, &loglen, &logbuf[ 0 ] ); glDeleteShader(fs); glDeleteShader(vs); throw GLException("Fragment-Shader compilation error\n", logbuf ); } if( geomsrc ) { gs = glCreateShader( GL_GEOMETRY_SHADER ); if( !gs ) { glDeleteShader( vs ); throw GLException("Geometry-Shader creation failed!\n"); } glShaderSource( gs, 1, &geomsrc, NULL ); glCompileShader( gs ); glGetShaderiv( gs, GL_COMPILE_STATUS, &status ); if( status == GL_FALSE ) { glGetShaderiv( gs, GL_INFO_LOG_LENGTH, &loglen ); logbuf.resize( loglen ); glGetShaderInfoLog( gs, loglen, &loglen, &logbuf[ 0 ] ); glDeleteShader( fs ); glDeleteShader( vs ); glDeleteShader( gs ); throw GLException("Geometry-Shader compilation error\n", logbuf ); } } glAttachShader( program, fs ); glAttachShader( program, vs ); if( gs ) glAttachShader( program, gs ); /* shaders are now referenced by programm, delete them*/ glDeleteShader( vs ); glDeleteShader( fs ); if( gs ) glDeleteShader( gs ); glLinkProgram( program ); glGetProgramiv( program, GL_LINK_STATUS, &status ); if(status == GL_FALSE) { glGetProgramiv( program, GL_INFO_LOG_LENGTH, &loglen ); logbuf.resize( loglen ); glGetProgramInfoLog( program, loglen, &loglen, &logbuf[ 0 ] ); throw GLException("Shader link error\n", logbuf ); } }