/** * Function for creating and holding of shared context. * Generation and uploading of new textures over some period with sleep time. */ void AsyncFetcher::run() { EQASSERT( !_sharedContextWindow ); _sharedContextWindow = initSharedContextWindow( _wnd ); _outQueue.push( TextureId( )); // unlock pipe thread if( !_sharedContextWindow ) return; _objectManager = new ObjectManager( glewGetContext( )); EQINFO << "async fetcher initialized: " << _wnd << std::endl; int i = 0; bool running = true; co::base::sleep( 1000 ); // imitate loading of the first texture while( running ) { // generate new texture eq::util::Texture* tx = _objectManager->newEqTexture( ++i, GL_TEXTURE_2D ); tx->init( GL_RGBA8, 64, 64 ); int j = 0; co::base::RNG rng; for( int y = 0; y < 64; ++y ) { for( int x = 0; x < 64; ++x ) { const GLbyte rnd = rng.get< uint8_t >() % 127; const GLbyte val = (x / 8) % 2 == (y / 8) % 2 ? rnd : 0; _tmpTexture[ j++ ] = val; _tmpTexture[ j++ ] = val; _tmpTexture[ j++ ] = val; _tmpTexture[ j++ ] = val; } } tx->upload( 64, 64, _tmpTexture ); EQ_GL_CALL( glFinish( )); // add new texture to the pool _outQueue.push( TextureId( tx->getName( ), i )); // imitate hard work of loading something else co::base::sleep( rng.get< uint32_t >() % 5000u ); // clean unused textures int keyToDelete = 0; while( _inQueue.tryPop( keyToDelete )) { if( keyToDelete ) { EQWARN << "Deleting eq texture " << keyToDelete << std::endl; _objectManager->deleteEqTexture( keyToDelete ); } else running = false; } } deleteSharedContextWindow( _wnd, &_sharedContextWindow, &_objectManager ); }
void CDeco::CreateLightStrip (float x, float z, float width, float depth, float height, GLrgba color) { GLvertex p; quad_strip qs1; float u, v; qs1.index_list.push_back(0); qs1.index_list.push_back(1); qs1.index_list.push_back(3); qs1.index_list.push_back(2); _color = color; _use_alpha = true; _center = glVector (x + width / 2, height, z + depth / 2); if (width < depth) { u = 1.0f; v = (float)((int)(depth / width)); } else { v = 1.0f; u = (float)((int)(width / depth)); } _texture = TextureId (TEXTURE_LIGHT); p.position = glVector (x, height, z); p.uv = glVector (0.0f, 0.0f); _mesh->VertexAdd (p); p.position = glVector (x, height, z + depth); p.uv = glVector (0.0f, v); _mesh->VertexAdd (p); p.position = glVector (x + width, height, z + depth); p.uv = glVector (u, v); _mesh->VertexAdd (p); p.position = glVector (x + width, height, z); p.uv = glVector (u, 0.0f); _mesh->VertexAdd (p); _mesh->QuadStripAdd (qs1); _mesh->Compile (); }
void LightRender () { CLight* l; if (!EntityReady ()) return; if (!angles_done) { for (int size = 0; size < MAX_SIZE; size++) { for (int i = 0 ; i < 360; i++) { angles[size][i].x = cosf ((float)i * DEGREES_TO_RADIANS) * ((float)size + 0.5f); angles[size][i].y = sinf ((float)i * DEGREES_TO_RADIANS) * ((float)size + 0.5f); } } } glDepthMask (false); glEnable (GL_BLEND); glDisable (GL_CULL_FACE); glBlendFunc (GL_ONE, GL_ONE); glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_LIGHT)); glDisable (GL_CULL_FACE); glBegin (GL_QUADS); for (l = head; l; l = l->_next) l->Render (); glEnd (); glDepthMask (true); }
void CDeco::CreateRadioTower (GLvector pos, float height) { CLight* l; float offset; GLvertex v; fan f; for(int i=0; i<6; i++) f.index_list.push_back(i); offset = height / 15.0f; _center = pos; _use_alpha = true; //Radio tower v.position = glVector (_center.x, _center.y + height, _center.z); v.uv = glVector (0,1); _mesh->VertexAdd (v); v.position = glVector (_center.x - offset, _center.y, _center.z - offset); v.uv = glVector (1,0); _mesh->VertexAdd (v); v.position = glVector (_center.x + offset, _center.y, _center.z - offset); v.uv = glVector (0,0); _mesh->VertexAdd (v); v.position = glVector (_center.x + offset, _center.y, _center.z + offset); v.uv = glVector (1,0); _mesh->VertexAdd (v); v.position = glVector (_center.x - offset, _center.y, _center.z + offset); v.uv = glVector (0,0); _mesh->VertexAdd (v); v.position = glVector (_center.x - offset, _center.y, _center.z - offset); v.uv = glVector (1,0); _mesh->VertexAdd (v); _mesh->FanAdd (f); l = new CLight (glVector (_center.x, _center.y + height + 1.0f, _center.z), glRgba (255,192,160), 1); l->Blink (); _texture = TextureId (TEXTURE_LATTICE); }
unsigned TextureRandomBuilding (int index) { index = abs (index) % BUILDING_COUNT; return TextureId (TEXTURE_BUILDING1 + index); }
void CSky::Render () { GLvector angle, position; if (!TextureReady ()) return; glDepthMask (false); glPushAttrib (GL_POLYGON_BIT | GL_FOG_BIT); glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); glDisable (GL_CULL_FACE); glDisable (GL_FOG); glPushMatrix (); glLoadIdentity(); angle = CameraAngle (); position = CameraPosition (); glRotatef (angle.x, 1.0f, 0.0f, 0.0f); glRotatef (angle.y, 0.0f, 1.0f, 0.0f); glRotatef (angle.z, 0.0f, 0.0f, 1.0f); glTranslatef (0.0f, -position.y / 100.0f, 0.0f); glEnable (GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_SKY)); glCallList (m_list); glPopMatrix (); glPopAttrib (); glDepthMask (true); glEnable (GL_COLOR_MATERIAL); }
/** * Function for creating and holding of shared context. * Generation and uploading of new textures over some period with sleep time. */ void AsyncFetcher::run() { LBASSERT( _sharedWindow ); if( !_sharedWindow ) return; _sharedWindow->makeCurrent(); eq::util::ObjectManager objects( glewGetContext( )); lunchbox::Bufferb textureData( 64*64*4 ); LBINFO << "async fetcher initialized" << std::endl; bool running = true; lunchbox::sleep( 1000 ); // imitate loading of the first texture for( uint8_t* i = 0; running; ++i ) { // generate new texture eq::util::Texture* tx = objects.newEqTexture( i, GL_TEXTURE_2D ); tx->init( GL_RGBA8, 64, 64 ); int j = 0; lunchbox::RNG rng; for( int y = 0; y < 64; ++y ) { for( int x = 0; x < 64; ++x ) { const GLbyte rnd = rng.get< uint8_t >() % 127; const GLbyte val = (x / 8) % 2 == (y / 8) % 2 ? rnd : 0; textureData[ j++ ] = val; textureData[ j++ ] = val; textureData[ j++ ] = val; textureData[ j++ ] = val; } } tx->upload( 64, 64, textureData.getData( )); EQ_GL_CALL( glFinish( )); // add new texture to the pool _outQueue.push( TextureId( tx->getName(), i )); // imitate hard work of loading something else lunchbox::sleep( rng.get< uint32_t >() % 5000u ); // clean unused textures const void* keyToDelete = 0; while( _inQueue.tryPop( keyToDelete )) { if( keyToDelete ) { LBWARN << "Deleting eq texture " << keyToDelete << std::endl; objects.deleteEqTexture( keyToDelete ); } else running = false; } } objects.deleteAll(); }
void CDeco::CreateLightTrim (GLvector* chain, int count, float height, int seed, GLrgba color) { GLvertex p; GLvector to; GLvector out; int i; int index; int prev, next; float u, v1, v2; float row; quad_strip qs; _color = color; _center = glVector (0.0f, 0.0f, 0.0f); qs.index_list.reserve(count * 2 + 2); for (i = 0; i < count; i++) _center += chain[i]; _center /= (float)count; row = (float)(seed % TRIM_ROWS); v1 = row * TRIM_SIZE; v2 = (row + 1.0f) * TRIM_SIZE; index = 0; u = 0.0f; for (i = 0; i < count + 1; i++) { if (i) u += glVectorLength (chain[i % count] - p.position) * 0.1f; //Add the bottom point prev = i - 1; if (prev < 0) prev = count + prev; next = (i + 1) % count; to = glVectorNormalize (chain[next] - chain[prev]); out = glVectorCrossProduct (glVector (0.0f, 1.0f, 0.0f), to) * LOGO_OFFSET; p.position = chain[i % count] + out; p.uv = glVector (u, v2); _mesh->VertexAdd (p); qs.index_list.push_back(index++); //Top point p.position.y += height; p.uv = glVector (u, v1); _mesh->VertexAdd (p); qs.index_list.push_back(index++); } _mesh->QuadStripAdd (qs); _texture = TextureId (TEXTURE_TRIM); _mesh->Compile (); }
void CDeco::CreateLogo (GLvector2 start, GLvector2 end, float bottom, int seed, GLrgba color) { GLvertex p; quad_strip qs; float u1, u2, v1, v2; float top; float height, length; GLvector2 center2d; GLvector to; GLvector out; int logo_index; qs.index_list.push_back(0); qs.index_list.push_back(1); qs.index_list.push_back(3); qs.index_list.push_back(2); _use_alpha = true; _color = color; logo_index = seed % LOGO_ROWS; to = glVector (start.x, 0.0f, start.y) - glVector (end.x, 0.0f, end.y); to = glVectorNormalize (to); out = glVectorCrossProduct (glVector (0.0f, 1.0f, 0.0f), to) * LOGO_OFFSET; center2d = (start + end) / 2; _center = glVector (center2d.x, bottom, center2d.y); length = glVectorLength (start - end); height = (length / 8.0f) * 1.5f; top = bottom + height; u1 = 0.0f; u2 = 0.5f;//We actually only use the left half of the texture v1 = (float)logo_index / LOGO_ROWS; v2 = v1 + (1.0f / LOGO_ROWS); p.position = glVector (start.x, bottom, start.y) + out; p.uv = glVector (u1,v1); _mesh->VertexAdd (p); p.position = glVector (end.x, bottom, end.y) + out; p.uv = glVector (u2, v1); _mesh->VertexAdd (p); p.position = glVector (end.x, top, end.y) + out; p.uv = glVector (u2, v2); _mesh->VertexAdd (p); p.position = glVector (start.x, top, start.y) + out; p.uv = glVector (u1, v2); _mesh->VertexAdd (p); _mesh->QuadStripAdd (qs); _texture = TextureId (TEXTURE_LOGOS); }
void CarRender () { CCar* c; if (!angles_done) { for (int i = 0 ;i < 360; i++) { angles[i].x = cosf ((float)i * DEGREES_TO_RADIANS) * CAR_SIZE; angles[i].y = sinf ((float)i * DEGREES_TO_RADIANS) * CAR_SIZE; } } glDepthMask (false); glEnable (GL_BLEND); glDisable (GL_CULL_FACE); glBlendFunc (GL_ONE, GL_ONE); glBindTexture (GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_HEADLIGHT)); for (c = head; c; c = c->m_next) c->Render (); glDepthMask (true); }
void CTexture::DrawSky() { GLrgba color; float grey; float scale, inv_scale; int i, x, y; int width, height; int offset; int width_adjust; int height_adjust; color = WorldBloomColor(); grey = (color.red + color.green + color.blue) / 3.0f; //desaturate, slightly dim color = (color + glRgba(grey) * 2.0f) / 15.0f; glDisable(GL_BLEND); glBegin(GL_QUAD_STRIP); glColor3f(0, 0, 0); glVertex2i(0, _half); glVertex2i(_size, _half); glColor3fv(&color.red); glVertex2i(0, _size - 2); glVertex2i(_size, _size - 2); glEnd(); //Draw a bunch of little faux-buildings on the horizon. for (i = 0; i < _size; i += 5) drawrect(i, _size - RandomVal(8) - RandomVal(8) - RandomVal(8), i + RandomVal(9), _size, glRgba(0.0f)); //Draw the clouds for (i = _size - 30; i > 5; i -= 2) { x = RandomVal(_size); y = i; scale = 1.0f - ((float)y / (float)_size); width = RandomVal(_half / 2) + (int)((float)_half * scale) / 2; scale = 1.0f - (float)y / (float)_size; height = (int)((float)(width) * scale); height = MAX(height, 4); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_CULL_FACE); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, TextureId(TEXTURE_SOFT_CIRCLE)); glDepthMask(false); glBegin(GL_QUADS); for (offset = -_size; offset <= _size; offset += _size) { for (scale = 1.0f; scale > 0.0f; scale -= 0.25f) { inv_scale = 1.0f - (scale); if (scale < 0.4f) color = WorldBloomColor() * 0.1f; else color = glRgba(0.0f); color.alpha = 0.2f; glColor4fv(&color.red); width_adjust = (int)((float)width / 2.0f + (int)(inv_scale * ((float)width / 2.0f))); height_adjust = height + (int)(scale * (float)height * 0.99f); glTexCoord2f(0, 0); glVertex2i(offset + x - width_adjust, y + height - height_adjust); glTexCoord2f(0, 1); glVertex2i(offset + x - width_adjust, y + height); glTexCoord2f(1, 1); glVertex2i(offset + x + width_adjust, y + height); glTexCoord2f(1, 0); glVertex2i(offset + x + width_adjust, y + height - height_adjust); } } } glEnd(); }
static void do_effects (int type) { float hue1, hue2, hue3, hue4; GLrgba color; float fade; int radius; int x, y; int i; int bloom_radius; int bloom_step; fade = WorldFade (); bloom_radius = 15; bloom_step = bloom_radius / 3; if (!TextureReady ()) return; //Now change projection modes so we can render full-screen effects glMatrixMode (GL_PROJECTION); glPushMatrix (); glLoadIdentity (); glOrtho (0, render_width, render_height, 0, 0.1f, 2048); glMatrixMode (GL_MODELVIEW); glPushMatrix (); glLoadIdentity(); glTranslatef(0, 0, -1.0f); glDisable (GL_CULL_FACE); glDisable (GL_FOG); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //Render full-screen effects glBlendFunc (GL_ONE, GL_ONE); glEnable (GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glDepthMask (false); glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_BLOOM)); switch (type) { case EFFECT_DEBUG: glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_LOGOS)); glDisable (GL_BLEND); glBegin (GL_QUADS); glColor3f (1, 1, 1); glTexCoord2f (0, 0); glVertex2i (0, render_height / 4); glTexCoord2f (0, 1); glVertex2i (0, 0); glTexCoord2f (1, 1); glVertex2i (render_width / 4, 0); glTexCoord2f (1, 0); glVertex2i (render_width / 4, render_height / 4); glTexCoord2f (0, 0); glVertex2i (0, 512); glTexCoord2f (0, 1); glVertex2i (0, 0); glTexCoord2f (1, 1); glVertex2i (512, 0); glTexCoord2f (1, 0); glVertex2i (512, 512); glEnd (); break; case EFFECT_BLOOM_RADIAL: //Psychedelic bloom glEnable (GL_BLEND); glBegin (GL_QUADS); color = WorldBloomColor () * BLOOM_SCALING * 2; glColor3fv (&color.red); for (i = 0; i <= 100; i+=10) { glTexCoord2f (0, 0); glVertex2i (-i, i + render_height); glTexCoord2f (0, 1); glVertex2i (-i, -i); glTexCoord2f (1, 1); glVertex2i (i + render_width, -i); glTexCoord2f (1, 0); glVertex2i (i + render_width, i + render_height); } glEnd (); break; case EFFECT_COLOR_CYCLE: //Oooh. Pretty colors. Tint the scene according to screenspace. hue1 = (float)(GetTickCount () % COLOR_CYCLE_TIME) / COLOR_CYCLE_TIME; hue2 = (float)((GetTickCount () + COLOR_CYCLE) % COLOR_CYCLE_TIME) / COLOR_CYCLE_TIME; hue3 = (float)((GetTickCount () + COLOR_CYCLE * 2) % COLOR_CYCLE_TIME) / COLOR_CYCLE_TIME; hue4 = (float)((GetTickCount () + COLOR_CYCLE * 3) % COLOR_CYCLE_TIME) / COLOR_CYCLE_TIME; glBindTexture(GL_TEXTURE_2D, 0); glEnable (GL_BLEND); glBlendFunc (GL_ONE, GL_ONE); glBlendFunc (GL_DST_COLOR, GL_SRC_COLOR); glBegin (GL_QUADS); color = glRgbaFromHsl (hue1, 1.0f, 0.6f); glColor3fv (&color.red); glTexCoord2f (0, 0); glVertex2i (0, render_height); color = glRgbaFromHsl (hue2, 1.0f, 0.6f); glColor3fv (&color.red); glTexCoord2f (0, 1); glVertex2i (0, 0); color = glRgbaFromHsl (hue3, 1.0f, 0.6f); glColor3fv (&color.red); glTexCoord2f (1, 1); glVertex2i (render_width, 0); color = glRgbaFromHsl (hue4, 1.0f, 0.6f); glColor3fv (&color.red); glTexCoord2f (1, 0); glVertex2i (render_width, render_height); glEnd (); break; case EFFECT_BLOOM: //Simple bloom effect glBegin (GL_QUADS); color = WorldBloomColor () * BLOOM_SCALING; glColor3fv (&color.red); for (x = -bloom_radius; x <= bloom_radius; x += bloom_step) { for (y = -bloom_radius; y <= bloom_radius; y += bloom_step) { if (abs (x) == abs (y) && x) continue; glTexCoord2f (0, 0); glVertex2i (x, y + render_height); glTexCoord2f (0, 1); glVertex2i (x, y); glTexCoord2f (1, 1); glVertex2i (x + render_width, y); glTexCoord2f (1, 0); glVertex2i (x + render_width, y + render_height); } } glEnd (); break; case EFFECT_DEBUG_OVERBLOOM: //This will punish that uppity GPU. Good for testing low frame rate behavior. glBegin (GL_QUADS); color = WorldBloomColor () * 0.01f; glColor3fv (&color.red); for (x = -50; x <= 50; x+=5) { for (y = -50; y <= 50; y+=5) { glTexCoord2f (0, 0); glVertex2i (x, y + render_height); glTexCoord2f (0, 1); glVertex2i (x, y); glTexCoord2f (1, 1); glVertex2i (x + render_width, y); glTexCoord2f (1, 0); glVertex2i (x + render_width, y + render_height); } } glEnd (); break; } //Do the fade to / from darkness used to hide scene transitions if (LOADING_SCREEN) { if (fade > 0.0f) { glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable (GL_BLEND); glDisable (GL_TEXTURE_2D); glColor4f (0, 0, 0, fade); glBegin (GL_QUADS); glVertex2i (0, 0); glVertex2i (0, render_height); glVertex2i (render_width, render_height); glVertex2i (render_width, 0); glEnd (); } if (TextureReady () && !EntityReady () && fade != 0.0f) { radius = render_width / 16; do_progress ((float)render_width / 2, (float)render_height / 2, (float)radius, fade, EntityProgress ()); RenderPrint (render_width / 2 - LOGO_PIXELS, render_height / 2 + LOGO_PIXELS, 0, glRgba (0.5f), "%1.2f%%", EntityProgress () * 100.0f); RenderPrint (1, "%s v%d.%d.%03d", APP_TITLE, VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION); } } glPopMatrix (); glMatrixMode (GL_PROJECTION); glPopMatrix (); glMatrixMode (GL_MODELVIEW); glEnable(GL_DEPTH_TEST); }
PostShaderStage::RenderPassData::RenderPassData(const std::string& VertexProgram, const std::string& FragmentProgram, bool isLastPass, UInt32 Index, Int32 iPixelWidth, Int32 iPixelHeight, PostShaderStageData *StageData, const Vec2f& FBOSize, TextureObjChunk* const SceneColorTex, TextureObjChunk* const SceneDepthTex, const RenderPassVector& Passes, FrameBufferObject* const SceneFBO) : _IsLassPass(isLastPass), _Index(Index), _FBOSize(FBOSize) { //If this pass is not the last if(!_IsLassPass) { _FBO = FrameBufferObject::createLocal(); _OutputTexture = TextureObjChunk::createLocal(); TextureEnvChunkUnrecPtr pTexEnv = TextureEnvChunk::createLocal(); ImageUnrecPtr pImg = Image ::createLocal(); pImg->set(Image::OSG_RGB_PF, static_cast<Real32>(iPixelWidth) * _FBOSize.x() , static_cast<Real32>(iPixelHeight) * _FBOSize.y(), 1, 1, 1, 0.0, 0, Image::OSG_UINT8_IMAGEDATA, false); _OutputTexture ->setImage (pImg ); _OutputTexture ->setMinFilter (GL_LINEAR ); _OutputTexture ->setMagFilter (GL_LINEAR ); _OutputTexture ->setWrapS (GL_CLAMP_TO_EDGE ); _OutputTexture ->setWrapT (GL_CLAMP_TO_EDGE ); _OutputTexture ->setInternalFormat(GL_RGB ); pTexEnv->setEnvMode (GL_REPLACE ); TextureBufferUnrecPtr pTexBuffer = TextureBuffer::createLocal(); pTexBuffer->setTexture(_OutputTexture); _FBO->setSize(static_cast<Real32>(iPixelWidth) * _FBOSize.x(), static_cast<Real32>(iPixelHeight) * _FBOSize.y()); _FBO->setColorAttachment(pTexBuffer, 0); _FBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT); StageData->pushToRenderTargets(_FBO); OSG_ASSERT(StageData->getMFRenderTargets()->size() == _Index+1); } else { _FBO = SceneFBO; } //Update the flags on what uniforms are present _ShaderHasSceneColorTex = ((FragmentProgram.find(PostShaderStage::ShaderSceneColorTexName) != std::string::npos) || (VertexProgram.find(PostShaderStage::ShaderSceneColorTexName) != std::string::npos)); _ShaderHasSceneDepthTex = ((FragmentProgram.find(PostShaderStage::ShaderSceneDepthTexName) != std::string::npos) || (VertexProgram.find(PostShaderStage::ShaderSceneDepthTexName) != std::string::npos)); _ShaderHasFBOWidth = ((FragmentProgram.find(PostShaderStage::ShaderFBOWidthName) != std::string::npos) || (VertexProgram.find(PostShaderStage::ShaderFBOWidthName) != std::string::npos)); _ShaderHasFBOHeight = ((FragmentProgram.find(PostShaderStage::ShaderFBOHeightName) != std::string::npos) || (VertexProgram.find(PostShaderStage::ShaderFBOHeightName) != std::string::npos)); _ShaderHasCameraNear = ((FragmentProgram.find(PostShaderStage::ShaderCameraNearName) != std::string::npos) || (VertexProgram.find(PostShaderStage::ShaderCameraNearName) != std::string::npos)); _ShaderHasCameraFar = ((FragmentProgram.find(PostShaderStage::ShaderCameraFarName) != std::string::npos) || (VertexProgram.find(PostShaderStage::ShaderCameraFarName) != std::string::npos)); //Create the material used by this pass ChunkMaterialUnrecPtr pPostShaderMat = ChunkMaterial ::createLocal(); UInt16 TextureId(0); _Shader = SimpleSHLChunk::createLocal(); TextureEnvChunkUnrecPtr pGenericTexEnv = TextureEnvChunk::createLocal(); pGenericTexEnv->setEnvMode(GL_REPLACE); //Scene Color Texture if(_ShaderHasSceneColorTex) { pPostShaderMat->addChunk(SceneColorTex, TextureId); pPostShaderMat->addChunk(pGenericTexEnv, TextureId); _Shader->addUniformVariable(PostShaderStage::ShaderSceneColorTexName.c_str(), TextureId); ++TextureId; } //Scene Depth Texture if(_ShaderHasSceneDepthTex) { pPostShaderMat->addChunk(SceneDepthTex, TextureId); pPostShaderMat->addChunk(pGenericTexEnv, TextureId); _Shader->addUniformVariable(PostShaderStage::ShaderSceneDepthTexName.c_str(), TextureId); ++TextureId; } _HeightRefs.clear(); _WidthRefs.clear(); //Preceding passes variables std::string VariableName; for(RenderPassVector::const_iterator PassItor(Passes.begin()) ; PassItor != Passes.end() ; ++PassItor) { VariableName = (*PassItor)->getOutputTextureName(); if((FragmentProgram.find(VariableName) != std::string::npos) || (VertexProgram.find(VariableName) != std::string::npos)) { pPostShaderMat->addChunk((*PassItor)->getOutputTexture(), TextureId); pPostShaderMat->addChunk(pGenericTexEnv, TextureId); _Shader->addUniformVariable(VariableName.c_str(), TextureId); ++TextureId; } VariableName = (*PassItor)->getWidthName(); if((FragmentProgram.find(VariableName) != std::string::npos) || (VertexProgram.find(VariableName) != std::string::npos)) { _Shader->addUniformVariable<Real32>(VariableName.c_str(), (*PassItor)->getOutputTexture()->getImage()->getWidth()); _WidthRefs.push_back((*PassItor)->getIndex()); } VariableName = (*PassItor)->getHeightName(); if((FragmentProgram.find(VariableName) != std::string::npos) || (VertexProgram.find(VariableName) != std::string::npos)) { _Shader->addUniformVariable<Real32>(VariableName.c_str(), (*PassItor)->getOutputTexture()->getImage()->getHeight()); _HeightRefs.push_back((*PassItor)->getIndex()); } } MaterialChunkUnrecPtr pMatChunk = MaterialChunk::createLocal(); pMatChunk->setLit(false); pPostShaderMat->addChunk(pMatChunk); _Shader->setVertexProgram(VertexProgram); _Shader->setFragmentProgram(FragmentProgram); //Add the uniform parameters _Shader->addUniformVariable(ShaderFBOWidthName.c_str(), 0.0f); _Shader->addUniformVariable(ShaderFBOHeightName.c_str(), 0.0f); _Shader->addUniformVariable(ShaderCameraNearName.c_str(), 0.0f); _Shader->addUniformVariable(ShaderCameraFarName.c_str(), 1.0f); pPostShaderMat->addChunk(_Shader, 0); StageData->pushToShaderMaterials(pPostShaderMat); OSG_ASSERT(StageData->getMFShaderMaterials()->size() == _Index+1); }