// // Constructor // CCgShader::CCgShader( CGenum SourceType, const string& SourceStr, CGprofile Profile, CGGLenum ProfileClass, const string& Entry, const string& Arguments ): m_Program( NULL ) { if (SourceType != CG_SOURCE && SourceType != CG_OBJECT) throw Sys::CDeveloperException( "GL::CCgShader", "::CCgShader() : Invalid <SourceType> parameter." ); if (SourceStr.length() == 0) throw Sys::CDeveloperException( "GL::CCgShader", "::CCgShader() : Invalid <SourceStr> parameter." ); CCgContext::AddRef(); if (Profile == CG_PROFILE_UNKNOWN) Profile = cgGLGetLatestProfile( ProfileClass ); else { CheckDomain( Profile, ProfileClass ); if (cgGLIsProfileSupported( Profile ) == CG_FALSE) { const char *ProfileName = GetProfileName( Profile ); if (!ProfileName) throw Sys::CException( 0, "GL::CCgShader", "::CCgShader() : Unknown shader profile." ); else { throw Sys::CException( 0, "GL::CCgShader", "::CCgShader() : Profile %s unsupported.\n" "A profile may not be supported if required OpenGL extension is not available.", ProfileName ); } } } try { const char *TypeName = NULL; switch (ProfileClass) { case CG_GL_VERTEX: TypeName = "vertex"; break; case CG_GL_GEOMETRY: TypeName = "geometry"; break; case CG_GL_FRAGMENT: TypeName = "fragment"; break; } const char *Args[ 2 ] = { Arguments.c_str(), NULL }; m_Program = cgCreateProgram( CCgContext::GetContext(), SourceType, SourceStr.c_str(), Profile, (Entry.length() == 0) ? NULL : Entry.c_str(), (Arguments.length() == 0) ? NULL : Args ); if (!m_Program) { m_LastListing = CCgContext::GetLastListing(); #ifdef _DEBUG OutputDebugLog(); #endif throw CCgException( "GL::CCgShader", cgGetError(), "::CCgShader() : Failed to create Cg %s shader.\nSee program log for more details.", TypeName ); } cgCompileProgram( m_Program ); CGerror Error = cgGetError(); if (Error != CG_NO_ERROR) { m_LastListing = CCgContext::GetLastListing(); #ifdef _DEBUG OutputDebugLog(); #endif throw CCgException( "GL::CCgShader", Error, "::CCgShader() : Failed to compile Cg %s shader.\nSee program log for more details.", TypeName ); } } catch (const Sys::CException& Ex) { if (cgIsProgram( m_Program )) cgDestroyProgram( m_Program ); CCgContext::Release(); throw Ex; } }
bool CGLCG::LoadShader(const TCHAR *shaderFile) { CCGShader cgShader; TCHAR shaderPath[MAX_PATH]; TCHAR tempPath[MAX_PATH]; CGprofile vertexProfile, fragmentProfile; GLenum error; if(!fboFunctionsLoaded) { MessageBox(NULL, TEXT("Your OpenGL graphics driver does not support framebuffer objects.\nYou will not be able to use CG shaders in OpenGL mode."), TEXT("CG Error"), MB_OK|MB_ICONEXCLAMATION); return false; } vertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX); fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); cgGLDisableProfile(vertexProfile); cgGLDisableProfile(fragmentProfile); ClearPasses(); if(prevTex) { glDeleteTextures(1,&prevTex); prevTex=0; } if (shaderFile == NULL || *shaderFile==TEXT('\0')) return true; lstrcpy(shaderPath,shaderFile); for(int i=lstrlen(shaderPath); i>=0; i--){ if(IS_SLASH(shaderPath[i])){ shaderPath[i]=TEXT('\0'); break; } } SetCurrentDirectory(shaderPath); if(!cgShader.LoadShader(_tToChar(shaderFile))) return false; cgGLSetOptimalOptions(vertexProfile); cgGLSetOptimalOptions(fragmentProfile); /* insert dummy pass that will contain the original texture */ shaderPasses.push_back(shaderPass()); for(CCGShader::passVector::iterator it=cgShader.shaderPasses.begin(); it!=cgShader.shaderPasses.end();it++) { shaderPass pass; pass.scaleParams = it->scaleParams; /* if this is the last pass (the only one that can have CG_SCALE_NONE) and no filter has been set use the GUI setting */ if(pass.scaleParams.scaleTypeX==CG_SCALE_NONE && !it->filterSet) { pass.linearFilter = GUI.BilinearFilter; } else { pass.linearFilter = it->linearFilter; } // paths in the meta file can be relative _tfullpath(tempPath,_tFromChar(it->cgShaderFile),MAX_PATH); char *fileContents = ReadShaderFileContents(tempPath); if(!fileContents) return false; pass.cgVertexProgram = cgCreateProgram( cgContext, CG_SOURCE, fileContents, vertexProfile, "main_vertex", NULL); checkForCgError("Compiling vertex program"); pass.cgFragmentProgram = cgCreateProgram( cgContext, CG_SOURCE, fileContents, fragmentProfile, "main_fragment", NULL); checkForCgError("Compiling fragment program"); delete [] fileContents; if(!pass.cgVertexProgram || !pass.cgFragmentProgram) { return false; } cgGLLoadProgram(pass.cgVertexProgram); cgGLLoadProgram(pass.cgFragmentProgram); /* generate framebuffer and texture for this pass and apply default texture settings */ glGenFramebuffers(1,&pass.fbo); glGenTextures(1,&pass.tex); glBindTexture(GL_TEXTURE_2D,pass.tex); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); shaderPasses.push_back(pass); } for(std::vector<CCGShader::lookupTexture>::iterator it=cgShader.lookupTextures.begin();it!=cgShader.lookupTextures.end();it++) { lookupTexture tex; strcpy(tex.id,it->id); /* generate texture for the lut and apply specified filter setting */ glGenTextures(1,&tex.tex); glBindTexture(GL_TEXTURE_2D,tex.tex); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, it->linearfilter?GL_LINEAR:GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, it->linearfilter?GL_LINEAR:GL_NEAREST); _tfullpath(tempPath,_tFromChar(it->texturePath),MAX_PATH); // simple file extension png/tga decision int strLen = strlen(it->texturePath); if(strLen>4) { if(!strcasecmp(&it->texturePath[strLen-4],".png")) { int width, height; bool hasAlpha; GLubyte *texData; if(loadPngImage(tempPath,width,height,hasAlpha,&texData)) { glPixelStorei(GL_UNPACK_ROW_LENGTH, width); glTexImage2D(GL_TEXTURE_2D, 0, hasAlpha ? 4 : 3, width, height, 0, hasAlpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, texData); free(texData); } } else if(!strcasecmp(&it->texturePath[strLen-4],".tga")) { STGA stga; if(loadTGA(tempPath,stga)) { glPixelStorei(GL_UNPACK_ROW_LENGTH, stga.width); glTexImage2D(GL_TEXTURE_2D, 0, 4, stga.width, stga.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, stga.data); } } } lookupTextures.push_back(tex); } /* enable texture unit 1 for the lookup textures */ glClientActiveTexture(GL_TEXTURE1); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2,GL_FLOAT,0,lut_coords); glClientActiveTexture(GL_TEXTURE0); /* generate a texture that we can swap with the original texture and pass back to the main opengl code */ glGenTextures(1,&prevTex); glBindTexture(GL_TEXTURE_2D,prevTex); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,512,512,0,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,NULL); glBindTexture(GL_TEXTURE_2D,0); prevTexSize.x = prevTexSize.y = prevTexImageSize.x = prevTexImageSize.y = 0; memset(prevTexCoords,0,sizeof(prevTexCoords)); shaderLoaded = true; return true; }
void CGLCG::Render(GLuint &origTex, xySize textureSize, xySize inputSize, xySize viewportSize, xySize windowSize) { GLenum error; frameCnt++; CGprofile vertexProfile, fragmentProfile; if(!shaderLoaded) return; vertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX); fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); cgGLEnableProfile(vertexProfile); cgGLEnableProfile(fragmentProfile); /* set up our dummy pass for easier loop code */ shaderPasses[0].tex = origTex; shaderPasses[0].outputSize = inputSize; shaderPasses[0].textureSize = textureSize; /* loop through all real passes */ for(int i=1;i<shaderPasses.size();i++) { switch(shaderPasses[i].scaleParams.scaleTypeX) { case CG_SCALE_ABSOLUTE: shaderPasses[i].outputSize.x = (double)shaderPasses[i].scaleParams.absX; break; case CG_SCALE_SOURCE: shaderPasses[i].outputSize.x = shaderPasses[i-1].outputSize.x * shaderPasses[i].scaleParams.scaleX; break; case CG_SCALE_VIEWPORT: shaderPasses[i].outputSize.x = viewportSize.x * shaderPasses[i].scaleParams.scaleX; break; default: shaderPasses[i].outputSize.x = viewportSize.x; } switch(shaderPasses[i].scaleParams.scaleTypeY) { case CG_SCALE_ABSOLUTE: shaderPasses[i].outputSize.y = (double)shaderPasses[i].scaleParams.absX; break; case CG_SCALE_SOURCE: shaderPasses[i].outputSize.y = shaderPasses[i-1].outputSize.y * shaderPasses[i].scaleParams.scaleY; break; case CG_SCALE_VIEWPORT: shaderPasses[i].outputSize.y = viewportSize.y * shaderPasses[i].scaleParams.scaleY; break; default: shaderPasses[i].outputSize.y = viewportSize.y; } /* use next power of two in both directions */ float texSize = npot(max(shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y)); shaderPasses[i].textureSize.x = shaderPasses[i].textureSize.y = texSize; /* set size of output texture */ glBindTexture(GL_TEXTURE_2D,shaderPasses[i].tex); glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,(unsigned int)shaderPasses[i].textureSize.x, (unsigned int)shaderPasses[i].textureSize.y,0,GL_RGBA,GL_UNSIGNED_INT_8_8_8_8,NULL); /* viewport determines the area we render into the output texture */ glViewport(0,0,shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y); /* set up framebuffer and attach output texture */ glBindFramebuffer(GL_FRAMEBUFFER,shaderPasses[i].fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, shaderPasses[i].tex, 0); /* set up input texture (output of previous pass) and apply filter settings */ glBindTexture(GL_TEXTURE_2D,shaderPasses[i-1].tex); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)shaderPasses[i-1].textureSize.x); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shaderPasses[i].linearFilter?GL_LINEAR:GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, shaderPasses[i].linearFilter?GL_LINEAR:GL_NEAREST); /* calculate tex coords first since we pass them to the shader */ setTexCoords(i,shaderPasses[i-1].outputSize,shaderPasses[i-1].textureSize); setShaderVars(i); cgGLBindProgram(shaderPasses[i].cgVertexProgram); cgGLBindProgram(shaderPasses[i].cgFragmentProgram); glClearColor(0.0f, 0.0f, 0.0f, 0.5f); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays (GL_QUADS, 0, 4); } /* disable framebuffer */ glBindFramebuffer(GL_FRAMEBUFFER,0); /* switch original and prev texture and make sure the new original texture has the same size as the old one */ origTex = prevTex; prevTex = shaderPasses[0].tex; prevTexSize.x = textureSize.x; prevTexSize.y = textureSize.y; prevTexImageSize.x = inputSize.x; prevTexImageSize.y = inputSize.y; memcpy(prevTexCoords,shaderPasses[1].texcoords,sizeof(prevTexCoords)); glBindTexture(GL_TEXTURE_2D,origTex); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,textureSize.x,textureSize.y,0,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,NULL); /* bind output of last pass to be rendered on the backbuffer */ glBindTexture(GL_TEXTURE_2D,shaderPasses.back().tex); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)shaderPasses.back().textureSize.x); /* calculate and apply viewport and texture coordinates to that will be used in the main ogl code */ RECT displayRect=CalculateDisplayRect(shaderPasses.back().outputSize.x,shaderPasses.back().outputSize.y,windowSize.x,windowSize.y); glViewport(displayRect.left,windowSize.y-displayRect.bottom,displayRect.right-displayRect.left,displayRect.bottom-displayRect.top); setTexCoords(shaderPasses.size()-1,shaderPasses.back().outputSize,shaderPasses.back().textureSize,true); /* render to backbuffer without shaders */ cgGLDisableProfile(vertexProfile); cgGLDisableProfile(fragmentProfile); }
static void *gl_cg_init(void *data, const char *path) { unsigned i; cg_shader_data_t *cg = (cg_shader_data_t*) calloc(1, sizeof(cg_shader_data_t)); if (!cg) return NULL; #ifdef HAVE_CG_RUNTIME_COMPILER cgRTCgcInit(); #endif cg->cgCtx = cgCreateContext(); if (!cg->cgCtx) { RARCH_ERR("Failed to create Cg context.\n"); goto error; } #ifdef RARCH_CG_DEBUG cgGLSetDebugMode(CG_TRUE); cgSetErrorHandler(cg_error_handler, NULL); #endif cg->cgFProf = cgGLGetLatestProfile(CG_GL_FRAGMENT); cg->cgVProf = cgGLGetLatestProfile(CG_GL_VERTEX); if ( cg->cgFProf == CG_PROFILE_UNKNOWN || cg->cgVProf == CG_PROFILE_UNKNOWN) { RARCH_ERR("Invalid profile type\n"); goto error; } RARCH_LOG("[CG]: Vertex profile: %s\n", cgGetProfileString(cg->cgVProf)); RARCH_LOG("[CG]: Fragment profile: %s\n", cgGetProfileString(cg->cgFProf)); cgGLSetOptimalOptions(cg->cgFProf); cgGLSetOptimalOptions(cg->cgVProf); cgGLEnableProfile(cg->cgFProf); cgGLEnableProfile(cg->cgVProf); memset(cg->alias_define, 0, sizeof(cg->alias_define)); if ( !string_is_empty(path) && string_is_equal(path_get_extension(path), "cgp")) { if (!gl_cg_load_preset(cg, path)) goto error; } else { if (!gl_cg_load_plain(cg, path)) goto error; } cg->prg[0].mvp = cgGetNamedParameter(cg->prg[0].vprg, "IN.mvp_matrix"); for (i = 1; i <= cg->shader->passes; i++) gl_cg_set_program_attributes(cg, i); /* If we aren't using last pass non-FBO shader, * this shader will be assumed to be "fixed-function". * * Just use prg[0] for that pass, which will be * pass-through. */ cg->prg[cg->shader->passes + 1] = cg->prg[0]; /* No need to apply Android hack in Cg. */ cg->prg[VIDEO_SHADER_STOCK_BLEND] = cg->prg[0]; gl_cg_set_shaders(cg->prg[1].fprg, cg->prg[1].vprg); gl_cg_reset_attrib(cg); return cg; error: gl_cg_destroy_resources(cg); if (!cg) free(cg); return NULL; }
void COpenGLCgMaterialRenderer::init(s32& materialType, const c8* vertexProgram, const c8* vertexEntry, E_VERTEX_SHADER_TYPE vertexProfile, const c8* fragmentProgram, const c8* fragmentEntry, E_PIXEL_SHADER_TYPE fragmentProfile, const c8* geometryProgram, const c8* geometryEntry, E_GEOMETRY_SHADER_TYPE geometryProfile, scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, u32 vertices) { bool shaderStatus = true; CGerror Error = CG_NO_ERROR; materialType = -1; // TODO: add profile selection if (vertexProgram) { VertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX); if (VertexProfile) VertexProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, vertexProgram, VertexProfile, vertexEntry, 0); if (!VertexProgram) { Error = cgGetError(); os::Printer::log("Cg vertex program failed to compile:", ELL_ERROR); os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); shaderStatus = false; } else cgGLLoadProgram(VertexProgram); } if (fragmentProgram) { FragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); if (FragmentProfile) FragmentProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, fragmentProgram, FragmentProfile, fragmentEntry, 0); if (!FragmentProgram) { Error = cgGetError(); os::Printer::log("Cg fragment program failed to compile:", ELL_ERROR); os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); shaderStatus = false; } else cgGLLoadProgram(FragmentProgram); } if (geometryProgram) { GeometryProfile = cgGLGetLatestProfile(CG_GL_GEOMETRY); if (GeometryProfile) GeometryProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, geometryProgram, GeometryProfile, geometryEntry, 0); if (!GeometryProgram) { Error = cgGetError(); os::Printer::log("Cg geometry program failed to compile:", ELL_ERROR); os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); shaderStatus = false; } else cgGLLoadProgram(GeometryProgram); } getUniformList(); // create OpenGL specifics sampler uniforms. for (unsigned int i = 0; i < UniformInfo.size(); ++i) { if (UniformInfo[i]->getType() == CG_SAMPLER2D) { bool IsGlobal = true; if (UniformInfo[i]->getSpace() == CG_PROGRAM) IsGlobal = false; CCgUniform* Uniform = new COpenGLCgUniformSampler2D(UniformInfo[i]->getParameter(), IsGlobal); delete UniformInfo[i]; UniformInfo[i] = Uniform; } } if (shaderStatus) materialType = Driver->addMaterialRenderer(this); }
void Sarge::InitializeSargeShaders() { TextureLoader textureLoader; ///////////////////////////// //Vertex Shader vsSargeProfile = cgGLGetLatestProfile(CG_GL_VERTEX); cgGLSetOptimalOptions(vsSargeProfile); CheckForCgError("sarge", "selecting vertex profile"); vsSargeProgram = cgCreateProgramFromFile(ShaderContext, CG_SOURCE, "assets/vertexshaders/vs_sarge.cg", vsSargeProfile, "sargeVertexShader", 0); CheckForCgError("sarge", "creating vertex program from file"); cgGLLoadProgram(vsSargeProgram); CheckForCgError("sarge", "loading vertex program"); ////////////////////////////// //Pixel Shader psSargeProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); cgGLSetOptimalOptions(psSargeProfile); CheckForCgError("sarge", "selecting pixel profile"); psSargeProgram = cgCreateProgramFromFile(ShaderContext, CG_SOURCE, "assets/pixelshaders/ps_sarge.cg", psSargeProfile, "sargeLightMap", 0); CheckForCgError("sarge", "creating fragment program from file"); cgGLLoadProgram(psSargeProgram); CheckForCgError("sarge", "loading fragment program"); modelViewProj = cgGetNamedParameter(vsSargeProgram, "modelViewProj"); lightViewProj = cgGetNamedParameter(vsSargeProgram, "lightViewProj"); vertin = cgGetNamedParameter(vsSargeProgram, "vertin"); lightPosition = cgGetNamedParameter(vsSargeProgram, "lightPosition"); fragin = cgGetNamedParameter(psSargeProgram, "fragin"); eyevector = cgGetNamedParameter(psSargeProgram, "eyevector"); CheckForCgError("sarge", "getting parameters"); textureLoader.LoadTextureFromDisk("assets/textures/shadermaps/sarge_normalmap.tga", &sargeNormalTexture); textureLoader.LoadTextureFromDisk("assets/textures/shadermaps/sarge_colormap.tga", &sargeColorTexture); //textureLoader.LoadTextureFromDisk("assets/textures/weapon/fire1.tga", &sargeColorTexture); normalmap = cgGetNamedParameter(psSargeProgram, "normalmap"); cgGLSetTextureParameter(normalmap, sargeNormalTexture.TextureID); decalmap = cgGetNamedParameter(psSargeProgram, "decalmap"); cgGLSetTextureParameter(decalmap, sargeColorTexture.TextureID); CheckForCgError("sarge", "setting decal 2D texture"); /* decalmap = cgGetNamedParameter(psSargeProgram, "decalmap"); cgGLSetTextureParameter(text1, sargeColorTexture.TextureID); CheckForCgError("sarge", "setting decal 2D texture"); */ mMeshObject.Scale(1.6f); }
static bool gl_cg_init(const char *path) { #ifdef HAVE_CG_RUNTIME_COMPILER cgRTCgcInit(); #endif if (!cgCtx) cgCtx = cgCreateContext(); if (cgCtx == NULL) { RARCH_ERR("Failed to create Cg context\n"); return false; } #ifdef RARCH_CG_DEBUG cgGLSetDebugMode(CG_TRUE); cgSetErrorHandler(cg_error_handler, NULL); #endif cgFProf = cgGLGetLatestProfile(CG_GL_FRAGMENT); cgVProf = cgGLGetLatestProfile(CG_GL_VERTEX); if (cgFProf == CG_PROFILE_UNKNOWN || cgVProf == CG_PROFILE_UNKNOWN) { RARCH_ERR("Invalid profile type\n"); return false; } #ifndef HAVE_RGL RARCH_LOG("[Cg]: Vertex profile: %s\n", cgGetProfileString(cgVProf)); RARCH_LOG("[Cg]: Fragment profile: %s\n", cgGetProfileString(cgFProf)); #endif cgGLSetOptimalOptions(cgFProf); cgGLSetOptimalOptions(cgVProf); cgGLEnableProfile(cgFProf); cgGLEnableProfile(cgVProf); if (path && strcmp(path_get_extension(path), "cgp") == 0) { if (!load_preset(path)) return false; } else { if (!load_plain(path)) return false; } prg[0].mvp = cgGetNamedParameter(prg[0].vprg, "modelViewProj"); for (unsigned i = 1; i <= cg_shader->passes; i++) set_program_attributes(i); // If we aren't using last pass non-FBO shader, // this shader will be assumed to be "fixed-function". // Just use prg[0] for that pass, which will be // pass-through. prg[cg_shader->passes + 1] = prg[0]; // No need to apply Android hack in Cg. prg[GL_SHADER_STOCK_BLEND] = prg[0]; cgGLBindProgram(prg[1].fprg); cgGLBindProgram(prg[1].vprg); cg_active = true; return true; }
void Glow::Load() { this->cg_blur_steps = 4; this->cg_enagled_glow = 1; this->glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB"); unsigned char* pBlankTex = new unsigned char[pWinWidth*pWinHeight * 3]; memset(pBlankTex, 0, pWinWidth*pWinHeight * 3); glGenTextures(1, &this->g_uiSceneTex); glBindTexture(GL_TEXTURE_RECTANGLE_NV, this->g_uiSceneTex); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGB8, pWinWidth, pWinHeight, 0, GL_RGB8, GL_UNSIGNED_BYTE, pBlankTex); glGenTextures(1, &this->g_uiBlurTex); glBindTexture(GL_TEXTURE_RECTANGLE_NV, this->g_uiBlurTex); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGB8, pWinWidth / 2, pWinHeight / 2, 0, GL_RGB8, GL_UNSIGNED_BYTE, pBlankTex); delete[] pBlankTex; this->g_bInitialised = true; this->g_cgContext = cgCreateContext(); if (!this->g_cgContext) { MessageBox(NULL, "Couldn't make Cg context", NULL, NULL); return; } this->g_cgVertProfile = cgGLGetLatestProfile(CG_GL_VERTEX); if (this->g_cgVertProfile == CG_PROFILE_UNKNOWN) { MessageBox(NULL, "Couldn't fetch valid VP profile", NULL, NULL); return; } cgGLSetOptimalOptions(this->g_cgVertProfile); if (!LoadProgram(&this->g_cgVP_GlowDarken, this->g_cgVertProfile, "Data/Custom/Shader/glow_darken_vp.cg")) return; if (!LoadProgram(&this->g_cgVP_GlowBlur, this->g_cgVertProfile, "Data/Custom/Shader/glow_blur_vp.cg")) return; if (!LoadProgram(&this->g_cgVP_GlowCombine, this->g_cgVertProfile, "Data/Custom/Shader/glow_combine_vp.cg")) return; this->g_cgpVP0_ModelViewMatrix = cgGetNamedParameter(this->g_cgVP_GlowDarken, "ModelViewProj"); this->g_cgpVP1_ModelViewMatrix = cgGetNamedParameter(this->g_cgVP_GlowBlur, "ModelViewProj"); this->g_cgpVP1_XOffset = cgGetNamedParameter(this->g_cgVP_GlowBlur, "XOffset"); this->g_cgpVP1_YOffset = cgGetNamedParameter(this->g_cgVP_GlowBlur, "YOffset"); this->g_cgpVP2_ModelViewMatrix = cgGetNamedParameter(this->g_cgVP_GlowCombine, "ModelViewProj"); this->g_cgFragProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); if (this->g_cgFragProfile == CG_PROFILE_UNKNOWN) { MessageBox(NULL, "Couldn't fetch valid FP profile", NULL, NULL); return; } cgGLSetOptimalOptions(this->g_cgFragProfile); if (!LoadProgram(&this->g_cgFP_GlowDarken, this->g_cgFragProfile, "Data/Custom/Shader/glow_darken_fp.cg")) return; if (!LoadProgram(&this->g_cgFP_GlowBlur, this->g_cgFragProfile, "Data/Custom/Shader/glow_blur_fp.cg")) return; if (!LoadProgram(&this->g_cgFP_GlowCombine, this->g_cgFragProfile, "Data/Custom/Shader/glow_combine_fp.cg")) return; }