/** * @file pipeline.h * @brief Rendering pipeline definitions * * $LicenseInfo:firstyear=2001&license=viewergpl$ * * Copyright (c) 2001-2009, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at * http://secondlifegrid.net/programs/open_source/licensing/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, * and agree to abide by those obligations. * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ #ifndef LL_PIPELINE_H #define LL_PIPELINE_H #include "llcamera.h" #include "llerror.h" #include "lldarrayptr.h" #include "lldqueueptr.h" #include "lldrawpool.h" #include "llspatialpartition.h" #include "m4math.h" #include "llpointer.h" #include "lldrawpool.h" #include "llgl.h" #include "lldrawable.h" #include "llrendertarget.h" class LLViewerTexture; class LLEdge; class LLFace; class LLViewerObject; class LLAgent; class LLDisplayPrimitive; class LLTextureEntry; class LLRenderFunc; class LLCubeMap; class LLCullResult; class LLVOAvatar; class LLGLSLShader; class LLCurlRequest; class LLMeshResponder; typedef enum e_avatar_skinning_method { SKIN_METHOD_SOFTWARE, SKIN_METHOD_VERTEX_PROGRAM } EAvatarSkinningMethod; BOOL compute_min_max(LLMatrix4& box, LLVector2& min, LLVector2& max); // Shouldn't be defined here! bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& origin, const LLVector3& dir, LLVector3 &coord, F32 epsilon = 0); BOOL setup_hud_matrices(); // use whole screen to render hud BOOL setup_hud_matrices(const LLRect& screen_region); // specify portion of screen (in pixels) to render hud attachments from (for picking) glh::matrix4f glh_copy_matrix(GLdouble* src); glh::matrix4f glh_get_current_modelview(); void glh_set_current_modelview(const glh::matrix4f& mat); glh::matrix4f glh_get_current_projection(); void glh_set_current_projection(glh::matrix4f& mat); glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar); glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar); glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up); extern LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY; extern LLFastTimer::DeclareTimer FTM_RENDER_GRASS; extern LLFastTimer::DeclareTimer FTM_RENDER_INVISIBLE; extern LLFastTimer::DeclareTimer FTM_RENDER_OCCLUSION; extern LLFastTimer::DeclareTimer FTM_RENDER_SHINY; extern LLFastTimer::DeclareTimer FTM_RENDER_SIMPLE; extern LLFastTimer::DeclareTimer FTM_RENDER_TERRAIN; extern LLFastTimer::DeclareTimer FTM_RENDER_TREES; extern LLFastTimer::DeclareTimer FTM_RENDER_UI; extern LLFastTimer::DeclareTimer FTM_RENDER_WATER; extern LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY; extern LLFastTimer::DeclareTimer FTM_RENDER_ALPHA; extern LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS; extern LLFastTimer::DeclareTimer FTM_RENDER_BUMP; extern LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT; extern LLFastTimer::DeclareTimer FTM_RENDER_GLOW; extern LLFastTimer::DeclareTimer FTM_STATESORT; extern LLFastTimer::DeclareTimer FTM_PIPELINE; extern LLFastTimer::DeclareTimer FTM_CLIENT_COPY; class LLPipeline { public: LLPipeline(); ~LLPipeline(); void destroyGL(); void restoreGL(); void resetVertexBuffers(); void resizeScreenTexture(); void releaseGLBuffers(); void createGLBuffers(); void allocateScreenBuffer(U32 resX, U32 resY); void resetVertexBuffers(LLDrawable* drawable); void setUseVBO(BOOL use_vbo); void generateImpostor(LLVOAvatar* avatar); void bindScreenToTexture(); void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0); void init(); void cleanup(); BOOL isInit() { return mInitialized; }; /// @brief Get a draw pool from pool type (POOL_SIMPLE, POOL_MEDIA) and texture. /// @return Draw pool, or NULL if not found. LLDrawPool *findPool(const U32 pool_type, LLViewerTexture *tex0 = NULL); /// @brief Get a draw pool for faces of the appropriate type and texture. Create if necessary. /// @return Always returns a draw pool. LLDrawPool *getPool(const U32 pool_type, LLViewerTexture *tex0 = NULL); /// @brief Figures out draw pool type from texture entry. Creates pool if necessary. static LLDrawPool* getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* te_image); static U32 getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep); void addPool(LLDrawPool *poolp); // Only to be used by LLDrawPool classes for splitting pools! void removePool( LLDrawPool* poolp ); void allocDrawable(LLViewerObject *obj); void unlinkDrawable(LLDrawable*); // Object related methods void markVisible(LLDrawable *drawablep, LLCamera& camera); void markOccluder(LLSpatialGroup* group); void doOcclusion(LLCamera& camera); void markNotCulled(LLSpatialGroup* group, LLCamera &camera); void markMoved(LLDrawable *drawablep, BOOL damped_motion = FALSE); void markShift(LLDrawable *drawablep); void markTextured(LLDrawable *drawablep); void markGLRebuild(LLGLUpdate* glu); void markRebuild(LLSpatialGroup* group, BOOL priority = FALSE); void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE); //get the object between start and end that's closest to start. LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, BOOL pick_transparent, S32* face_hit, // return the face hit LLVector3* intersection = NULL, // return the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point LLVector3* normal = NULL, // return the surface normal at the intersection point LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point ); LLViewerObject* lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end, BOOL pick_transparent, S32* face_hit, // return the face hit LLVector3* intersection = NULL, // return the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point LLVector3* normal = NULL, // return the surface normal at the intersection point LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point ); // Something about these textures has changed. Dirty them. void dirtyPoolObjectTextures(const std::set& textures); void resetDrawOrders(); U32 addObject(LLViewerObject *obj); void enableShadows(const BOOL enable_shadows); // void setLocalLighting(const BOOL local_lighting); // BOOL isLocalLightingEnabled() const; S32 setLightingDetail(S32 level); S32 getLightingDetail() const { return mLightingDetail; } S32 getMaxLightingDetail() const; void setUseVertexShaders(BOOL use_shaders); BOOL getUseVertexShaders() const { return mVertexShadersEnabled; } BOOL canUseVertexShaders(); BOOL canUseWindLightShaders() const; BOOL canUseWindLightShadersOnObjects() const; // phases void resetFrameStats(); void updateMoveDampedAsync(LLDrawable* drawablep); void updateMoveNormalAsync(LLDrawable* drawablep); void updateMovedList(LLDrawable::drawable_vector_t& move_list); void updateMove(); BOOL visibleObjectsInFrustum(LLCamera& camera); BOOL getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max); BOOL getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector& fp, LLVector3 light_dir = LLVector3(0,0,0)); void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane void createObjects(F32 max_dtime); void createObject(LLViewerObject* vobj); void updateGeom(F32 max_dtime); void updateGL(); void rebuildPriorityGroups(); void rebuildGroups(); //calculate pixel area of given box from vantage point of given camera static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); void stateSort(LLCamera& camera, LLCullResult& result); void stateSort(LLSpatialGroup* group, LLCamera& camera); void stateSort(LLSpatialBridge* bridge, LLCamera& camera); void stateSort(LLDrawable* drawablep, LLCamera& camera); void postSort(LLCamera& camera); void forAllVisibleDrawables(void (*func)(LLDrawable*)); void renderObjects(U32 type, U32 mask, BOOL texture = TRUE); void renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture); void grabReferences(LLCullResult& result); void renderGeom(LLCamera& camera, BOOL forceVBOUpdate = FALSE); void renderGeomDeferred(LLCamera& camera); void renderGeomPostDeferred(LLCamera& camera); void renderGeomShadow(LLCamera& camera); void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0, LLRenderTarget* gi_source = NULL, LLRenderTarget* last_gi_post = NULL, U32 noise_map = 0xFFFFFFFF); void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep); void unbindDeferredShader(LLGLSLShader& shader); void renderDeferredLighting(); void generateWaterReflection(LLCamera& camera); void generateSunShadow(LLCamera& camera); void generateHighlight(LLCamera& camera); void renderHighlight(const LLViewerObject* obj, F32 fade); void setHighlightObject(LLDrawable* obj) { mHighlightObject = obj; } void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, BOOL use_shader = TRUE, BOOL use_occlusion = TRUE); void generateGI(LLCamera& camera, LLVector3& lightDir, std::vector& vpc); void renderHighlights(); void renderDebug(); void renderForSelect(std::set& objects, BOOL render_transparent, const LLRect& screen_rect); void rebuildPools(); // Rebuild pools void findReferences(LLDrawable *drawablep); // Find the lists which have references to this object BOOL verify(); // Verify that all data in the pipeline is "correct" S32 getLightCount() const { return mLights.size(); } void calcNearbyLights(LLCamera& camera); void setupHWLights(LLDrawPool* pool); void setupAvatarLights(BOOL for_edit = FALSE); void enableLights(U32 mask); void enableLightsStatic(); void enableLightsDynamic(); void enableLightsAvatar(); void enableLightsAvatarEdit(const LLColor4& color); void enableLightsFullbright(const LLColor4& color); void disableLights(); void shiftObjects(const LLVector3 &offset); void setLight(LLDrawable *drawablep, BOOL is_light); BOOL hasRenderBatches(const U32 type) const; LLCullResult::drawinfo_list_t::iterator beginRenderMap(U32 type); LLCullResult::drawinfo_list_t::iterator endRenderMap(U32 type); LLCullResult::sg_list_t::iterator beginAlphaGroups(); LLCullResult::sg_list_t::iterator endAlphaGroups(); void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES); BOOL hasRenderType(const U32 type) const { return (type && (mRenderTypeMask & (1< mShadowFrustPoints[4]; LLVector4 mShadowError; LLVector4 mShadowFOV; LLVector3 mShadowFrustOrigin[4]; LLCamera mShadowCamera[8]; LLVector3 mShadowExtents[4][2]; glh::matrix4f mSunShadowMatrix[6]; glh::matrix4f mShadowModelview[6]; glh::matrix4f mShadowProjection[6]; glh::matrix4f mGIMatrix; glh::matrix4f mGIMatrixProj; glh::matrix4f mGIModelview; glh::matrix4f mGIProjection; glh::matrix4f mGINormalMatrix; glh::matrix4f mGIInvProj; LLVector2 mGIRange; F32 mGILightRadius; LLPointer mShadowSpotLight[2]; F32 mSpotLightFade[2]; LLPointer mTargetShadowSpotLight[2]; LLVector4 mSunClipPlanes; LLVector4 mSunOrthoClipPlanes; LLVector2 mScreenScale; //water reflection texture LLRenderTarget mWaterRef; //water distortion texture (refraction) LLRenderTarget mWaterDis; //texture for making the glow LLRenderTarget mGlow[3]; //noise map U32 mNoiseMap; U32 mTrueNoiseMap; U32 mLightFunc; LLColor4 mSunDiffuse; LLVector3 mSunDir; BOOL mInitialized; BOOL mVertexShadersEnabled; S32 mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed protected: U32 mRenderTypeMask; U32 mRenderDebugFeatureMask; U32 mRenderDebugMask; U32 mOldRenderDebugMask; ///////////////////////////////////////////// // // LLDrawable::drawable_vector_t mMovedList; LLDrawable::drawable_vector_t mMovedBridge; LLDrawable::drawable_vector_t mShiftList; ///////////////////////////////////////////// // // struct Light { Light(LLDrawable* ptr, F32 d, F32 f = 0.0f) : drawable(ptr), dist(d), fade(f) {} LLPointer drawable; F32 dist; F32 fade; struct compare { bool operator()(const Light& a, const Light& b) const { if ( a.dist < b.dist ) return true; else if ( a.dist > b.dist ) return false; else return a.drawable < b.drawable; } }; }; typedef std::set< Light, Light::compare > light_set_t; LLDrawable::drawable_set_t mLights; light_set_t mNearbyLights; // lights near camera LLColor4 mHWLightColors[8]; ///////////////////////////////////////////// // // Different queues of drawables being processed. // LLDrawable::drawable_list_t mBuildQ1; // priority LLDrawable::drawable_list_t mBuildQ2; // non-priority LLSpatialGroup::sg_list_t mGroupQ1; //priority LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority LLViewerObject::vobj_list_t mCreateQ; LLDrawable::drawable_set_t mRetexturedList; class HighlightItem { public: const LLPointer mItem; mutable F32 mFade; HighlightItem(LLDrawable* item) : mItem(item), mFade(0) { } bool operator<(const HighlightItem& rhs) const { return mItem < rhs.mItem; } bool operator==(const HighlightItem& rhs) const { return mItem == rhs.mItem; } void incrFade(F32 val) const { mFade = llclamp(mFade+val, 0.f, 1.f); } }; std::set mHighlightSet; LLPointer mHighlightObject; ////////////////////////////////////////////////// // // Draw pools are responsible for storing all rendered data, // and performing the actual rendering of objects. // struct compare_pools { bool operator()(const LLDrawPool* a, const LLDrawPool* b) const { if (!a) return true; else if (!b) return false; else { S32 atype = a->getType(); S32 btype = b->getType(); if (atype < btype) return true; else if (atype > btype) return false; else return a->getId() < b->getId(); } } }; typedef std::set pool_set_t; pool_set_t mPools; LLDrawPool* mLastRebuildPool; // For quick-lookups into mPools (mapped by texture pointer) std::map mTerrainPools; std::map mTreePools; LLDrawPool* mAlphaPool; LLDrawPool* mSkyPool; LLDrawPool* mTerrainPool; LLDrawPool* mWaterPool; LLDrawPool* mGroundPool; LLRenderPass* mSimplePool; LLRenderPass* mGrassPool; LLRenderPass* mFullbrightPool; LLDrawPool* mInvisiblePool; LLDrawPool* mGlowPool; LLDrawPool* mBumpPool; LLDrawPool* mWLSkyPool; // Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar public: std::vector mHighlightFaces; // highlight faces on physical objects protected: std::vector mSelectedFaces; typedef std::map > mesh_load_map; mesh_load_map mLoadingMeshes[4]; typedef std::list mesh_response_list; mesh_response_list mMeshResponseList; LLPointer mFaceSelectImagep; LLPointer mBloomImagep; LLPointer mBloomImage2p; U32 mLightMask; U32 mLightMovingMask; S32 mLightingDetail; static BOOL sRenderPhysicalBeacons; static BOOL sRenderScriptedTouchBeacons; static BOOL sRenderScriptedBeacons; static BOOL sRenderParticleBeacons; static BOOL sRenderSoundBeacons; public: static BOOL sRenderBeacons; static BOOL sRenderHighlight; }; void render_bbox(const LLVector3 &min, const LLVector3 &max); extern LLPipeline gPipeline; extern BOOL gRenderForSelect; extern BOOL gDebugPipeline; extern const LLMatrix4* gGLLastMatrix; #endif