//----------------------------------------------------------------------------- // render() //----------------------------------------------------------------------------- BOOL LLImagePreviewSculpted::render() { mNeedsUpdate = FALSE; LLGLSUIDefault def; LLGLDisable no_blend(GL_BLEND); LLGLEnable cull(GL_CULL_FACE); LLGLDepthTest depth(GL_TRUE); glMatrixMode(GL_PROJECTION); gGL.pushMatrix(); glLoadIdentity(); glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); gGL.pushMatrix(); glLoadIdentity(); gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); gl_rect_2d_simple( mWidth, mHeight ); glMatrixMode(GL_PROJECTION); gGL.popMatrix(); glMatrixMode(GL_MODELVIEW); gGL.popMatrix(); glClear(GL_DEPTH_BUFFER_BIT); LLVector3 target_pos(0, 0, 0); LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * LLQuaternion(mCameraYaw, LLVector3::z_axis); LLQuaternion av_rot = camera_rot; LLViewerCamera::getInstance()->setOriginAndLookAt( target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera LLVector3::z_axis, // up target_pos + (mCameraOffset * av_rot) ); // point of interest stop_glerror(); LLViewerCamera::getInstance()->setAspect((F32) mWidth / mHeight); LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE); const LLVolumeFace &vf = mVolume->getVolumeFace(0); U32 num_indices = vf.mIndices.size(); mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL); gPipeline.enableLightsAvatar(); gGL.pushMatrix(); const F32 SCALE = 1.25f; gGL.scalef(SCALE, SCALE, SCALE); const F32 BRIGHTNESS = 0.9f; gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0); gGL.popMatrix(); return TRUE; }
// for low end hardware void LLDrawPoolWater::renderOpaqueLegacyWater() { LLVOSky *voskyp = gSky.mVOSkyp; stop_glerror(); // Depth sorting and write to depth buffer // since this is opaque, we should see nothing // behind the water. No blending because // of no transparency. And no face culling so // that the underside of the water is also opaque. LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); LLGLDisable no_cull(GL_CULL_FACE); LLGLDisable no_blend(GL_BLEND); gPipeline.disableLights(); mOpaqueWaterImagep->addTextureStats(1024.f*1024.f); // Activate the texture binding and bind one // texture since all images will have the same texture gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->bind(mOpaqueWaterImagep); // Automatically generate texture coords for water texture glEnable(GL_TEXTURE_GEN_S); //texture unit 0 glEnable(GL_TEXTURE_GEN_T); //texture unit 0 glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); // Use the fact that we know all water faces are the same size // to save some computation // Slowly move texture coordinates over time so the watter appears // to be moving. F32 movement_period_secs = 50.f; F32 offset = fmod(gFrameTimeSeconds, movement_period_secs); if (movement_period_secs != 0) { offset /= movement_period_secs; } else { offset = 0; } F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset }; F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset }; glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1); glColor3f(1.f, 1.f, 1.f); for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) { LLFace *face = *iter; if (voskyp->isReflFace(face)) { continue; } face->renderIndexed(); } stop_glerror(); // Reset the settings back to expected values glDisable(GL_TEXTURE_GEN_S); //texture unit 0 glDisable(GL_TEXTURE_GEN_T); //texture unit 0 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); }
//----------------------------------------------------------------------------- // update() //----------------------------------------------------------------------------- BOOL LLImagePreviewAvatar::render() { mNeedsUpdate = FALSE; LLVOAvatar* avatarp = mDummyAvatar; glMatrixMode(GL_PROJECTION); gGL.pushMatrix(); glLoadIdentity(); glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); gGL.pushMatrix(); glLoadIdentity(); LLGLSUIDefault def; gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); gl_rect_2d_simple( mWidth, mHeight ); glMatrixMode(GL_PROJECTION); gGL.popMatrix(); glMatrixMode(GL_MODELVIEW); gGL.popMatrix(); gGL.flush(); LLVector3 target_pos = mTargetJoint->getWorldPosition(); LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * LLQuaternion(mCameraYaw, LLVector3::z_axis); LLQuaternion av_rot = avatarp->mPelvisp->getWorldRotation() * camera_rot; LLViewerCamera::getInstance()->setOriginAndLookAt( target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera LLVector3::z_axis, // up target_pos + (mCameraOffset * av_rot) ); // point of interest stop_glerror(); LLViewerCamera::getInstance()->setAspect((F32)mWidth / mHeight); LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE); LLVertexBuffer::unbind(); avatarp->updateLOD(); if (avatarp->mDrawable.notNull()) { LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); // make sure alpha=0 shows avatar material color LLGLDisable no_blend(GL_BLEND); LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool(); avatarPoolp->renderAvatars(avatarp); // renders only one avatar } gGL.color4f(1,1,1,1); return TRUE; }
// for low end hardware void LLDrawPoolWater::renderOpaqueLegacyWater() { LLVOSky *voskyp = gSky.mVOSkyp; LLGLSLShader* shader = NULL; if (LLGLSLShader::sNoFixedFunction) { if (LLPipeline::sUnderWaterRender) { shader = &gObjectSimpleNonIndexedTexGenWaterProgram; } else { shader = &gObjectSimpleNonIndexedTexGenProgram; } shader->bind(); } stop_glerror(); // Depth sorting and write to depth buffer // since this is opaque, we should see nothing // behind the water. No blending because // of no transparency. And no face culling so // that the underside of the water is also opaque. LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); LLGLDisable no_cull(GL_CULL_FACE); LLGLDisable no_blend(GL_BLEND); gPipeline.disableLights(); //Singu note: This is a hack around bizarre opensim behavior. The opaque water texture we get is pure white and only has one channel. // This behavior is clearly incorrect, so we try to detect that case, purge it from the cache, and try to re-fetch the texture. // If the re-fetched texture is still invalid, or doesn't exist, we use transparent water, which is fine since alphablend is unset. // The current logic for refetching is crude here, and probably wont work if, say, a prim were to also have the texture for some reason, // however it works well enough otherwise, and is much cleaner than diving into LLTextureList, LLViewerFetchedTexture, and LLViewerTexture. // Perhaps a proper reload mechanism could be done if we ever add user-level texture reloading, but until then it's not a huge priority. // Failing to fully refetch will just give us the same invalid texture we started with, which will result in the fallback texture being used. if(mOpaqueWaterImagep != mWaterImagep) { if(mOpaqueWaterImagep->isMissingAsset()) { mOpaqueWaterImagep = mWaterImagep; } else if(mOpaqueWaterImagep->hasGLTexture() && mOpaqueWaterImagep->getComponents() < 3) { LLAppViewer::getTextureCache()->removeFromCache(mOpaqueWaterImagep->getID()); static bool sRefetch = true; if(sRefetch) { sRefetch = false; ((LLViewerFetchedTexture*)mOpaqueWaterImagep.get())->forceRefetch(); } else mOpaqueWaterImagep = mWaterImagep; } } mOpaqueWaterImagep->addTextureStats(1024.f*1024.f); // Activate the texture binding and bind one // texture since all images will have the same texture gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->bind(mOpaqueWaterImagep); // Automatically generate texture coords for water texture if (!shader) { glEnable(GL_TEXTURE_GEN_S); //texture unit 0 glEnable(GL_TEXTURE_GEN_T); //texture unit 0 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); } // Use the fact that we know all water faces are the same size // to save some computation // Slowly move texture coordinates over time so the water appears // to be moving. F32 movement_period_secs = 50.f; static const LLCachedControl<bool> freeze_time("FreezeTime",false); static F32 frame_time; if (!freeze_time) frame_time = gFrameTimeSeconds; F32 offset = fmod(frame_time, movement_period_secs); if (movement_period_secs != 0) { offset /= movement_period_secs; } else { offset = 0; } F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset }; F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset }; if (!shader) { glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1); } else { shader->uniform4fv("object_plane_s", 1, tp0); shader->uniform4fv("object_plane_t", 1, tp1); } gGL.diffuseColor3f(1.f, 1.f, 1.f); for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) { LLFace *face = *iter; if (voskyp->isReflFace(face)) { continue; } face->renderIndexed(); } stop_glerror(); if (!shader) { // Reset the settings back to expected values glDisable(GL_TEXTURE_GEN_S); //texture unit 0 glDisable(GL_TEXTURE_GEN_T); //texture unit 0 } gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); }