summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llimagegl.cpp93
-rw-r--r--indra/llrender/llimagegl.h2
-rw-r--r--indra/llrender/llrendertarget.h2
-rw-r--r--indra/llrender/llvertexbuffer.cpp176
-rw-r--r--indra/llrender/llvertexbuffer.h14
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;