bool WShaderProgram::isValid() const { GLint validated; glValidateProgramARB( programId() ); glGetObjectParameterivARB( programId(), GL_OBJECT_VALIDATE_STATUS_ARB, &validated ); return validated != 0; }
bool ShaderProgramGl::link(string &messages){ assertGl(); VertexShaderGl *vertexShaderGl= static_cast<VertexShaderGl*>(vertexShader); FragmentShaderGl *fragmentShaderGl= static_cast<FragmentShaderGl*>(fragmentShader); const ShaderSource *vss= vertexShaderGl->getSource(); const ShaderSource *fss= fragmentShaderGl->getSource(); messages= "Linking program: " + vss->getPathInfo() + ", " + fss->getPathInfo() + "\n"; //attach glAttachObjectARB(handle, vertexShaderGl->getHandle()); glAttachObjectARB(handle, fragmentShaderGl->getHandle()); assertGl(); //bind attributes for(int i=0; i<attributes.size(); ++i){ //int a= attributes[i].second; //string s= attributes[i].first; glBindAttribLocationARB(handle, attributes[i].second, attributes[i].first.c_str()); } assertGl(); //link glLinkProgramARB(handle); glValidateProgramARB(handle); assertGl(); //log GLint logLength= 0; glGetObjectParameterivARB(handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logLength); char *buffer= new char[logLength+1]; glGetInfoLogARB(handle, logLength+1, NULL, buffer); messages+= buffer; delete [] buffer; assertGl(); //status GLint status= false; glGetObjectParameterivARB(handle, GL_OBJECT_LINK_STATUS_ARB, &status); assertGl(); return status!=0; }
GLboolean ValidateShaderProgram(GLuint program) { GLint stat; glValidateProgramARB(program); glGetProgramiv(program, GL_VALIDATE_STATUS, &stat); if (!stat) { GLchar log[1000]; GLsizei len; glGetProgramInfoLog(program, 1000, &len, log); fprintf(stderr, "Program validation error:\n%s\n", log); return 0; } return (GLboolean) stat; }
unsigned int RAS_2DFilterManager::CreateShaderProgram(const char* shadersource) { GLuint program = 0; GLuint fShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER); GLint success; glShaderSourceARB(fShader, 1, (const char**)&shadersource, NULL); glCompileShaderARB(fShader); glGetObjectParameterivARB(fShader, GL_COMPILE_STATUS, &success); if(!success) { /*Shader Comile Error*/ PrintShaderErrors(fShader, "compile", shadersource); return 0; } program = glCreateProgramObjectARB(); glAttachObjectARB(program, fShader); glLinkProgramARB(program); glGetObjectParameterivARB(program, GL_LINK_STATUS, &success); if (!success) { /*Program Link Error*/ PrintShaderErrors(fShader, "link", shadersource); return 0; } glValidateProgramARB(program); glGetObjectParameterivARB(program, GL_VALIDATE_STATUS, &success); if (!success) { /*Program Validation Error*/ PrintShaderErrors(fShader, "validate", shadersource); return 0; } return program; }
bool GLSL_ShaderPair::link () { GLint stat ; handle = glCreateProgramObjectARB () ; glAttachObjectARB ( handle, vertShader -> getHandle () ) ; glAttachObjectARB ( handle, fragShader -> getHandle () ) ; glLinkProgramARB ( handle ) ; glGetObjectParameterivARB ( handle, GL_OBJECT_LINK_STATUS_ARB, &stat ) ; showShaderInfo ( "Linking", handle, name ) ; glValidateProgramARB ( handle ) ; showShaderInfo ( "Validate", handle, name ) ; if ( ! stat ) { fprintf ( stderr, "Failed to link shader.\n" ) ; return false ; } return true ; }
int setup(void) { GLuint major, minor; GLint success; GLuint model_id; srand( (unsigned)time( NULL ) ); // Make sure required functionality is available! if (!getGLversion( &major, &minor)) return -1; if (major < 2) { printf("<!> OpenGL 2.0 or higher is required\n"); return -1; } windowpos = IsExtSupported("GL_ARB_window_pos"); // Make sure required functionality is available! if (!(IsExtSupported("GL_ARB_vertex_program"))) { printf("<!> ARB vertex program extension not supported\n"); return -1; } if (!(IsExtSupported("GL_ARB_fragment_program"))) { printf("<!> ARB fragment program extension not supported\n"); return -1; } if (!(IsExtSupported("GL_ARB_vertex_shader"))) { printf("<!> ARB vertex shader extension not supported\n"); return -1; } if (!(IsExtSupported("GL_ARB_fragment_shader"))) { printf("<!> ARB fragment shader extension not supported\n"); return -1; } if (!(IsExtSupported("GL_EXT_framebuffer_object"))) { printf("<!> Framebuffer object extension not supported\n"); return -1; } //Define extension prointers glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)glXGetProcAddressARB("glGenFramebuffersEXT"); glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)glXGetProcAddressARB("glBindFramebufferEXT"); glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)glXGetProcAddressARB("glFramebufferTexture2DEXT"); glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)glXGetProcAddressARB("glGenRenderbuffersEXT"); glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)glXGetProcAddressARB("glBindRenderbufferEXT"); glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)glXGetProcAddressARB("glRenderbufferStorageEXT"); glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)glXGetProcAddressARB("glFramebufferRenderbufferEXT"); glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)glXGetProcAddressARB("glDeleteFramebuffersEXT"); glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)glXGetProcAddressARB("glDeleteRenderbuffersEXT"); glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)glXGetProcAddressARB("glCheckFramebufferStatusEXT"); if ( !glGenFramebuffersEXT || !glBindFramebufferEXT || !glFramebufferTexture2DEXT || !glGenRenderbuffersEXT || !glBindRenderbufferEXT || !glRenderbufferStorageEXT || !glFramebufferRenderbufferEXT || !glDeleteFramebuffersEXT || !glDeleteRenderbuffersEXT || !glCheckFramebufferStatusEXT ) { printf("<!> Required extension not supported\n"); return -1; } //Enable smooth shading glShadeModel(GL_SMOOTH); //Enable depth testing glEnable(GL_DEPTH_TEST); glPolygonOffset( scalePoly, biasPoly ); //Enable backface culling glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace( GL_CW ); //Background color (Ligth blue) glClearColor(0.0f, 0.4f, 0.8f, 1.0f); //Generate texture objects texture_id = (GLuint *)malloc( NUM_TEXTURES * sizeof(GLuint) ); glGenTextures( NUM_TEXTURES, texture_id ); // Enable Anisotropic filtering (for 2D textures only) if( enable_anisotropic ) { glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &MaxAnisoLevel); if( AnisoLevel > MaxAnisoLevel) AnisoLevel = MaxAnisoLevel; if( print_info ) printf("<-> %.0fX anisotropic filtering enabled\n", AnisoLevel); } else AnisoLevel = 0.0f; // Enable FSAA if (enable_fsaa) glEnable(GL_MULTISAMPLE); //Load MD2 models and textures for (model_id = 0; model_id < NUM_MODELS; ++model_id) { // Load the .md2 model if ( (md2_model[model_id] = (MD2_MODEL_PTR)malloc(sizeof(MD2_MODEL))) == NULL) { printf("<!> Unable to allocate memory for MD2 model in %s\n", filename[3*model_id]); return -1; } if ( !LoadMD2(md2_model[model_id], filename[3*model_id]) ) { printf("<!> Unable to load MD2 model from %s\n", filename[3*model_id]); return -1; } if( print_info ) printf("<-> Loaded MD2 model from \"%s\" for model #%d\n", filename[3*model_id], model_id); // Load texture from disk if ( !LoadImageFromDisk(md2_model[model_id]->skin, filename[3*model_id+1]) ) { printf("<!> Unable to load texture from %s \n", filename[3*model_id+1]); return -1; } if( print_info ) printf("<-> Loaded texture from \"%s\" for model #%d\n", filename[3*model_id+1], model_id); //Set up model texture parameters glBindTexture(GL_TEXTURE_2D, texture_id[2*model_id]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D( GL_TEXTURE_2D, 0, md2_model[model_id]->skin->components, md2_model[model_id]->skin->width, md2_model[model_id]->skin->height, 0, md2_model[model_id]->skin->format, GL_UNSIGNED_BYTE, md2_model[model_id]->skin->data); // Load normal from disk if ( !LoadImageFromDisk(md2_model[model_id]->normal, filename[3*model_id+2]) ) { printf("<!> Unable to load texture from %s \n", filename[3*model_id+2]); return -1; } if( print_info ) printf("<-> Loaded texture from \"%s\" for model #%d\n", filename[3*model_id+2], model_id); //Set up model texture parameters glBindTexture(GL_TEXTURE_2D, texture_id[2*model_id+1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D( GL_TEXTURE_2D, 0, md2_model[model_id]->normal->components, md2_model[model_id]->normal->width, md2_model[model_id]->normal->height, 0, md2_model[model_id]->normal->format, GL_UNSIGNED_BYTE, md2_model[model_id]->normal->data); } // Load floor texture from disk floor_texture = (IMAGE_PTR)malloc(sizeof(IMAGE)); floor_texture->data = NULL; if ( !LoadImageFromDisk(floor_texture, filename[3*NUM_MODELS]) ) { printf("<!> Unable to load texture from %s\n", filename[3*NUM_MODELS]); return -1; } if( print_info ) printf("<-> Loaded texture from \"%s\"\n", filename[3*NUM_MODELS]); //Set up floor texture parameters glBindTexture(GL_TEXTURE_2D, texture_id[NUM_TEXTURES-2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (enable_anisotropic) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, AnisoLevel); glTexImage2D( GL_TEXTURE_2D, 0, floor_texture->components, floor_texture->width, floor_texture->height, 0, floor_texture->format, GL_UNSIGNED_BYTE, floor_texture->data); if (floor_texture->data) { free(floor_texture->data); floor_texture->data = NULL; } // Load floor normal map from disk floor_texture = (IMAGE_PTR)malloc(sizeof(IMAGE)); floor_texture->data = NULL; if ( !LoadImageFromDisk(floor_texture, filename[3*NUM_MODELS+1]) ) { printf("<!> Unable to load texture from %s\n", filename[3*NUM_MODELS+1]); return -1; } if( print_info ) printf("<-> Loaded texture from \"%s\"\n", filename[3*NUM_MODELS+1]); //Set up floor texture parameters glBindTexture(GL_TEXTURE_2D, texture_id[NUM_TEXTURES-1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (enable_anisotropic) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, AnisoLevel); glTexImage2D( GL_TEXTURE_2D, 0, floor_texture->components, floor_texture->width, floor_texture->height, 0, floor_texture->format, GL_UNSIGNED_BYTE, floor_texture->data); if (floor_texture->data) { free(floor_texture->data); floor_texture->data = NULL; } // Load and compile low-level shaders glGenProgramsARB(NUM_SHADERS, ids); if (!CompileShader(GL_VERTEX_PROGRAM_ARB, ids[0], DATA_DIR "data/shaders/light.vp")) return -1; if (!CompileShader(GL_FRAGMENT_PROGRAM_ARB, ids[1], DATA_DIR "data/shaders/lightMasked.fp")) return -1; // Create program object and compile GLSL shaders progObj = glCreateProgramObjectARB(); if (!CompileGLSLshaders(&progObj, DATA_DIR "data/shaders/bumpTBN_SH_VP.glsl", DATA_DIR "data/shaders/bumpTBN_SH_FP.glsl", GL_FALSE)) return -1; // Retrieve uniform and attributes locations glUseProgramObjectARB(progObj); colorMap = glGetUniformLocationARB(progObj, "colorMap"); bumpMap = glGetUniformLocationARB(progObj, "bumpMap"); shadowMap = glGetUniformLocationARB(progObj, "shadowMap"); tangent = glGetAttribLocation(progObj, "tangent"); binormal = glGetAttribLocation(progObj, "binormal"); for (model_id = 0; model_id < NUM_MODELS; ++model_id) { md2_model[model_id]->tangent = tangent; md2_model[model_id]->binormal = binormal; } // Set texture units glUniform1i( colorMap, 0 ); glUniform1i( bumpMap, 1 ); glUniform1i( shadowMap, 2 ); //Validate shaders glValidateProgramARB(progObj); glGetObjectParameterivARB(progObj, GL_OBJECT_VALIDATE_STATUS_ARB, &success); if (!success) { GLbyte infoLog[MAX_INFO_LOG_SIZE]; glGetInfoLogARB(progObj, MAX_INFO_LOG_SIZE, NULL, (char *)infoLog); printf("<!> Error in program validation\n"); printf("Info log: %s\n", infoLog); return -1; } //Disable GLSL and enable low-level shaders glUseProgramObjectARB(0); glEnable(GL_VERTEX_PROGRAM_ARB); glEnable(GL_FRAGMENT_PROGRAM_ARB); glBindProgramARB(GL_VERTEX_PROGRAM_ARB, ids[0]); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, ids[1]); // Create FrameBuffer if (!CreateFB( shadow_sz, &FBO, &shadow_tx )) return -1; //Prebuild the display lists FList = glGenLists(1); glNewList(FList, GL_COMPILE); DrawGround(); glEndList(); //Init animations and kinematic state md2_model[0]->anim_state = ANIMATION_RUN; md2_model[0]->anim_command = ANIMATION_START; md2_model[0]->delta_rate = 30.f; md2_model[0]->position.x = 85.f; md2_model[0]->position.z = 0.f; md2_model[0]->rotation = 90.f; md2_model[1]->anim_state = ANIMATION_RUN; md2_model[1]->anim_command = ANIMATION_START; md2_model[1]->delta_rate = 30.f; md2_model[1]->position.x = 85.f; md2_model[1]->position.z = 0.f; md2_model[1]->rotation = 90.f; md2_model[2]->anim_state = ANIMATION_STANDING_IDLE; md2_model[2]->anim_command = ANIMATION_START; // Set initial camera position and orientation xCam = 0.0f; yCam = 70.0f; zCam = 200.0f; eCam = -0.35f; aCam = 0.0f; lCam = 0.0f; vCam = 0.0f; dCam = 0.0f; //Set initial light aLit = 0.0f; eLit = 0.75f; // Initialise timer gettimeofday(&tv, NULL); t0 = (double)tv.tv_sec + tv.tv_usec / 1000000.0f; t1 = t0; t2 = t0; return 0; }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_ARBShaderObjects_nglValidateProgramARB(JNIEnv *env, jclass clazz, jint programObj, jlong function_pointer) { glValidateProgramARBPROC glValidateProgramARB = (glValidateProgramARBPROC)((intptr_t)function_pointer); glValidateProgramARB(programObj); }
/*************************************************************************** setShader ****************************************************************************/ void setShader(){ GLhandleARB my_program; GLhandleARB my_vertex_shader; GLhandleARB my_fragment_shader; GLsizei* elength = E_MALLOC(sizeof(GLint)); GLchar* infolog = E_MALLOC(5000*sizeof(GLchar)); // Create Shader And Program Objects my_program = glCreateProgramObjectARB(); my_vertex_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); my_fragment_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); // Load Shader Sources GLcharARB* vertsrc; GLcharARB* fragsrc; switch(shademode){ case GOOCH_SHADER: vertsrc = readShaderSrc("/Users/tom/Desktop/all_shaders/gooch.vert"); fragsrc = readShaderSrc("/Users/tom/Desktop/all_shaders/gooch.frag"); break; case PHONG_SHADER: vertsrc = readShaderSrc("/Users/tom/Desktop/all_shaders/phong-use-diffuse.vert"); fragsrc = readShaderSrc("/Users/tom/Desktop/all_shaders/phong-use-diffuse.frag"); break; case LATTICE_SHADER: vertsrc = readShaderSrc("/Users/tom/Desktop/all_shaders/CH11-lattice.vert.txt"); fragsrc = readShaderSrc("/Users/tom/Desktop/all_shaders/CH11-lattice.frag.txt"); break; case PPL2_SHADER: vertsrc = readShaderSrc("/Users/tom/Desktop/all_shaders/per-pixel-lighting.vert"); fragsrc = readShaderSrc("/Users/tom/Desktop/all_shaders/per-pixel-lighting.frag"); break; case TEST_SHADER: vertsrc = readShaderSrc("/Users/tom/Desktop/all_shaders/CH14-chromaticAb.vert.txt"); fragsrc = readShaderSrc("/Users/tom/Desktop/all_shaders/CH14-chromaticAb.frag.txt"); break; } glShaderSourceARB(my_vertex_shader, 1, &vertsrc, NULL); glShaderSourceARB(my_fragment_shader, 1, &fragsrc, NULL); // Compile The Shaders glCompileShaderARB(my_vertex_shader); GLint blen = 0; GLint slen = 0; GLchar* compiler_log; glGetObjectParameterivARB(my_vertex_shader, GL_OBJECT_INFO_LOG_LENGTH_ARB , &blen); if (blen > 1) { if ((compiler_log = (GLcharARB*)E_MALLOC(blen)) == NULL) { printf("OOM\n"); } glGetInfoLogARB(my_vertex_shader, blen, &slen, compiler_log); if (compiler_log!=0) { printf("compiler_log: %s\n", compiler_log); free(compiler_log); } } glCompileShaderARB(my_fragment_shader); glGetObjectParameterivARB(my_fragment_shader, GL_OBJECT_INFO_LOG_LENGTH_ARB , &blen); if (blen > 1) { if ((compiler_log = (GLcharARB*)E_MALLOC(blen)) == NULL) { printf("OOM\n"); } glGetInfoLogARB(my_fragment_shader, blen, &slen, compiler_log); if (compiler_log!=0) { printf("compiler_log: %s\n", compiler_log); free(compiler_log); } } // Attach The Shader Objects To The Program Object glAttachObjectARB(my_program, my_vertex_shader); glAttachObjectARB(my_program, my_fragment_shader); glGetObjectParameterivARB(my_program, GL_OBJECT_INFO_LOG_LENGTH_ARB , elength); if (elength > 0){ glGetInfoLogARB(my_program, 500, elength, infolog); printf("%s\n", infolog); } // Link The Program Object glLinkProgramARB(my_program); glGetObjectParameterivARB(my_program, GL_OBJECT_INFO_LOG_LENGTH_ARB , elength); if (elength > 0){ glGetInfoLogARB(my_program, 500, elength, infolog); printf("%s\n", infolog); } glValidateProgramARB(my_program); if(GL_VALIDATE_STATUS){ // Use The Program Object Instead Of Fixed Function OpenGL glUseProgramObjectARB(my_program); if(shademode == GOOCH_SHADER){ // set gooch shader parameters GLint loc; GLfloat vs[]={0.75, 0.75, 0.75}; loc = glGetUniformLocationARB(my_program, "SurfaceColor"); glUniform3fv(loc, 1, vs); GLfloat vw[]={0.6, 0.6, 0.0}; loc = glGetUniformLocationARB(my_program, "WarmColor"); glUniform3fv(loc, 1, vw); GLfloat vc[]={0.0, 0.0, 0.6}; loc = glGetUniformLocationARB(my_program, "CoolColor"); glUniform3fv(loc, 1, vc); loc = glGetUniformLocationARB(my_program, "DiffuseWarm"); glUniform1f(loc, 0.45); loc = glGetUniformLocationARB(my_program, "DiffuseCool"); glUniform1f(loc, 0.40); } if(shademode == LATTICE_SHADER){ // set gooch shader parameters GLint loc; GLfloat vs[]={10.00, 100.0, 0.0}; loc = glGetUniformLocationARB(my_program, "LightPosition"); glUniform3fv(loc, 1, vs); GLfloat vw[]={0.6, 0.6, 0.0}; loc = glGetUniformLocationARB(my_program, "LightColor"); glUniform3fv(loc, 1, vw); GLfloat vc[]={0.0, 0.0, 100.0}; loc = glGetUniformLocationARB(my_program, "EyePosition"); glUniform3fv(loc, 1, vc); GLfloat vd[]={0.5, 0.5, 0.5}; loc = glGetUniformLocationARB(my_program, "Specular"); glUniform3fv(loc, 1, vd); GLfloat ve[]={1.0, 1.0, 1.0}; loc = glGetUniformLocationARB(my_program, "Ambient"); glUniform3fv(loc, 1, ve); loc = glGetUniformLocationARB(my_program, "Kd"); glUniform1f(loc, 0.40); GLfloat vf[]={20.0, 20.0}; loc = glGetUniformLocationARB(my_program, "Scale"); glUniform2fv(loc, 1, vf); GLfloat vg[]={0.3, 0.3}; loc = glGetUniformLocationARB(my_program, "Threshold"); glUniform2fv(loc, 1, vg); GLfloat vh[]={0.5, 0.5, 0.5}; loc = glGetUniformLocationARB(my_program, "SurfaceColor"); glUniform3fv(loc, 1, vh); } } glGetObjectParameterivARB(my_program, GL_OBJECT_INFO_LOG_LENGTH_ARB , elength); if (elength > 0){ glGetInfoLogARB(my_program, 500, elength, infolog); printf("%s\n", infolog); } }
static inline bool r_create_program(const char *id, const char *vss, const char *fss, uint *vs, uint *fs, uint *prog) { OPENGL_EVENT_BEGIN(0, __PRETTY_FUNCTION__); *vs = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); *fs = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); // shut up compiler... glShaderSourceARB(*vs, 1, (const char **)&vss, NULL); glShaderSourceARB(*fs, 1, (const char **)&fss, NULL); // compile vertex shader glCompileShaderARB(*vs); if (!r_shader_check(*vs, GL_OBJECT_COMPILE_STATUS_ARB, id, "vertex shader compilation")) { OPENGL_EVENT_END(); return false; } // compile fragment shader glCompileShaderARB(*fs); if (!r_shader_check(*fs, GL_OBJECT_COMPILE_STATUS_ARB, id, "fragment shader compilation")) { OPENGL_EVENT_END(); return false; } // link the program together *prog = glCreateProgramObjectARB(); glAttachObjectARB(*prog, *vs); glAttachObjectARB(*prog, *fs); glLinkProgramARB(*prog); if (!r_shader_check(*prog, GL_OBJECT_LINK_STATUS_ARB, id, "GPU program linking")) { OPENGL_EVENT_END(); return false; } // validate the program glValidateProgramARB(*prog); if (!r_shader_check(*prog, GL_OBJECT_VALIDATE_STATUS_ARB, id, "GPU program validation")) { OPENGL_EVENT_END(); return false; } #if OPENGL_DEBUG if (GLEW_KHR_debug) { glObjectLabel(GL_SHADER, *vs, -1, id); glObjectLabel(GL_SHADER, *fs, -1, id); glObjectLabel(GL_PROGRAM, *prog, -1, id); } #endif OPENGL_EVENT_END(); return true; }