diff options
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/llfontgl.cpp | 2 | ||||
-rw-r--r-- | indra/llrender/llimagegl.cpp | 44 | ||||
-rw-r--r-- | indra/llrender/llimagegl.h | 2 | ||||
-rw-r--r-- | indra/llrender/llrender.cpp | 50 | ||||
-rw-r--r-- | indra/llrender/llrendersphere.cpp | 86 | ||||
-rw-r--r-- | indra/llrender/llrendersphere.h | 4 |
6 files changed, 131 insertions, 57 deletions
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 768f042e69..d9e1976341 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -673,7 +673,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t target_x *= sScaleX; // max_chars is S32_MAX by default, so make sure we don't get overflow - const S32 max_index = begin_offset + llmin(S32_MAX - begin_offset, max_chars); + const S32 max_index = begin_offset + llmin(S32_MAX - begin_offset, max_chars - 1); F32 scaled_max_pixels = max_pixels * sScaleX; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 36ac3ff119..ff47c57c70 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -105,9 +105,9 @@ void check_all_images() } } -void LLImageGL::checkTexSize() const +void LLImageGL::checkTexSize(bool forced) const { - if (gDebugGL && mTarget == GL_TEXTURE_2D) + if ((forced || gDebugGL) && mTarget == GL_TEXTURE_2D) { GLint texname; glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname); @@ -129,6 +129,8 @@ void LLImageGL::checkTexSize() const glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_WIDTH, (GLint*)&x); glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_HEIGHT, (GLint*)&y) ; stop_glerror() ; + llcallstacks << "w: " << x << " h: " << y << llcallstacksendl ; + if(!x || !y) { return ; @@ -138,11 +140,13 @@ void LLImageGL::checkTexSize() const error = TRUE; if (gDebugSession) { - gFailLog << "wrong texture size and discard level!" << std::endl; + gFailLog << "wrong texture size and discard level!" << + mWidth << " Height: " << mHeight << " Current Level: " << mCurrentDiscardLevel << std::endl; } else { - llerrs << "wrong texture size and discard level!" << llendl ; + llerrs << "wrong texture size and discard level: width: " << + mWidth << " Height: " << mHeight << " Current Level: " << mCurrentDiscardLevel << llendl ; } } @@ -1044,7 +1048,9 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_ { if (gGL.getTexUnit(0)->bind(this, false, true)) { - //checkTexSize() ; + checkTexSize(true) ; + llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height << llcallstacksendl ; + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height); mGLTextureCreated = true; stop_glerror(); @@ -1699,8 +1705,8 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) U32 size = pick_width * pick_height; size = (size + 7) / 8; // pixelcount-to-bits mPickMask = new U8[size]; - mPickMaskWidth = pick_width; - mPickMaskHeight = pick_height; + mPickMaskWidth = pick_width - 1; + mPickMaskHeight = pick_height - 1; memset(mPickMask, 0, sizeof(U8) * size); @@ -1732,8 +1738,18 @@ BOOL LLImageGL::getMask(const LLVector2 &tc) if (mPickMask) { - F32 u = tc.mV[0] - floorf(tc.mV[0]); - F32 v = tc.mV[1] - floorf(tc.mV[1]); + F32 u,v; + if (LL_LIKELY(tc.isFinite())) + { + u = tc.mV[0] - floorf(tc.mV[0]); + v = tc.mV[1] - floorf(tc.mV[1]); + } + else + { + LL_WARNS_ONCE("render") << "Ugh, non-finite u/v in mask pick" << LL_ENDL; + u = v = 0.f; + llassert(false); + } if (LL_UNLIKELY(u < 0.f || u > 1.f || v < 0.f || v > 1.f)) @@ -1743,20 +1759,18 @@ BOOL LLImageGL::getMask(const LLVector2 &tc) llassert(false); } - llassert(mPickMaskWidth > 0 && mPickMaskHeight > 0); - S32 x = llfloor(u * mPickMaskWidth); S32 y = llfloor(v * mPickMaskHeight); - if (LL_UNLIKELY(x >= mPickMaskWidth)) + if (LL_UNLIKELY(x > mPickMaskWidth)) { LL_WARNS_ONCE("render") << "Ooh, width overrun on pick mask read, that coulda been bad." << LL_ENDL; - x = llmax(0, mPickMaskWidth-1); + x = llmax((U16)0, mPickMaskWidth); } - if (LL_UNLIKELY(y >= mPickMaskHeight)) + if (LL_UNLIKELY(y > mPickMaskHeight)) { LL_WARNS_ONCE("render") << "Ooh, height overrun on pick mask read, that woulda been bad." << LL_ENDL; - y = llmax(0, mPickMaskHeight-1); + y = llmax((U16)0, mPickMaskHeight); } S32 idx = y*mPickMaskWidth+x; diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index f0870c3fc4..41239d24c8 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -157,7 +157,7 @@ public: void updatePickMask(S32 width, S32 height, const U8* data_in); BOOL getMask(const LLVector2 &tc); - void checkTexSize() const ; + void checkTexSize(bool forced = false) const ; // Sets the addressing mode used to sample the texture // (such as wrapping, mirrored wrapping, and clamp) diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 656f690db5..c3540a717c 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -121,6 +121,8 @@ void LLTexUnit::refreshState(void) // We set dirty to true so that the tex unit knows to ignore caching // and we reset the cached tex unit state + gGL.flush(); + glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); if (mCurrTexType != TT_NONE) { @@ -150,6 +152,7 @@ void LLTexUnit::activate(void) if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty) { + gGL.flush(); glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); gGL.mCurrTextureUnitIndex = mIndex; } @@ -181,6 +184,7 @@ void LLTexUnit::disable(void) { activate(); unbind(mCurrTexType); + gGL.flush(); glDisable(sGLTextureType[mCurrTexType]); mCurrTexType = TT_NONE; } @@ -386,6 +390,8 @@ void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode) { if (mIndex < 0 || mCurrTexture == 0) return; + gGL.flush(); + activate(); glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]); @@ -400,6 +406,8 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio { if (mIndex < 0 || mCurrTexture == 0) return; + gGL.flush(); + if (option == TFO_POINT) { glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -567,6 +575,7 @@ void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eT if (mCurrBlendType != TB_COMBINE || gGL.mDirty) { mCurrBlendType = TB_COMBINE; + gGL.flush(); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); } @@ -577,6 +586,8 @@ void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eT return; } + gGL.flush(); + // Get the gl source enums according to the eTextureBlendSrc sources passed in GLint source1 = getTextureSource(src1); GLint source2 = getTextureSource(src2); @@ -709,6 +720,7 @@ void LLTexUnit::setColorScale(S32 scale) if (mCurrColorScale != scale || gGL.mDirty) { mCurrColorScale = scale; + gGL.flush(); glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale ); } } @@ -718,6 +730,7 @@ void LLTexUnit::setAlphaScale(S32 scale) if (mCurrAlphaScale != scale || gGL.mDirty) { mCurrAlphaScale = scale; + gGL.flush(); glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale ); } } @@ -853,7 +866,15 @@ void LLRender::scaleUI(F32 x, F32 y, F32 z) void LLRender::pushUIMatrix() { - mUIOffset.push_front(mUIOffset.front()); + if (mUIOffset.empty()) + { + mUIOffset.push_front(LLVector3(0,0,0)); + } + else + { + mUIOffset.push_front(mUIOffset.front()); + } + if (mUIScale.empty()) { mUIScale.push_front(LLVector3(1,1,1)); @@ -1105,6 +1126,33 @@ void LLRender::flush() sUICalls++; sUIVerts += mCount; } + + if (gDebugGL) + { + if (mMode == LLRender::QUADS) + { + if (mCount%4 != 0) + { + llerrs << "Incomplete quad rendered." << llendl; + } + } + + if (mMode == LLRender::TRIANGLES) + { + if (mCount%3 != 0) + { + llerrs << "Incomplete triangle rendered." << llendl; + } + } + + if (mMode == LLRender::LINES) + { + if (mCount%2 != 0) + { + llerrs << "Incomplete line rendered." << llendl; + } + } + } mBuffer->setBuffer(immediate_mask); mBuffer->drawArrays(mMode, 0, mCount); diff --git a/indra/llrender/llrendersphere.cpp b/indra/llrender/llrendersphere.cpp index e22b753923..212963f270 100644 --- a/indra/llrender/llrendersphere.cpp +++ b/indra/llrender/llrendersphere.cpp @@ -68,45 +68,6 @@ void drawSolidSphere(GLdouble radius, GLint slices, GLint stacks) } -// lat = 0 is Z-axis -// lon = 0, lat = 90 at X-axis -void lat2xyz(LLVector3 * result, F32 lat, F32 lon) -{ - // Convert a latitude and longitude to x,y,z on a normal sphere and return it in result - F32 r; - result->mV[VX] = (F32) (cos(lon * DEG_TO_RAD) * sin(lat * DEG_TO_RAD)); - result->mV[VY] = (F32) (sin(lon * DEG_TO_RAD) * sin(lat * DEG_TO_RAD)); - r = (F32) pow(result->mV[VX] * result->mV[VX] + result->mV[VY] * result->mV[VY], 0.5f); - if (r == 1.0f) - { - result->mV[VZ] = 0.0f; - } - else - { - result->mV[VZ] = (F32) pow(1 - r*r, 0.5f); - if (lat > 90.01) - { - result->mV[VZ] *= -1.0; - } - } -} - -void lat2xyz_rad(LLVector3 * result, F32 lat, F32 lon) -{ - // Convert a latitude and longitude to x,y,z on a normal sphere and return it in result - F32 r; - result->mV[VX] = (F32) (cos(lon) * sin(lat)); - result->mV[VY] = (F32) (sin(lon) * sin(lat)); - r = (F32) pow(result->mV[VX] * result->mV[VX] + result->mV[VY] * result->mV[VY], 0.5f); - if (r == 1.0f) - result->mV[VZ] = 0.0f; - else - { - result->mV[VZ] = (F32) pow(1 - r*r, 0.5f); - if (lat > F_PI_BY_TWO) result->mV[VZ] *= -1.0; - } -} - // A couple thoughts on sphere drawing: // 1) You need more slices than stacks, but little less than 2:1 // 2) At low LOD, setting stacks to an odd number avoids a "band" around the equator, making things look smoother @@ -181,3 +142,50 @@ void LLRenderSphere::render() { glCallList(mDList[0]); } + +inline LLVector3 polar_to_cart(F32 latitude, F32 longitude) +{ + return LLVector3(sin(F_TWO_PI * latitude) * cos(F_TWO_PI * longitude), + sin(F_TWO_PI * latitude) * sin(F_TWO_PI * longitude), + cos(F_TWO_PI * latitude)); +} + + +void LLRenderSphere::renderGGL() +{ + S32 const LATITUDE_SLICES = 20; + S32 const LONGITUDE_SLICES = 30; + + if (mSpherePoints.empty()) + { + mSpherePoints.resize(LATITUDE_SLICES + 1); + for (S32 lat_i = 0; lat_i < LATITUDE_SLICES + 1; lat_i++) + { + mSpherePoints[lat_i].resize(LONGITUDE_SLICES + 1); + for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES + 1; lon_i++) + { + F32 lat = (F32)lat_i / LATITUDE_SLICES; + F32 lon = (F32)lon_i / LONGITUDE_SLICES; + + mSpherePoints[lat_i][lon_i] = polar_to_cart(lat, lon); + } + } + } + + gGL.begin(LLRender::TRIANGLES); + + for (S32 lat_i = 0; lat_i < LATITUDE_SLICES; lat_i++) + { + for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES; lon_i++) + { + gGL.vertex3fv(mSpherePoints[lat_i][lon_i].mV); + gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV); + gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV); + + gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV); + gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV); + gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i+1].mV); + } + } + gGL.end(); +} diff --git a/indra/llrender/llrendersphere.h b/indra/llrender/llrendersphere.h index 617ee3e12e..ebc71b6146 100644 --- a/indra/llrender/llrendersphere.h +++ b/indra/llrender/llrendersphere.h @@ -52,6 +52,10 @@ public: void cleanupGL(); void render(F32 pixel_area); // of a box of size 1.0 at that position void render(); // render at highest LOD + void renderGGL(); // render using LLRender + +private: + std::vector< std::vector<LLVector3> > mSpherePoints; }; extern LLRenderSphere gSphere; |