diff options
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/llimagegl.cpp | 93 | ||||
-rw-r--r-- | indra/llrender/llimagegl.h | 2 | ||||
-rw-r--r-- | indra/llrender/llrendertarget.h | 2 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 176 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.h | 14 |
5 files changed, 252 insertions, 35 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 2a8424a09b..d5ad38dff3 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -128,10 +128,16 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat) void LLImageGL::bindExternalTexture(LLGLuint gl_name, S32 stage, LLGLenum bind_target ) { gGL.flush(); - glActiveTextureARB(GL_TEXTURE0_ARB + stage); - glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); + if (stage > 0) + { + glActiveTextureARB(GL_TEXTURE0_ARB + stage); + } glBindTexture(bind_target, gl_name); sCurrentBoundTextures[stage] = gl_name; + if (stage > 0) + { + glActiveTextureARB(GL_TEXTURE0_ARB); + } } // static @@ -141,9 +147,16 @@ void LLImageGL::unbindTexture(S32 stage, LLGLenum bind_target) if (stage >= 0) { gGL.flush(); - glActiveTextureARB(GL_TEXTURE0_ARB + stage); - glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); - glBindTexture(bind_target, 0); + if (stage > 0) + { + glActiveTextureARB(GL_TEXTURE0_ARB + stage); + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTextureARB(GL_TEXTURE0_ARB); + } + else + { + glBindTexture(GL_TEXTURE_2D, 0); + } sCurrentBoundTextures[stage] = 0; } } @@ -151,15 +164,7 @@ void LLImageGL::unbindTexture(S32 stage, LLGLenum bind_target) // static (duplicated for speed and to avoid GL_TEXTURE_2D default argument which requires GL header dependency) void LLImageGL::unbindTexture(S32 stage) { - // LLGLSLShader can return -1 - if (stage >= 0) - { - gGL.flush(); - glActiveTextureARB(GL_TEXTURE0_ARB + stage); - glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); - glBindTexture(GL_TEXTURE_2D, 0); - sCurrentBoundTextures[stage] = 0; - } + unbindTexture(stage, GL_TEXTURE_2D); } // static @@ -419,8 +424,6 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const } - glActiveTextureARB(GL_TEXTURE0_ARB + stage); - if (sCurrentBoundTextures[stage] && sCurrentBoundTextures[stage] == mTexName) { // already set! @@ -434,10 +437,20 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const #endif gGL.flush(); + if (stage > 0) + { + glActiveTextureARB(GL_TEXTURE0_ARB + stage); + } + glBindTexture(mBindTarget, mTexName); sCurrentBoundTextures[stage] = mTexName; sBindCount++; + if (stage > 0) + { + glActiveTextureARB(GL_TEXTURE0_ARB); + } + if (mLastBindTime != sLastFrameTime) { // we haven't accounted for this texture yet this frame @@ -451,7 +464,15 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const else { gGL.flush(); + if (stage > 0) + { + glActiveTextureARB(GL_TEXTURE0_ARB+stage); + } glBindTexture(mBindTarget, 0); + if (stage > 0) + { + glActiveTextureARB(GL_TEXTURE0_ARB+stage); + } sCurrentBoundTextures[stage] = 0; return FALSE; } @@ -594,18 +615,25 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) S32 w = width, h = height; const U8* prev_mip_data = 0; const U8* cur_mip_data = 0; + S32 prev_mip_size = 0; + S32 cur_mip_size = 0; for (int m=0; m<nummips; m++) { if (m==0) { cur_mip_data = data_in; + cur_mip_size = width * height * mComponents; } else { S32 bytes = w * h * mComponents; + llassert(prev_mip_data); + llassert(prev_mip_size == bytes); U8* new_data = new U8[bytes]; + llassert_always(new_data); LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents); cur_mip_data = new_data; + cur_mip_size = bytes; } llassert(w > 0 && h > 0 && cur_mip_data); { @@ -630,12 +658,14 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) delete[] prev_mip_data; } prev_mip_data = cur_mip_data; + prev_mip_size = cur_mip_size; w >>= 1; h >>= 1; } if (prev_mip_data && prev_mip_data != data_in) { delete[] prev_mip_data; + prev_mip_data = NULL; } } } @@ -985,6 +1015,21 @@ BOOL LLImageGL::setDiscardLevel(S32 discard_level) } } +BOOL LLImageGL::isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) +{ + assert_glerror(); + S32 gl_discard = discard_level - mCurrentDiscardLevel; + LLGLint glwidth = 0; + glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_WIDTH, (GLint*)&glwidth); + LLGLint glheight = 0; + glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_HEIGHT, (GLint*)&glheight); + LLGLint glcomponents = 0 ; + glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&glcomponents); + assert_glerror(); + + return glwidth >= image_width && glheight >= image_height && (GL_RGB8 == glcomponents || GL_RGBA8 == glcomponents) ; +} + BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) { if (discard_level < 0) @@ -1022,6 +1067,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre llerrs << llformat("LLImageGL::readBackRaw: bogus params: %d x %d x %d",width,height,ncomponents) << llendl; } + BOOL return_result = TRUE ; LLGLint is_compressed = 0; if (compressed_ok) { @@ -1033,16 +1079,28 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint*)&glbytes); imageraw->allocateDataSize(width, height, ncomponents, glbytes); glGetCompressedTexImageARB(mTarget, gl_discard, (GLvoid*)(imageraw->getData())); + if(glGetError() != GL_NO_ERROR) + { + llwarns << "Error happens when reading back the compressed texture image." << llendl ; + imageraw->deleteData() ; + return_result = FALSE ; + } stop_glerror(); } else { imageraw->allocateDataSize(width, height, ncomponents); glGetTexImage(GL_TEXTURE_2D, gl_discard, mFormatPrimary, mFormatType, (GLvoid*)(imageraw->getData())); + if(glGetError() != GL_NO_ERROR) + { + llwarns << "Error happens when reading back the texture image." << llendl ; + imageraw->deleteData() ; + return_result = FALSE ; + } stop_glerror(); } - return TRUE; + return return_result ; } void LLImageGL::destroyGLTexture() @@ -1057,7 +1115,6 @@ void LLImageGL::destroyGLTexture() { unbindTexture(i, GL_TEXTURE_2D); stop_glerror(); - glActiveTextureARB(GL_TEXTURE0_ARB); } } diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 20cf4ae10f..82ea147d6e 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -131,6 +131,8 @@ public: BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; } BOOL getDontDiscard() const { return mDontDiscard; } + BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ; + protected: void init(BOOL usemipmaps); virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 7f9c611c69..27c40fcfcf 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -71,7 +71,7 @@ public: //allocate resources for rendering //must be called before use //multiple calls will release previously allocated resources - void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage = GL_TEXTURE_2D, BOOL use_fbo = TRUE); + void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage = GL_TEXTURE_2D, BOOL use_fbo = FALSE); //allocate a depth texture void allocateDepth(); diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 9303e00228..b646a02cae 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -38,6 +38,7 @@ #include "llglheaders.h" #include "llmemory.h" #include "llmemtype.h" +#include "llglimmediate.h" //============================================================================ @@ -76,6 +77,141 @@ S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] = sizeof(LLVector4), // TYPE_CLOTHWEIGHT, }; +U32 LLVertexBuffer::sGLMode[LLVertexBuffer::NUM_MODES] = +{ + GL_TRIANGLES, + GL_TRIANGLE_STRIP, + GL_TRIANGLE_FAN, + GL_POINTS, + GL_LINES, + GL_LINE_STRIP +}; + +//static +void LLVertexBuffer::setupClientArrays(U32 data_mask) +{ + if (LLGLImmediate::sStarted) + { + llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl; + } + + if (sLastMask != data_mask) + { + U32 mask[] = + { + MAP_VERTEX, + MAP_NORMAL, + MAP_TEXCOORD, + MAP_COLOR + }; + + GLenum array[] = + { + GL_VERTEX_ARRAY, + GL_NORMAL_ARRAY, + GL_TEXTURE_COORD_ARRAY, + GL_COLOR_ARRAY + }; + + for (U32 i = 0; i < 4; ++i) + { + if (sLastMask & mask[i]) + { //was enabled + if (!(data_mask & mask[i]) && i > 0) + { //needs to be disabled + glDisableClientState(array[i]); + } + else + { //needs to be enabled, make sure it was (DEBUG TEMPORARY) + if (i > 0 && !glIsEnabled(array[i])) + { + llerrs << "Bad client state! " << array[i] << " disabled." << llendl; + } + } + } + else + { //was disabled + if (data_mask & mask[i]) + { //needs to be enabled + glEnableClientState(array[i]); + } + else if (glIsEnabled(array[i])) + { //needs to be disabled, make sure it was (DEBUG TEMPORARY) + llerrs << "Bad client state! " << array[i] << " enabled." << llendl; + } + } + } + + if (sLastMask & MAP_TEXCOORD2) + { + if (!(data_mask & MAP_TEXCOORD2)) + { + glClientActiveTextureARB(GL_TEXTURE1_ARB); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + } + else if (data_mask & MAP_TEXCOORD2) + { + glClientActiveTextureARB(GL_TEXTURE1_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + + sLastMask = data_mask; + } +} + +void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const +{ + if (start >= (U32) mRequestedNumVerts || + end >= (U32) mRequestedNumVerts) + { + llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl; + } + + if (indices_offset >= (U32) mRequestedNumIndices || + indices_offset + count > (U32) mRequestedNumIndices) + { + llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; + } + + if (mGLIndices != sGLRenderIndices) + { + llerrs << "Wrong index buffer bound." << llendl; + } + + if (mGLBuffer != sGLRenderBuffer) + { + llerrs << "Wrong vertex buffer bound." << llendl; + } + + glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, + ((U16*) getIndicesPointer()) + indices_offset); +} + +void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const +{ + if (indices_offset >= (U32) mRequestedNumIndices || + indices_offset + count > (U32) mRequestedNumIndices) + { + llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; + } + + if (mGLIndices != sGLRenderIndices) + { + llerrs << "Wrong index buffer bound." << llendl; + } + + if (mGLBuffer != sGLRenderBuffer) + { + llerrs << "Wrong vertex buffer bound." << llendl; + } + + glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT, + ((U16*) getIndicesPointer()) + indices_offset); +} + //static void LLVertexBuffer::initClass(bool use_vbo) { @@ -102,7 +238,8 @@ void LLVertexBuffer::unbind() sGLRenderBuffer = 0; sGLRenderIndices = 0; - sLastMask = 0; + + setupClientArrays(0); } //static @@ -118,22 +255,14 @@ void LLVertexBuffer::cleanupClass() void LLVertexBuffer::startRender() { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); - if (sEnableVBOs) - { - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - sVBOActive = FALSE; - sIBOActive = FALSE; - } - + + unbind(); sRenderActive = TRUE; - sGLRenderBuffer = 0; - sGLRenderIndices = 0; - sLastMask = 0; } void LLVertexBuffer::stopRender() { + unbind(); sRenderActive = FALSE; } @@ -615,6 +744,16 @@ U8* LLVertexBuffer::mapBuffer(S32 access) llerrs << "Mapped two VBOs at the same time!" << llendl; } sMapped = TRUE;*/ + if (!mMappedData) + { + llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; + } + + if (!mMappedIndexData) + { + llerrs << "glMapBuffer returned NULL (no index data)" << llendl; + } + sMappedCount++; } @@ -666,7 +805,12 @@ template <class T,S32 type> struct VertexBufferStrider strider_t& strider, S32 index) { - vbo.mapBuffer(); + if (vbo.mapBuffer() == NULL) + { + llwarns << "mapBuffer failed!" << llendl; + return FALSE; + } + if (type == LLVertexBuffer::TYPE_INDEX) { S32 stride = sizeof(T); @@ -828,6 +972,8 @@ void LLVertexBuffer::setBuffer(U32 data_mask) sIBOActive = FALSE; } } + + setupClientArrays(data_mask); if (mGLIndices) { @@ -846,8 +992,6 @@ void LLVertexBuffer::setBuffer(U32 data_mask) sSetCount++; } } - - sLastMask = data_mask; } // virtual (default) @@ -871,10 +1015,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const { glClientActiveTextureARB(GL_TEXTURE1_ARB); glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD2])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } if (data_mask & MAP_TEXCOORD) { - glClientActiveTextureARB(GL_TEXTURE0_ARB); glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD])); } if (data_mask & MAP_COLOR) diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index e2a4196b0e..50f79cfc9d 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -84,6 +84,7 @@ public: static void initClass(bool use_vbo); static void cleanupClass(); + static void setupClientArrays(U32 data_mask); static void startRender(); //between start and stop render, no client copies will occur static void stopRender(); //any buffer not copied to GL will be rendered from client memory static void clientCopy(F64 max_time = 0.005); //copy data from client to GL @@ -123,6 +124,15 @@ public: MAP_UNMAPPED = 0x8000 // Indicates that buffer has been logically un-mapped }; + enum { + TRIANGLES = 0, + TRIANGLE_STRIP, + TRIANGLE_FAN, + POINTS, + LINES, + LINE_STRIP, + NUM_MODES + }; protected: friend class LLGLImmediate; @@ -194,6 +204,9 @@ public: void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count); + void draw(U32 mode, U32 count, U32 indices_offset) const; + void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; + protected: S32 mNumVerts; // Number of vertices allocated S32 mNumIndices; // Number of indices allocated @@ -241,6 +254,7 @@ public: static BOOL sEnableVBOs; static S32 sTypeOffsets[TYPE_MAX]; + static U32 sGLMode[NUM_MODES]; static U32 sGLRenderBuffer; static U32 sGLRenderIndices; static BOOL sVBOActive; |