diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index c6680e6dd..52f4951e6 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1043,7 +1043,8 @@ LLRender::LLRender() mCount(0), mMode(LLRender::TRIANGLES), mCurrTextureUnitIndex(0), - mMaxAnisotropy(0.f) + mMaxAnisotropy(0.f), + mPrimitiveReset(false) { mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS); for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++) @@ -2056,7 +2057,8 @@ void LLRender::begin(const GLuint& mode) { if (mMode == LLRender::LINES || mMode == LLRender::TRIANGLES || - mMode == LLRender::POINTS) + mMode == LLRender::POINTS || + mMode == LLRender::TRIANGLE_STRIP ) { flush(); } @@ -2079,11 +2081,16 @@ void LLRender::end() if ((mMode != LLRender::LINES && mMode != LLRender::TRIANGLES && - mMode != LLRender::POINTS) || + mMode != LLRender::POINTS && + mMode != LLRender::TRIANGLE_STRIP) || mCount > 2048) { flush(); } + else if (mMode == LLRender::TRIANGLE_STRIP) + { + mPrimitiveReset = true; + } } void LLRender::flush() { @@ -2177,6 +2184,7 @@ void LLRender::flush() mColorsp[0] = mColorsp[count]; mCount = 0; + mPrimitiveReset = false; } } @@ -2190,6 +2198,21 @@ void LLRender::vertex4a(const LLVector4a& vertex) case LLRender::POINTS: flush(); break; case LLRender::TRIANGLES: if (mCount%3==0) flush(); break; case LLRender::LINES: if (mCount%2 == 0) flush(); break; + case LLRender::TRIANGLE_STRIP: + { + LLVector4a vert[] = { mVerticesp[mCount - 2], mVerticesp[mCount - 1], mVerticesp[mCount] }; + LLColor4U col[] = { mColorsp[mCount - 2], mColorsp[mCount - 1], mColorsp[mCount] }; + LLVector2 tc[] = { mTexcoordsp[mCount - 2], mTexcoordsp[mCount - 1], mTexcoordsp[mCount] }; + flush(); + for (int i = 0; i < LL_ARRAY_SIZE(vert); ++i) + { + mVerticesp[i] = vert[i]; + mColorsp[i] = col[i]; + mTexcoordsp[i] = tc[i]; + } + mCount = 2; + break; + } } } @@ -2199,6 +2222,18 @@ void LLRender::vertex4a(const LLVector4a& vertex) return; } + if (mPrimitiveReset && mCount) + { + // Insert degenerate + ++mCount; + mVerticesp[mCount] = mVerticesp[mCount - 1]; + mColorsp[mCount] = mColorsp[mCount - 1]; + mTexcoordsp[mCount] = mTexcoordsp[mCount - 1]; + mVerticesp[mCount - 1] = mVerticesp[mCount - 2]; + mColorsp[mCount - 1] = mColorsp[mCount - 2]; + mTexcoordsp[mCount - 1] = mTexcoordsp[mCount - 2]; + } + if (mUIOffset.empty()) { mVerticesp[mCount]=vertex; @@ -2213,7 +2248,17 @@ void LLRender::vertex4a(const LLVector4a& vertex) mCount++; mVerticesp[mCount] = mVerticesp[mCount-1]; mColorsp[mCount] = mColorsp[mCount-1]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; + mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; + + if (mPrimitiveReset && mCount) + { + mCount++; + mVerticesp[mCount] = mVerticesp[mCount - 1]; + mColorsp[mCount] = mColorsp[mCount - 1]; + mTexcoordsp[mCount] = mTexcoordsp[mCount - 1]; + } + + mPrimitiveReset = false; } void LLRender::vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count) @@ -2224,6 +2269,21 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count) return; } + if (mPrimitiveReset && mCount) + { + // Insert degenerate + ++mCount; + mVerticesp[mCount] = verts[0]; + mColorsp[mCount] = mColorsp[mCount - 1]; + mTexcoordsp[mCount] = mTexcoordsp[mCount - 1]; + mVerticesp[mCount - 1] = mVerticesp[mCount - 2]; + mColorsp[mCount - 1] = mColorsp[mCount - 2]; + mTexcoordsp[mCount - 1] = mTexcoordsp[mCount - 2]; + ++mCount; + mColorsp[mCount] = mColorsp[mCount - 1]; + mTexcoordsp[mCount] = mTexcoordsp[mCount - 1]; + } + for (S32 i = 0; i < vert_count; i++) { mVerticesp[mCount] = verts[i]; @@ -2234,6 +2294,8 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count) } mVerticesp[mCount] = mVerticesp[mCount-1]; + + mPrimitiveReset = false; } void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 vert_count) @@ -2244,6 +2306,21 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 return; } + if (mPrimitiveReset && mCount) + { + // Insert degenerate + ++mCount; + mVerticesp[mCount] = verts[0]; + mColorsp[mCount] = mColorsp[mCount - 1]; + mTexcoordsp[mCount] = uvs[0]; + mVerticesp[mCount - 1] = mVerticesp[mCount - 2]; + mColorsp[mCount - 1] = mColorsp[mCount - 2]; + mTexcoordsp[mCount - 1] = mTexcoordsp[mCount - 2]; + ++mCount; + mColorsp[mCount] = mColorsp[mCount - 1]; + mTexcoordsp[mCount] = mTexcoordsp[mCount - 1]; + } + for (S32 i = 0; i < vert_count; i++) { mVerticesp[mCount] = verts[i]; @@ -2255,6 +2332,8 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 mVerticesp[mCount] = mVerticesp[mCount-1]; mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; + + mPrimitiveReset = false; } void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count) @@ -2265,7 +2344,21 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLCo return; } - + if (mPrimitiveReset && mCount) + { + // Insert degenerate + ++mCount; + mVerticesp[mCount] = verts[0]; + mColorsp[mCount] = colors[mCount - 1]; + mTexcoordsp[mCount] = uvs[0]; + mVerticesp[mCount - 1] = mVerticesp[mCount - 2]; + mColorsp[mCount - 1] = mColorsp[mCount - 2]; + mTexcoordsp[mCount - 1] = mTexcoordsp[mCount - 2]; + ++mCount; + mColorsp[mCount] = mColorsp[mCount - 1]; + mTexcoordsp[mCount] = mTexcoordsp[mCount - 1]; + } + for (S32 i = 0; i < vert_count; i++) { mVerticesp[mCount] = verts[i]; @@ -2278,6 +2371,8 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLCo mVerticesp[mCount] = mVerticesp[mCount-1]; mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; mColorsp[mCount] = mColorsp[mCount-1]; + + mPrimitiveReset = false; } void LLRender::texCoord2f(const GLfloat& x, const GLfloat& y) diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 392173a20..15be0d3cf 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -493,6 +493,8 @@ private: std::vector > mUIOffset; std::vector > mUIScale; + + bool mPrimitiveReset; } LL_ALIGN_POSTFIX(16); diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index 272b5af24..1787b5ddc 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -945,15 +945,15 @@ void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.begin( LLRender::TRIANGLE_STRIP ); + gGL.begin( LLRender::TRIANGLE_STRIP ); { steps += 1; // An extra step to close the circle. while( steps-- ) { + gGL.color4fv(inner_color.mV); + gGL.vertex2f(x2, y2); gGL.color4fv(outer_color.mV); gGL.vertex2f( x1, y1 ); - gGL.color4fv(inner_color.mV); - gGL.vertex2f( x2, y2 ); F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; y1 = x1 * SIN_DELTA + y1 * COS_DELTA; @@ -986,10 +986,10 @@ void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, steps += 1; // An extra step to close the circle. while( steps-- ) { + gGL.color4fv(inner_color.mV); + gGL.vertex2f(x2, y2); gGL.color4fv(outer_color.mV); gGL.vertex2f( x1, y1 ); - gGL.color4fv(inner_color.mV); - gGL.vertex2f( x2, y2 ); F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; y1 = x1 * SIN_DELTA + y1 * COS_DELTA; @@ -1042,31 +1042,33 @@ void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LL void gl_rect_2d_simple_tex( S32 width, S32 height ) { gGL.begin( LLRender::TRIANGLE_STRIP ); + { + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(0, height); gGL.texCoord2f(0.f, 0.f); gGL.vertex2i(0, 0); - gGL.texCoord2f(0.f, 1.f); - gGL.vertex2i(0, height); - - gGL.texCoord2f(1.f, 0.f); - gGL.vertex2i(width, 0); - gGL.texCoord2f(1.f, 1.f); gGL.vertex2i(width, height); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(width, 0); + } gGL.end(); } -void gl_rect_2d_simple( S32 width, S32 height ) +void gl_rect_2d_simple(S32 width, S32 height) { - gGL.begin( LLRender::TRIANGLES); + gGL.begin(LLRender::TRIANGLES); + { + gGL.vertex2i(0, height); gGL.vertex2i(0, 0); - gGL.vertex2i(0, height); - gGL.vertex2i(width, 0); - gGL.vertex2i(width, 0); - gGL.vertex2i(0, height); gGL.vertex2i(width, height); + gGL.vertex2i(width, height); + gGL.vertex2i(0, 0); + gGL.vertex2i(width, 0); + } gGL.end(); } @@ -1132,13 +1134,10 @@ void gl_segmented_rect_2d_tex(const S32 left, gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); gGL.vertex2fv((width_vec + height_vec - border_height_top).mV); - - // draw degenerate - gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec + height_vec - border_height_top).mV); - gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); - gGL.vertex2fv((height_vec - border_height_top).mV); - + } + gGL.end(); + gGL.begin(LLRender::TRIANGLE_STRIP); + { // draw left gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); gGL.vertex2fv((height_vec - border_height_top).mV); @@ -1166,12 +1165,10 @@ void gl_segmented_rect_2d_tex(const S32 left, gGL.texCoord2f(1.f, border_uv_scale.mV[VY]); gGL.vertex2fv((width_vec + border_height_bottom).mV); - // draw degenerate - gGL.texCoord2f(1.f, border_uv_scale.mV[VY]); - gGL.vertex2fv((width_vec + border_height_bottom).mV); - gGL.texCoord2f(0.f, border_uv_scale.mV[VY]); - gGL.vertex2fv(border_height_bottom.mV); - + } + gGL.end(); + gGL.begin(LLRender::TRIANGLE_STRIP); + { // draw bottom left gGL.texCoord2f(0.f, border_uv_scale.mV[VY]); gGL.vertex2fv(border_height_bottom.mV); @@ -1249,10 +1246,10 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, LLVector2 x_min; LLVector2 x_max; - gGL.begin(LLRender::TRIANGLE_STRIP); { if (start_fragment < middle_start) { + gGL.begin(LLRender::TRIANGLE_STRIP); u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX]; u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX]; x_min = (start_fragment / middle_start) * border_width_left; @@ -1284,22 +1281,14 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, gGL.texCoord2f(u_max, 1.f); gGL.vertex2fv((x_max + height_vec).mV); + gGL.end(); } if (end_fragment > middle_start || start_fragment < middle_end) { - if (start_fragment < middle_start) - { - gGL.texCoord2f(u_max, 1.f); - gGL.vertex2fv((x_max + height_vec).mV); - } + gGL.begin(LLRender::TRIANGLE_STRIP); x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec; x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec; - if (start_fragment < middle_start) - { - gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); - gGL.vertex2fv(x_min.mV); - } // draw bottom middle gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); @@ -1328,31 +1317,18 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); gGL.vertex2fv((x_max + height_vec).mV); + gGL.end(); + } if (end_fragment > middle_end) { - if (end_fragment > middle_start || start_fragment < middle_end) - { - gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); - gGL.vertex2fv((x_max + height_vec).mV); - } - else if (start_fragment < middle_start) - { - gGL.texCoord2f(u_max, 1.f); - gGL.vertex2fv((x_max + height_vec).mV); - } + gGL.begin(LLRender::TRIANGLE_STRIP); u_min = 1.f - ((1.f - llmax(0.f, (start_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]); u_max = 1.f - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]); x_min = width_vec - ((1.f - llmax(0.f, (start_fragment - middle_end) / middle_start)) * border_width_right); x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right); - if (end_fragment > middle_start || start_fragment < middle_end || start_fragment < middle_start) - { - gGL.texCoord2f(u_min, 0.f); - gGL.vertex2fv((x_min).mV); - } - // draw bottom right gGL.texCoord2f(u_min, 0.f); gGL.vertex2fv((x_min).mV); @@ -1379,9 +1355,9 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, gGL.texCoord2f(u_max, 1.f); gGL.vertex2fv((x_max + height_vec).mV); + gGL.end(); } } - gGL.end(); gGL.popUIMatrix(); } @@ -1417,13 +1393,10 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop); gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV); - - // draw degenerate - gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop); - gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV); - gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop); - gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV); - + } + gGL.end(); + gGL.begin(LLRender::TRIANGLE_STRIP); + { // draw left gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop); gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV); @@ -1451,12 +1424,10 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom); gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV); - // draw degenerate - gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom); - gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV); - gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom); - gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV); - + } + gGL.end(); + gGL.begin(LLRender::TRIANGLE_STRIP); + { // draw bottom left gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom); gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);