llrender and lldir merge. Removed duplicate assets from skins. cleaned up skin textures.xml files to only include changes from default.

This commit is contained in:
Shyotl
2016-04-11 02:51:08 -05:00
parent d40256fb31
commit be5d2f20bc
1280 changed files with 2354 additions and 10692 deletions

View File

@@ -104,7 +104,6 @@ LLFontGlyphInfo::LLFontGlyphInfo(U32 index)
LLFontFreetype::LLFontFreetype()
: mFontBitmapCachep(new LLFontBitmapCache),
mValid(FALSE),
mAscender(0.f),
mDescender(0.f),
mLineHeight(0.f),
@@ -112,6 +111,7 @@ LLFontFreetype::LLFontFreetype()
mFTFace(NULL),
mRenderGlyphCount(0),
mAddGlyphCount(0),
mStyle(0),
mPointSize(0)
{
}
@@ -204,6 +204,19 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, const F32 point_size,
mName = filename;
mPointSize = point_size;
mStyle = LLFontGL::NORMAL;
if(mFTFace->style_flags & FT_STYLE_FLAG_BOLD)
{
mStyle |= LLFontGL::BOLD;
mStyle &= ~LLFontGL::NORMAL;
}
if(mFTFace->style_flags & FT_STYLE_FLAG_ITALIC)
{
mStyle |= LLFontGL::ITALIC;
mStyle &= ~LLFontGL::NORMAL;
}
return TRUE;
}
@@ -536,6 +549,15 @@ const LLPointer<LLFontBitmapCache> LLFontFreetype::getFontBitmapCache() const
return mFontBitmapCachep;
}
void LLFontFreetype::setStyle(U8 style)
{
mStyle = style;
}
U8 LLFontFreetype::getStyle() const
{
return mStyle;
}
void LLFontFreetype::setSubImageLuminanceAlpha(const U32 x, const U32 y, const U32 bitmap_num, const U32 width, const U32 height, const U8 *data, S32 stride) const
{
LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num);

View File

@@ -93,8 +93,6 @@ public:
void setFallbackFonts(const font_vector_t &font);
const font_vector_t &getFallbackFonts() const;
void setCharToGlyphMap(llwchar wch, U32 glyph_index) const;
// Global font metrics - in units of pixels
F32 getLineHeight() const;
F32 getAscenderHeight() const;
@@ -140,6 +138,9 @@ public:
const std::string& getName() const;
const LLPointer<LLFontBitmapCache> getFontBitmapCache() const;
void setStyle(U8 style);
U8 getStyle() const;
static bool sOpenGLcrashOnRestart;
@@ -154,6 +155,8 @@ private:
std::string mName;
U8 mStyle;
F32 mPointSize;
F32 mAscender;
F32 mDescender;
@@ -164,8 +167,6 @@ private:
BOOL mIsFallback;
font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
BOOL mValid;
typedef boost::unordered_map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap

View File

@@ -36,6 +36,7 @@
#include "llfontregistry.h"
#include "llgl.h"
#include "llrender.h"
#include "lltexture.h"
#include "v4color.h"
#include "llstl.h"
#include "llfasttimer.h"
@@ -69,20 +70,6 @@ const F32 PIXEL_CORRECTION_DISTANCE = 0.01f;
const F32 PAD_UVY = 0.5f; // half of vertical padding between glyphs in the glyph texture
const F32 DROP_SHADOW_SOFT_STRENGTH = 0.3f;
F32 llfont_round_x(F32 x)
{
//return llfloor((x-LLFontGL::sCurOrigin.mX)/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleX+LLFontGL::sCurOrigin.mX;
//return llfloor(x/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleY;
return x;
}
F32 llfont_round_y(F32 y)
{
//return llfloor((y-LLFontGL::sCurOrigin.mY)/LLFontGL::sScaleY+0.5f)*LLFontGL::sScaleY+LLFontGL::sCurOrigin.mY;
//return llfloor(y+0.5f);
return y;
}
LLFontGL::LLFontGL()
{
clearEmbeddedChars();
@@ -166,8 +153,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
S32 scaled_max_pixels = max_pixels == S32_MAX ? S32_MAX : llceil((F32)max_pixels * sScaleX);
// Strip off any style bits that are already accounted for by the font.
style = style & (~getFontDesc().getStyle());
// determine which style flags need to be added programmatically by stripping off the
// style bits that are drawn by the underlying Freetype font
U8 style_to_add = (style | mFontDescriptor.getStyle()) & ~mFontFreetype->getStyle();
F32 drop_shadow_strength = 0.f;
if (shadow != NO_SHADOW)
@@ -412,7 +400,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
glyph_count = 0;
}
drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect, text_color, style, shadow, drop_shadow_strength);
drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect, text_color, style_to_add, shadow, drop_shadow_strength);
chars_drawn++;
cur_x += fgi->mXAdvance;
@@ -453,7 +441,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
*right_x = (cur_x - origin.mV[VX]) / sScaleX;
}
if (style & UNDERLINE)
//FIXME: add underline as glyph?
if (style_to_add & UNDERLINE)
{
F32 descender = (F32)llfloor(mFontFreetype->getDescenderHeight());
@@ -475,7 +464,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
(cur_x - origin.mV[VX]) / sScaleX, (F32)y,
color,
LEFT, valign,
style,
style_to_add,
shadow,
S32_MAX, max_pixels,
right_x,
@@ -940,7 +929,7 @@ void LLFontGL::removeEmbeddedChar( llwchar wc ) const
}
// static
void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector<std::string>& xui_paths, bool create_gl_textures)
void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures)
{
sVertDPI = (F32)llfloor(screen_dpi * y_scale);
sHorizDPI = (F32)llfloor(screen_dpi * x_scale);
@@ -951,7 +940,7 @@ void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::st
// Font registry init
if (!sFontRegistry)
{
sFontRegistry = new LLFontRegistry(xui_paths,create_gl_textures);
sFontRegistry = new LLFontRegistry(create_gl_textures);
sFontRegistry->parseFontInfo("fonts.xml");
}
else

View File

@@ -30,7 +30,7 @@
#include "llcoord.h"
#include "llfontregistry.h"
#include "lltexture.h"
#include "llimagegl.h"
#include "llpointer.h"
#include "llrect.h"
#include "v2math.h"
@@ -152,7 +152,7 @@ public:
void addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& label) const;
void removeEmbeddedChar( llwchar wc ) const;
static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector<std::string>& xui_paths, bool create_gl_textures = true);
static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures = true);
// Load sans-serif, sans-serif-small, etc.
// Slow, requires multiple seconds to load fonts.

View File

@@ -34,13 +34,15 @@
#include "llcontrol.h"
#include "lldir.h"
#include "llwindow.h"
#include "llxmlnode.h"
extern LLControlGroup gSavedSettings;
using std::string;
using std::map;
bool fontDescInitFromXML(LLXMLNodePtr node, LLFontDescriptor& desc);
bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc);
bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node);
LLFontDescriptor::LLFontDescriptor():
mStyle(0)
@@ -163,14 +165,9 @@ LLFontDescriptor LLFontDescriptor::normalize() const
return LLFontDescriptor(new_name,new_size,new_style,getFileNames());
}
LLFontRegistry::LLFontRegistry(const string_vec_t& xui_paths,
bool create_gl_textures)
LLFontRegistry::LLFontRegistry(bool create_gl_textures)
: mCreateGLTextures(create_gl_textures)
{
// Propagate this down from LLUICtrlFactory so LLRender doesn't
// need an upstream dependency on LLUI.
mXUIPaths = xui_paths;
// This is potentially a slow directory traversal, so we want to
// cache the result.
mUltimateFallbackList = LLWindow::getDynamicFallbackFontList();
@@ -183,23 +180,27 @@ LLFontRegistry::~LLFontRegistry()
bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
{
bool success = false; // Succeed if we find at least one XUI file
const string_vec_t& xml_paths = mXUIPaths;
bool success = false; // Succeed if we find and read at least one XUI file
const string_vec_t xml_paths = gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_filename);
if (xml_paths.empty())
{
// We didn't even find one single XUI file
return false;
}
for (string_vec_t::const_iterator path_it = xml_paths.begin();
path_it != xml_paths.end();
++path_it)
{
LLXMLNodePtr root;
std::string full_filename = gDirUtilp->findSkinnedFilename(*path_it, xml_filename);
bool parsed_file = LLXMLNode::parseFile(full_filename, root, NULL);
bool parsed_file = LLXMLNode::parseFile(*path_it, root, NULL);
if (!parsed_file)
continue;
if ( root.isNull() || ! root->hasName( "fonts" ) )
{
LL_WARNS() << "Bad font info file: "
<< full_filename << LL_ENDL;
LL_WARNS() << "Bad font info file: " << *path_it << LL_ENDL;
continue;
}
@@ -208,12 +209,12 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
if (root->hasName("fonts"))
{
// Expect a collection of children consisting of "font" or "font_size" entries
bool init_succ = initFromXML(root);
bool init_succ = init_from_xml(this, root);
success = success || init_succ;
}
}
if (success)
dump();
//if (success)
// dump();
return success;
}
@@ -231,7 +232,7 @@ std::string currentOsName()
#endif
}
bool fontDescInitFromXML(LLXMLNodePtr node, LLFontDescriptor& desc)
bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc)
{
if (node->hasName("font"))
{
@@ -264,14 +265,14 @@ bool fontDescInitFromXML(LLXMLNodePtr node, LLFontDescriptor& desc)
{
if (child_name == currentOsName())
{
fontDescInitFromXML(child, desc);
font_desc_init_from_xml(child, desc);
}
}
}
return true;
}
bool LLFontRegistry::initFromXML(LLXMLNodePtr node)
bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node)
{
LLXMLNodePtr child;
@@ -282,17 +283,17 @@ bool LLFontRegistry::initFromXML(LLXMLNodePtr node)
if (child->hasName("font"))
{
LLFontDescriptor desc;
bool font_succ = fontDescInitFromXML(child, desc);
bool font_succ = font_desc_init_from_xml(child, desc);
LLFontDescriptor norm_desc = desc.normalize();
if (font_succ)
{
// if this is the first time we've seen this font name,
// create a new template map entry for it.
const LLFontDescriptor *match_desc = getMatchingFontDesc(desc);
const LLFontDescriptor *match_desc = registry->getMatchingFontDesc(desc);
if (match_desc == NULL)
{
// Create a new entry (with no corresponding font).
mFontMap[norm_desc] = NULL;
registry->mFontMap[norm_desc] = NULL;
}
// otherwise, find the existing entry and combine data.
else
@@ -307,8 +308,8 @@ bool LLFontRegistry::initFromXML(LLXMLNodePtr node)
desc.getFileNames().end());
LLFontDescriptor new_desc = *match_desc;
new_desc.getFileNames() = match_file_names;
mFontMap.erase(*match_desc);
mFontMap[new_desc] = NULL;
registry->mFontMap.erase(*match_desc);
registry->mFontMap[new_desc] = NULL;
}
}
}
@@ -319,7 +320,7 @@ bool LLFontRegistry::initFromXML(LLXMLNodePtr node)
if (child->getAttributeString("name",size_name) &&
child->getAttributeF32("size",size_value))
{
mFontSizes[size_name] = size_value;
registry->mFontSizes[size_name] = size_value;
}
}

View File

@@ -28,7 +28,7 @@
#ifndef LL_LLFONTREGISTRY_H
#define LL_LLFONTREGISTRY_H
#include "llxmlnode.h"
#include "llpointer.h"
class LLFontGL;
@@ -65,15 +65,14 @@ private:
class LLFontRegistry
{
public:
friend bool init_from_xml(LLFontRegistry*, LLPointer<class LLXMLNode>);
// create_gl_textures - set to false for test apps with no OpenGL window,
// such as llui_libtest
LLFontRegistry(const string_vec_t& xui_paths,
bool create_gl_textures);
LLFontRegistry(bool create_gl_textures);
~LLFontRegistry();
// Load standard font info from XML file(s).
bool parseFontInfo(const std::string& xml_filename);
bool initFromXML(LLXMLNodePtr node);
// Clear cached glyphs for all fonts.
void reset();
@@ -95,6 +94,7 @@ public:
const string_vec_t& getUltimateFallbackList() const;
private:
LLFontRegistry(const LLFontRegistry& other); // no-copy
LLFontGL *createFont(const LLFontDescriptor& desc);
typedef std::map<LLFontDescriptor,LLFontGL*> font_reg_map_t;
typedef std::map<std::string,F32> font_size_map_t;
@@ -105,7 +105,6 @@ private:
font_size_map_t mFontSizes;
string_vec_t mUltimateFallbackList;
string_vec_t mXUIPaths;
bool mCreateGLTextures;
};

View File

@@ -223,6 +223,7 @@ PFNGLENDQUERYARBPROC glEndQueryARB = NULL;
PFNGLGETQUERYIVARBPROC glGetQueryivARB = NULL;
PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB = NULL;
PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB = NULL;
PFNGLGETQUERYOBJECTUI64VEXTPROC glGetQueryObjectui64vEXT = NULL;
// GL_ARB_point_parameters
PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB = NULL;
@@ -443,6 +444,7 @@ LLGLManager::LLGLManager() :
mHasCubeMap(FALSE),
mHasDebugOutput(FALSE),
mHasGpuShader5(FALSE),
mHasAdaptiveVsync(FALSE),
mHasTextureSwizzle(FALSE),
@@ -938,6 +940,9 @@ void LLGLManager::initExtensions()
mHasVertexShader = FALSE;
mHasFragmentShader = FALSE;
mHasTextureRectangle = FALSE;
#ifdef GL_ARB_gpu_shader5
mHasGpuShader5 = FALSE;
#endif
#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
@@ -982,7 +987,9 @@ void LLGLManager::initExtensions()
&& (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
#endif
#ifdef GL_ARB_gpu_shader5
mHasGpuShader5 = ExtensionExists("GL_ARB_gpu_shader5", gGLHExts.mSysExts);;
#endif
#if LL_WINDOWS
mHasAdaptiveVsync = ExtensionExists("WGL_EXT_swap_control_tear", gGLHExts.mSysExts);
#elif LL_LINUX
@@ -1262,6 +1269,9 @@ void LLGLManager::initExtensions()
glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectivARB");
glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectuivARB");
}
#if !LL_DARWIN
glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectui64vEXT");
#endif
if (mHasPointParameters)
{
LL_INFOS() << "initExtensions() PointParameters-related procs..." << LL_ENDL;

View File

@@ -112,7 +112,7 @@ public:
BOOL mHasARBEnvCombine;
BOOL mHasCubeMap;
BOOL mHasDebugOutput;
BOOL mHasGpuShader5;
BOOL mHasAdaptiveVsync;
BOOL mHasTextureSwizzle;

View File

@@ -620,6 +620,8 @@ extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;
extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;
extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB;
extern PFNGLGETQUERYOBJECTUI64VEXTPROC glGetQueryObjectui64vEXT;
// GL_ARB_point_parameters
extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;

View File

@@ -38,6 +38,11 @@
#include "OpenGL/OpenGL.h"
#endif
#ifdef LL_RELEASE_FOR_DOWNLOAD
#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
#else
#define UNIFORM_ERRS LL_ERRS("Shader")
#endif
// Lots of STL stuff in here, using namespace std to keep things more readable
using std::vector;
using std::pair;
@@ -48,6 +53,12 @@ GLhandleARB LLGLSLShader::sCurBoundShader = 0;
LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
S32 LLGLSLShader::sIndexedTextureChannels = 0;
bool LLGLSLShader::sNoFixedFunction = false;
bool LLGLSLShader::sProfileEnabled = false;
std::set<LLGLSLShader*> LLGLSLShader::sInstances;
U64 LLGLSLShader::sTotalTimeElapsed = 0;
U32 LLGLSLShader::sTotalTrianglesDrawn = 0;
U64 LLGLSLShader::sTotalSamplesDrawn = 0;
U32 LLGLSLShader::sTotalDrawCalls = 0;
//UI shader -- declared here so llui_libtest will link properly
//Singu note: Not using llui_libtest... and LLViewerShaderMgr is a part of newview. So,
@@ -77,13 +88,221 @@ LLShaderFeatures::LLShaderFeatures()
, hasGamma(false)
, mIndexedTextureChannels(0)
, disableTextureIndex(false)
, hasAlphaMask(false)
, hasAlphaMask(false)
, attachNothing(false)
{
}
//===============================
// LLGLSL Shader implementation
//===============================
//static
void LLGLSLShader::initProfile()
{
sProfileEnabled = true;
sTotalTimeElapsed = 0;
sTotalTrianglesDrawn = 0;
sTotalSamplesDrawn = 0;
sTotalDrawCalls = 0;
for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
{
(*iter)->clearStats();
}
}
struct LLGLSLShaderCompareTimeElapsed
{
bool operator()(const LLGLSLShader* const& lhs, const LLGLSLShader* const& rhs)
{
return lhs->mTimeElapsed < rhs->mTimeElapsed;
}
};
//static
void LLGLSLShader::finishProfile(bool emit_report)
{
sProfileEnabled = false;
if (emit_report)
{
std::vector<LLGLSLShader*> sorted;
for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
{
sorted.push_back(*iter);
}
std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed());
for (std::vector<LLGLSLShader*>::iterator iter = sorted.begin(); iter != sorted.end(); ++iter)
{
(*iter)->dumpStats();
}
LL_INFOS() << "-----------------------------------" << LL_ENDL;
LL_INFOS() << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed/1000000.f) << LL_ENDL;
LL_INFOS() << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn/1000000.f) << LL_ENDL;
LL_INFOS() << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn/1000000.f) << LL_ENDL;
}
}
void LLGLSLShader::clearStats()
{
mTrianglesDrawn = 0;
mTimeElapsed = 0;
mSamplesDrawn = 0;
mDrawCalls = 0;
mTextureStateFetched = false;
mTextureMagFilter.clear();
mTextureMinFilter.clear();
}
void LLGLSLShader::dumpStats()
{
if (mDrawCalls > 0)
{
LL_INFOS() << "=============================================" << LL_ENDL;
LL_INFOS() << mName << LL_ENDL;
for (U32 i = 0; i < mShaderFiles.size(); ++i)
{
LL_INFOS() << mShaderFiles[i].first << LL_ENDL;
}
for (U32 i = 0; i < mTexture.size(); ++i)
{
GLint idx = mTexture[i];
if (idx >= 0)
{
GLint uniform_idx = getUniformLocation(i);
LL_INFOS() << mUniformNameMap[uniform_idx] << " - " << std::hex << mTextureMagFilter[i] << "/" << mTextureMinFilter[i] << std::dec << LL_ENDL;
}
}
LL_INFOS() << "=============================================" << LL_ENDL;
F32 ms = mTimeElapsed/1000000.f;
F32 seconds = ms/1000.f;
F32 pct_tris = (F32) mTrianglesDrawn/(F32)sTotalTrianglesDrawn*100.f;
F32 tris_sec = (F32) (mTrianglesDrawn/1000000.0);
tris_sec /= seconds;
F32 pct_samples = (F32) ((F64)mSamplesDrawn/(F64)sTotalSamplesDrawn)*100.f;
F32 samples_sec = (F32) mSamplesDrawn/1000000000.0;
samples_sec /= seconds;
F32 pct_calls = (F32) mDrawCalls/(F32)sTotalDrawCalls*100.f;
U32 avg_batch = mTrianglesDrawn/mDrawCalls;
LL_INFOS() << "Triangles Drawn: " << mTrianglesDrawn << " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec ) << LL_ENDL;
LL_INFOS() << "Draw Calls: " << mDrawCalls << " " << llformat("(%.2f pct of total, avg %d tris/call)", pct_calls, avg_batch) << LL_ENDL;
LL_INFOS() << "SamplesDrawn: " << mSamplesDrawn << " " << llformat("(%.2f pct of total, %.3f billion/sec)", pct_samples, samples_sec) << LL_ENDL;
LL_INFOS() << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32) ((F64)mTimeElapsed/(F64)sTotalTimeElapsed)*100.f, ms) << LL_ENDL;
}
}
//static
void LLGLSLShader::startProfile()
{
if (sProfileEnabled && sCurBoundShaderPtr)
{
sCurBoundShaderPtr->placeProfileQuery();
}
}
//static
void LLGLSLShader::stopProfile(U32 count, U32 mode)
{
if (sProfileEnabled && sCurBoundShaderPtr)
{
sCurBoundShaderPtr->readProfileQuery(count, mode);
}
}
void LLGLSLShader::placeProfileQuery()
{
#if !LL_DARWIN
if (mTimerQuery == 0)
{
glGenQueriesARB(1, &mSamplesQuery);
glGenQueriesARB(1, &mTimerQuery);
}
if (!mTextureStateFetched)
{
mTextureStateFetched = true;
mTextureMagFilter.resize(mTexture.size());
mTextureMinFilter.resize(mTexture.size());
U32 cur_active = gGL.getCurrentTexUnitIndex();
for (U32 i = 0; i < mTexture.size(); ++i)
{
GLint idx = mTexture[i];
if (idx >= 0)
{
gGL.getTexUnit(idx)->activate();
U32 mag = 0xFFFFFFFF;
U32 min = 0xFFFFFFFF;
U32 type = LLTexUnit::getInternalType(gGL.getTexUnit(idx)->getCurrType());
glGetTexParameteriv(type, GL_TEXTURE_MAG_FILTER, (GLint*) &mag);
glGetTexParameteriv(type, GL_TEXTURE_MIN_FILTER, (GLint*) &min);
mTextureMagFilter[i] = mag;
mTextureMinFilter[i] = min;
}
}
gGL.getTexUnit(cur_active)->activate();
}
glBeginQueryARB(GL_SAMPLES_PASSED, mSamplesQuery);
glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery);
#endif
}
void LLGLSLShader::readProfileQuery(U32 count, U32 mode)
{
#if !LL_DARWIN
glEndQueryARB(GL_TIME_ELAPSED);
glEndQueryARB(GL_SAMPLES_PASSED);
GLuint64 time_elapsed = 0;
glGetQueryObjectui64vEXT(mTimerQuery, GL_QUERY_RESULT, &time_elapsed);
GLuint64 samples_passed = 0;
glGetQueryObjectui64vEXT(mSamplesQuery, GL_QUERY_RESULT, &samples_passed);
sTotalTimeElapsed += time_elapsed;
mTimeElapsed += time_elapsed;
sTotalSamplesDrawn += samples_passed;
mSamplesDrawn += samples_passed;
U32 tri_count = 0;
switch (mode)
{
case LLRender::TRIANGLES: tri_count = count/3; break;
case LLRender::TRIANGLE_FAN: tri_count = count-2; break;
case LLRender::TRIANGLE_STRIP: tri_count = count-2; break;
default: tri_count = count; break; //points lines etc just use primitive count
}
mTrianglesDrawn += tri_count;
sTotalTrianglesDrawn += tri_count;
sTotalDrawCalls++;
mDrawCalls++;
#endif
}
LLGLSLShader::LLGLSLShader(S32 shader_class)
: mProgramObject(0),
mShaderClass(shader_class),
@@ -91,20 +310,25 @@ LLGLSLShader::LLGLSLShader(S32 shader_class)
mTotalUniformSize(0),
mActiveTextureChannels(0),
mShaderLevel(0),
mShaderGroup(SG_DEFAULT),
mUniformsDirty(FALSE)
mShaderGroup(SG_DEFAULT),
mUniformsDirty(FALSE),
mTimerQuery(0),
mSamplesQuery(0)
{
LLShaderMgr::getGlobalShaderList().push_back(this);
}
LLGLSLShader::~LLGLSLShader()
{
{
}
void LLGLSLShader::unload()
{
stop_glerror();
mAttribute.clear();
sInstances.erase(this);
stop_glerror();
mAttribute.clear();
mTexture.clear();
mUniform.clear();
mShaderFiles.clear();
@@ -126,10 +350,22 @@ void LLGLSLShader::unload()
glDeleteObjectARB(mProgramObject);
mProgramObject = 0;
}
//hack to make apple not complain
glGetError();
if (mTimerQuery)
{
glDeleteQueriesARB(1, &mTimerQuery);
mTimerQuery = 0;
}
if (mSamplesQuery)
{
glDeleteQueriesARB(1, &mSamplesQuery);
mSamplesQuery = 0;
}
//hack to make apple not complain
glGetError();
stop_glerror();
}
@@ -138,9 +374,11 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
U32 varying_count,
const char** varyings)
{
//reloading, reset matrix hash values
for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
{
sInstances.insert(this);
//reloading, reset matrix hash values
for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
{
mMatHash[i] = 0xFFFFFFFF;
}
mLightHash = 0xFFFFFFFF;
@@ -243,9 +481,18 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
}
}
unbind();
}
}
return success;
if (LLShaderMgr::instance()->mProgramObjects.find(mName) == LLShaderMgr::instance()->mProgramObjects.end())
{
LLShaderMgr::instance()->mProgramObjects.emplace(mName, mProgramObject);
}
else
{
LL_WARNS("ShaderLoading") << "Attempting to create shader program with duplicate name: " << mName << LL_ENDL;
}
return success;
}
BOOL LLGLSLShader::attachObject(std::string object)
@@ -425,6 +672,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
}
LLStaticHashedString hashedName(name);
mUniformNameMap[location] = name;
mUniformMap[hashedName] = location;
LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
@@ -489,6 +737,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
mActiveTextureChannels = 0;
mUniform.clear();
mUniformMap.clear();
mUniformNameMap.clear();
mTexture.clear();
mValueVec4.clear();
mValueMat3.clear();

View File

@@ -56,6 +56,7 @@ public:
S32 mIndexedTextureChannels;
bool disableTextureIndex;
bool hasAlphaMask;
bool attachNothing;
// char numLights;
@@ -73,6 +74,9 @@ public:
SG_WATER
};
static std::set<LLGLSLShader*> sInstances;
static bool sProfileEnabled;
LLGLSLShader(S32 shader_class);
~LLGLSLShader();
@@ -81,7 +85,18 @@ public:
static S32 sIndexedTextureChannels;
static bool sNoFixedFunction;
static void initProfile();
static void finishProfile(bool emit_report = true);
static void startProfile();
static void stopProfile(U32 count, U32 mode);
void unload();
void clearStats();
void dumpStats();
void placeProfileQuery();
void readProfileQuery(U32 count, U32 mode);
BOOL createShader(std::vector<LLStaticHashedString> * attributes,
std::vector<LLStaticHashedString> * uniforms,
U32 varying_count = 0,
@@ -379,6 +394,7 @@ public:
U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location
std::map<GLint, std::string> mUniformNameMap; //lookup map of uniform location to uniform name
//There are less naive ways to do this than just having several vectors for the differing types, but this method is of least complexity and has some inherent type-safety.
std::vector<std::pair<GLint, LLVector4> > mValueVec4; //lookup map of uniform location to last known value
std::vector<std::pair<GLint, LLMatrix3> > mValueMat3; //lookup map of uniform location to last known value
@@ -395,6 +411,23 @@ public:
std::vector< std::pair< std::string, GLenum > > mShaderFiles;
std::string mName;
std::map<std::string, std::string> mDefines;
//statistcis for profiling shader performance
U32 mTimerQuery;
U32 mSamplesQuery;
U64 mTimeElapsed;
static U64 sTotalTimeElapsed;
U32 mTrianglesDrawn;
static U32 sTotalTrianglesDrawn;
U64 mSamplesDrawn;
static U64 sTotalSamplesDrawn;
U32 mDrawCalls;
static U32 sTotalDrawCalls;
bool mTextureStateFetched;
std::vector<U32> mTextureMagFilter;
std::vector<U32> mTextureMinFilter;
};
//UI shader (declared here so llui_libtest will link properly)

View File

@@ -2204,26 +2204,10 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
}
//----------------------------------------------------------------------------
void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight)
{
if(!mNeedsAlphaAndPickMask)
{
return ;
}
delete [] mPickMask;
mPickMask = NULL;
mPickMaskWidth = mPickMaskHeight = 0;
if (mFormatType != GL_UNSIGNED_BYTE ||
mFormatPrimary != GL_RGBA)
{
//cannot generate a pick mask for this texture
return;
}
U32 pick_width = width/2 + 1;
U32 pick_height = height/2 + 1;
U32 pick_width = pWidth/2 + 1;
U32 pick_height = pHeight/2 + 1;
U32 size = pick_width * pick_height;
size = (size + 7) / 8; // pixelcount-to-bits
@@ -2233,6 +2217,44 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
memset(mPickMask, 0, sizeof(U8) * size);
return size;
}
//----------------------------------------------------------------------------
void LLImageGL::freePickMask()
{
// pickmask validity depends on old image size, delete it
if (mPickMask != NULL)
{
delete [] mPickMask;
}
mPickMask = NULL;
mPickMaskWidth = mPickMaskHeight = 0;
}
//----------------------------------------------------------------------------
void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
{
if(!mNeedsAlphaAndPickMask)
{
return ;
}
freePickMask();
if (mFormatType != GL_UNSIGNED_BYTE ||
mFormatPrimary != GL_RGBA)
{
//cannot generate a pick mask for this texture
return;
}
#ifdef SHOW_ASSERT
const U32 pickSize = createPickMask(width, height);
#else // SHOW_ASSERT
createPickMask(width, height);
#endif // SHOW_ASSERT
U32 pick_bit = 0;
for (S32 y = 0; y < height; y += 2)
@@ -2245,7 +2267,7 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
{
U32 pick_idx = pick_bit/8;
U32 pick_offset = pick_bit%8;
llassert(pick_idx < size);
llassert(pick_idx < pickSize);
mPickMask[pick_idx] |= 1 << pick_offset;
}

View File

@@ -177,6 +177,9 @@ public:
mutable F32 mLastBindTime; // last time this was bound, by discard level
private:
U32 createPickMask(S32 pWidth, S32 pHeight);
void freePickMask();
LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
S32 mSaveDiscardLevel;
U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel

View File

@@ -56,7 +56,7 @@ bool LLRender::sGLCoreProfile = false;
static const U32 LL_NUM_TEXTURE_LAYERS = 32;
static const U32 LL_NUM_LIGHT_UNITS = 8;
static GLenum sGLTextureType[] =
static const GLenum sGLTextureType[] =
{
GL_TEXTURE_2D,
GL_TEXTURE_RECTANGLE_ARB,
@@ -64,14 +64,14 @@ static GLenum sGLTextureType[] =
//,GL_TEXTURE_2D_MULTISAMPLE Don't use.
};
static GLint sGLAddressMode[] =
static const GLint sGLAddressMode[] =
{
GL_REPEAT,
GL_MIRRORED_REPEAT,
GL_CLAMP_TO_EDGE
};
static GLenum sGLCompareFunc[] =
static const GLenum sGLCompareFunc[] =
{
GL_NEVER,
GL_ALWAYS,
@@ -85,7 +85,7 @@ static GLenum sGLCompareFunc[] =
const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0;
static GLenum sGLBlendFactor[] =
static const GLenum sGLBlendFactor[] =
{
GL_ONE,
GL_ZERO,
@@ -102,15 +102,15 @@ static GLenum sGLBlendFactor[] =
};
LLTexUnit::LLTexUnit(S32 index)
: mCurrTexType(TT_NONE), mCurrBlendType(TB_MULT),
mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT),
mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),
mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),
mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0),
mHasMipMaps(false)
: mCurrTexType(TT_NONE), mCurrBlendType(TB_MULT),
mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT),
mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),
mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),
mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0),
mHasMipMaps(false),
mIndex(index)
{
llassert_always(index < (S32)LL_NUM_TEXTURE_LAYERS);
mIndex = index;
}
//static
@@ -228,53 +228,66 @@ void LLTexUnit::disable(void)
bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
{
stop_glerror();
if (mIndex < 0) return false;
LLImageGL* gl_tex = NULL ;
if (texture == NULL || !(gl_tex = texture->getGLTexture()))
if (mIndex >= 0)
{
LL_WARNS() << "NULL LLTexUnit::bind texture" << LL_ENDL;
gGL.flush();
LLImageGL* gl_tex = NULL ;
if (texture != NULL && (gl_tex = texture->getGLTexture()))
{
if (gl_tex->getTexName()) //if texture exists
{
//in audit, replace the selected texture by the default one.
if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0)
{
if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize)
{
gl_tex->updateBindStats(gl_tex->mTextureMemory);
return bind(LLImageGL::sHighlightTexturep.get());
}
}
if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
{
gGL.flush();
activate();
enable(gl_tex->getTarget());
mCurrTexture = gl_tex->getTexName();
glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
if(gl_tex->updateBindStats(gl_tex->mTextureMemory))
{
texture->setActive() ;
texture->updateBindStatsForTester() ;
}
mHasMipMaps = gl_tex->mHasMipMaps;
if (gl_tex->mTexOptionsDirty)
{
gl_tex->mTexOptionsDirty = false;
setTextureAddressMode(gl_tex->mAddressMode);
setTextureFilteringOption(gl_tex->mFilterOption);
}
}
}
else
{
//if deleted, will re-generate it immediately
texture->forceImmediateUpdate() ;
gl_tex->forceUpdateBindStats() ;
return texture->bindDefaultImage(mIndex);
}
}
else
{
LL_WARNS() << "NULL LLTexUnit::bind texture" << LL_ENDL;
return false;
}
}
else
{ // mIndex < 0
return false;
}
if (!gl_tex->getTexName()) //if texture does not exist
{
//if deleted, will re-generate it immediately
texture->forceImmediateUpdate() ;
gl_tex->forceUpdateBindStats() ;
return texture->bindDefaultImage(mIndex);
}
//in audit, replace the selected texture by the default one.
if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0)
{
if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize)
{
gl_tex->updateBindStats(gl_tex->mTextureMemory);
return bind(LLImageGL::sHighlightTexturep.get());
}
}
if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
{
gGL.flush();
activate();
enable(gl_tex->getTarget());
mCurrTexture = gl_tex->getTexName();
glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
if(gl_tex->updateBindStats(gl_tex->mTextureMemory))
{
texture->setActive() ;
texture->updateBindStatsForTester() ;
}
mHasMipMaps = gl_tex->mHasMipMaps;
if (gl_tex->mTexOptionsDirty)
{
gl_tex->mTexOptionsDirty = false;
setTextureAddressMode(gl_tex->mAddressMode);
setTextureFilteringOption(gl_tex->mFilterOption);
}
}
return true;
}
@@ -1763,7 +1776,7 @@ void LLRender::pushUIMatrix()
{
if (mUIOffset.empty())
{
mUIOffset.push_back(LLVector4a(0.f));
mUIOffset.emplace_back(LLVector4a(0.f));
}
else
{
@@ -1772,7 +1785,7 @@ void LLRender::pushUIMatrix()
if (mUIScale.empty())
{
mUIScale.push_back(LLVector4a(1.f));
mUIScale.emplace_back(LLVector4a(1.f));
}
else
{
@@ -1782,9 +1795,9 @@ void LLRender::pushUIMatrix()
void LLRender::popUIMatrix()
{
if (mUIOffset.empty())
if (mUIOffset.empty() || mUIScale.empty())
{
LL_ERRS() << "UI offset stack blown." << LL_ENDL;
LL_ERRS() << "UI offset or scale stack blown." << LL_ENDL;
}
mUIOffset.pop_back();
mUIScale.pop_back();

View File

@@ -38,12 +38,13 @@
#include "v3math.h"
#include "v4coloru.h"
#include "v4math.h"
#include "llmatrix4a.h"
#include "llalignedarray.h"
#include "llstrider.h"
#include "llpointer.h"
#include "llglheaders.h"
#include "llmatrix4a.h"
#include "llrect.h"
#include "llvector4a.h"
#include <boost/align/aligned_allocator.hpp>
class LLVertexBuffer;
class LLCubeMap;
@@ -200,7 +201,7 @@ public:
void setHasMipMaps(bool hasMips) { mHasMipMaps = hasMips; }
protected:
S32 mIndex;
const S32 mIndex;
U32 mCurrTexture;
eTextureType mCurrTexType;
eTextureBlendType mCurrBlendType;
@@ -493,8 +494,8 @@ private:
F32 mMaxAnisotropy;
LLAlignedArray<LLVector4a, 64> mUIOffset;
LLAlignedArray<LLVector4a, 64> mUIScale;
std::vector<LLVector4a, boost::alignment::aligned_allocator<LLVector4a, 64> > mUIOffset;
std::vector<LLVector4a, boost::alignment::aligned_allocator<LLVector4a, 64> > mUIScale;
} LL_ALIGN_POSTFIX(16);

View File

@@ -348,6 +348,11 @@ void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const
gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );
}
void gl_draw_scaled_target(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* target, const LLColor4& color, const LLRectf& uv_rect)
{
gl_draw_scaled_rotated_image(x, y, width, height, 0.f, NULL, color, uv_rect, target);
}
void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
{
if (NULL == image)
@@ -358,7 +363,7 @@ void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image,
gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect );
}
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect)
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, bool scale_inner)
{
if (NULL == image)
{
@@ -371,10 +376,10 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border
F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0);
LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction);
gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect);
gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect, scale_inner);
}
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect)
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect, bool scale_inner)
{
stop_glerror();
@@ -384,56 +389,6 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
return;
}
// add in offset of current image to current UI translation
const LLVector3 ui_scale = gGL.getUIScale();
const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
F32 uv_width = uv_outer_rect.getWidth();
F32 uv_height = uv_outer_rect.getHeight();
// shrink scaling region to be proportional to clipped image region
LLRectf uv_center_rect(
uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
F32 image_width = image->getWidth(0);
F32 image_height = image->getHeight(0);
S32 image_natural_width = ll_round(image_width * uv_width);
S32 image_natural_height = ll_round(image_height * uv_height);
LLRectf draw_center_rect( uv_center_rect.mLeft * image_width,
uv_center_rect.mTop * image_height,
uv_center_rect.mRight * image_width,
uv_center_rect.mBottom * image_height);
{ // scale fixed region of image to drawn region
draw_center_rect.mRight += width - image_natural_width;
draw_center_rect.mTop += height - image_natural_height;
F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
draw_center_rect.mLeft = ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]);
draw_center_rect.mTop = ll_round(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]);
draw_center_rect.mRight = ll_round(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]);
draw_center_rect.mBottom = ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]);
}
LLRectf draw_outer_rect(ui_translation.mV[VX],
ui_translation.mV[VY] + height * ui_scale.mV[VY],
ui_translation.mV[VX] + width * ui_scale.mV[VX],
ui_translation.mV[VY]);
LLGLSUIDefault gls_ui;
if (solid_color)
{
if (LLGLSLShader::sNoFixedFunction)
@@ -447,7 +402,79 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
}
}
gGL.getTexUnit(0)->bind(image, true);
if (center_rect.mLeft == 0.f
&& center_rect.mRight == 1.f
&& center_rect.mBottom == 0.f
&& center_rect.mTop == 1.f)
{
gl_draw_scaled_image(x, y, width, height, image, color, uv_outer_rect);
}
else
{
// add in offset of current image to current UI translation
const LLVector3 ui_scale = gGL.getUIScale();
const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
F32 uv_width = uv_outer_rect.getWidth();
F32 uv_height = uv_outer_rect.getHeight();
// shrink scaling region to be proportional to clipped image region
LLRectf uv_center_rect( uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
F32 image_width = image->getWidth(0);
F32 image_height = image->getHeight(0);
S32 image_natural_width = ll_round(image_width * uv_width);
S32 image_natural_height = ll_round(image_height * uv_height);
LLRectf draw_center_rect( uv_center_rect.mLeft * image_width,
uv_center_rect.mTop * image_height,
uv_center_rect.mRight * image_width,
uv_center_rect.mBottom * image_height);
if (scale_inner)
{
// scale center region of image to drawn region
draw_center_rect.mRight += width - image_natural_width;
draw_center_rect.mTop += height - image_natural_height;
const F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
const F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
const F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
const F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
const F32 border_shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
draw_center_rect.mLeft *= border_shrink_scale;
draw_center_rect.mTop = lerp((F32)height, (F32)draw_center_rect.mTop, border_shrink_scale);
draw_center_rect.mRight = lerp((F32)width, (F32)draw_center_rect.mRight, border_shrink_scale);
draw_center_rect.mBottom *= border_shrink_scale;
}
else
{
// keep center region of image at fixed scale, but in same relative position
F32 scale_factor = llmin((F32)width / draw_center_rect.getWidth(), (F32)height / draw_center_rect.getHeight(), 1.f);
F32 scaled_width = draw_center_rect.getWidth() * scale_factor;
F32 scaled_height = draw_center_rect.getHeight() * scale_factor;
draw_center_rect.setCenterAndSize(uv_center_rect.getCenterX() * width, uv_center_rect.getCenterY() * height, scaled_width, scaled_height);
}
draw_center_rect.mLeft = ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * ui_scale.mV[VX]);
draw_center_rect.mTop = ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mTop * ui_scale.mV[VY]);
draw_center_rect.mRight = ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mRight * ui_scale.mV[VX]);
draw_center_rect.mBottom = ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * ui_scale.mV[VY]);
LLRectf draw_outer_rect(ui_translation.mV[VX],
ui_translation.mV[VY] + height * ui_scale.mV[VY],
ui_translation.mV[VX] + width * ui_scale.mV[VX],
ui_translation.mV[VY]);
LLGLSUIDefault gls_ui;
gGL.getTexUnit(0)->bind(image, true);
gGL.color4fv(color.mV);
gGL.diffuseColor4fv(color.mV); //workaround: Intel HD 4000
@@ -611,11 +638,12 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
pos[index].set(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
index++;
index++;
gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
}
gGL.end();
}
gGL.end();
if (solid_color)
{
@@ -635,9 +663,9 @@ void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LL
gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );
}
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect, LLRenderTarget* target)
{
if (NULL == image)
if (!image && !target)
{
LL_WARNS() << "image == NULL; aborting function" << LL_ENDL;
return;
@@ -645,8 +673,14 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
LLGLSUIDefault gls_ui;
gGL.getTexUnit(0)->bind(image, true);
if(image != NULL)
{
gGL.getTexUnit(0)->bind(image, true);
}
else
{
gGL.getTexUnit(0)->bind(target);
}
gGL.color4fv(color.mV);
@@ -698,11 +732,18 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
gGL.translateUI(offset_x, offset_y, 0.f);
LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
gGL.getTexUnit(0)->bind(image, true);
if(image != NULL)
{
gGL.getTexUnit(0)->bind(image, true);
}
else
{
gGL.getTexUnit(0)->bind(target);
}
gGL.color4fv(color.mV);
gGL.begin(LLRender::QUADS);
{
LLVector3 v;
@@ -1202,18 +1243,18 @@ void gl_segmented_rect_2d_tex(const S32 left,
gGL.popUIMatrix();
}
//FIXME: rewrite to use scissor?
void gl_segmented_rect_2d_fragment_tex(const S32 left,
const S32 top,
const S32 right,
const S32 bottom,
const S32 texture_width,
const S32 texture_height,
const S32 border_size,
const F32 start_fragment,
const F32 end_fragment,
const U32 edges)
void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
const S32 texture_width,
const S32 texture_height,
const S32 border_size,
const F32 start_fragment,
const F32 end_fragment,
const U32 edges)
{
const S32 left = rect.mLeft;
const S32 right = rect.mRight;
const S32 top = rect.mTop;
const S32 bottom = rect.mBottom;
S32 width = llabs(right - left);
S32 height = llabs(top - bottom);
@@ -1343,10 +1384,10 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
if (end_fragment > middle_end)
{
u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX];
u_max = (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);
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);
// draw bottom right
gGL.texCoord2f(u_min, 0.f);
@@ -1393,145 +1434,132 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
gGL.popUIMatrix();
}
void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width,
const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec,
const U32 edges)
void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect,
const LLVector3& width_vec, const LLVector3& height_vec)
{
LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero;
LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero;
LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero;
LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero;
gGL.begin(LLRender::QUADS);
{
// draw bottom left
gGL.texCoord2f(0.f, 0.f);
gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom);
gGL.vertex3f(0.f, 0.f, 0.f);
gGL.texCoord2f(border_scale.mV[VX], 0.f);
gGL.vertex3fv(left_border_width.mV);
gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(0.f, border_scale.mV[VY]);
gGL.vertex3fv(bottom_border_height.mV);
gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
// draw bottom middle
gGL.texCoord2f(border_scale.mV[VX], 0.f);
gGL.vertex3fv(left_border_width.mV);
gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
gGL.vertex3fv((width_vec - right_border_width).mV);
gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
// draw bottom right
gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
gGL.vertex3fv((width_vec - right_border_width).mV);
gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
gGL.texCoord2f(1.f, 0.f);
gGL.texCoord2f(clip_rect.mRight, clip_rect.mBottom);
gGL.vertex3fv(width_vec.mV);
gGL.texCoord2f(1.f, border_scale.mV[VY]);
gGL.vertex3fv((width_vec + bottom_border_height).mV);
gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
// draw left
gGL.texCoord2f(0.f, border_scale.mV[VY]);
gGL.vertex3fv(bottom_border_height.mV);
gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
gGL.vertex3fv((height_vec - top_border_height).mV);
gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
// draw middle
gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
// draw right
gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(1.f, border_scale.mV[VY]);
gGL.vertex3fv((width_vec + bottom_border_height).mV);
gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
// draw top left
gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
gGL.vertex3fv((height_vec - top_border_height).mV);
gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], 1.f);
gGL.vertex3fv((left_border_width + height_vec).mV);
gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
gGL.texCoord2f(0.f, 1.f);
gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop);
gGL.vertex3fv((height_vec).mV);
// draw top middle
gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
gGL.texCoord2f(border_scale.mV[VX], 1.f);
gGL.vertex3fv((left_border_width + height_vec).mV);
gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
// draw top right
gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
gGL.texCoord2f(1.f, 1.f);
gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop);
gGL.vertex3fv((width_vec + height_vec).mV);
gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
}
gGL.end();
}
void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec)
{
gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP);
}
// static
void LLRender2D::initClass(LLImageProviderInterface* image_provider,
const LLVector2* scale_factor)

View File

@@ -71,11 +71,12 @@ void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4&
void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color);
void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_target(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* target, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), LLRenderTarget* target = NULL);
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), bool scale_inner = true);
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f), bool scale_inner = true);
void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f );
@@ -105,9 +106,8 @@ typedef enum e_rounded_edge
void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, U32 edges = ROUNDED_RECT_ALL);
void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec);
void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, const LLVector3& width_vec, const LLVector3& height_vec);
inline void gl_rect_2d( const LLRect& rect, BOOL filled )
{

View File

@@ -80,7 +80,11 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
llassert_always(shader != NULL);
LLShaderFeatures *features = & shader->mFeatures;
if (features->attachNothing)
{
return TRUE;
}
//////////////////////////////////////
// Attach Vertex Shader Features First
//////////////////////////////////////
@@ -640,11 +644,14 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
// before any non-preprocessor directives (per spec)
text[count++] = strdup("#extension GL_ARB_texture_rectangle : enable\n");
text[count++] = strdup("#extension GL_ARB_shader_texture_lod : enable\n");
if (minor_version == 50 && gGLManager.mHasGpuShader5)
{
text[count++] = strdup("#extension GL_ARB_gpu_shader5 : enable\n");
}
//some implementations of GLSL 1.30 require integer precision be explicitly declared
text[count++] = strdup("precision mediump int;\n");
text[count++] = strdup("precision highp float;\n");
text[count++] = strdup("#define FXAA_GLSL_130 1\n");
}
else
{ //set version to 400
@@ -653,11 +660,11 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
// before any non-preprocessor directives (per spec)
text[count++] = strdup("#extension GL_ARB_texture_rectangle : enable\n");
text[count++] = strdup("#extension GL_ARB_shader_texture_lod : enable\n");
text[count++] = strdup("#define FXAA_GLSL_400 1\n");
}
text[count++] = strdup("#define DEFINE_GL_FRAGCOLOR 1\n");
text[count++] = strdup("#define FXAA_GLSL_130 1\n");
text[count++] = strdup("#define ATTRIBUTE in\n");
@@ -875,8 +882,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
{ //dump every 128 lines
LL_WARNS("ShaderLoading") << "\n" << ostr.str() << LL_ENDL;
ostr.clear();
ostr.str(LLStringUtil::null);
ostr = std::stringstream();
}
}
@@ -943,6 +949,63 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
return ret;
}
void LLShaderMgr::unloadShaders()
{
//Instead of manually unloading, shaders are now automatically accumulated in a list.
//Simply iterate and unload.
std::vector<LLGLSLShader *> &shader_list = LLShaderMgr::getGlobalShaderList();
for (std::vector<LLGLSLShader *>::iterator it = shader_list.begin(); it != shader_list.end(); ++it)
(*it)->unload();
mShaderObjects.clear();
mProgramObjects.clear();
}
void LLShaderMgr::unloadShaderObjects()
{
std::multimap<std::string, LLShaderMgr::CachedObjectInfo >::iterator it = mShaderObjects.begin();
for (; it != mShaderObjects.end(); ++it)
if (it->second.mHandle)
glDeleteObjectARB(it->second.mHandle);
mShaderObjects.clear();
cleanupShaderSources();
}
void LLShaderMgr::cleanupShaderSources()
{
if (!mProgramObjects.empty())
{
for (auto iter = mProgramObjects.cbegin(),
iter_end = mProgramObjects.cend(); iter != iter_end; ++iter)
{
GLuint program = iter->second;
if (program > 0)
{
GLhandleARB shaders[1024] = {};
GLsizei count = -1;
glGetAttachedObjectsARB(program, 1024, &count, shaders);
if (count > 0)
{
for (GLsizei i = 0; i < count; ++i)
{
std::multimap<std::string, LLShaderMgr::CachedObjectInfo>::iterator it = mShaderObjects.begin();
for (; it != LLShaderMgr::instance()->mShaderObjects.end(); it++)
{
if ((*it).second.mHandle == shaders[i])
{
glDetachObjectARB(program, shaders[i]);
break;
}
}
}
}
}
}
// Clear the linked program list as its no longer needed
mProgramObjects.clear();
}
}
BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
{
//check for errors

View File

@@ -232,6 +232,8 @@ DISPLAY_GAMMA,
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
BOOL validateProgramObject(GLhandleARB obj);
GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);
void unloadShaders();
void unloadShaderObjects();
// Implemented in the application to actually point to the shader directory.
virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual
@@ -252,6 +254,9 @@ public:
// Map of shader names to compiled
std::multimap<std::string, CachedObjectInfo > mShaderObjects; //Singu Note: Packing more info here. Doing such provides capability to skip unneeded duplicate loading..
// Map of program names linked
std::map<std::string, GLuint> mProgramObjects;
//global (reserved slot) shader parameters
std::vector<std::string> mReservedAttribs;
@@ -261,6 +266,7 @@ public:
std::map<std::string, std::string> mDefinitions;
protected:
void cleanupShaderSources();
// our parameter manager singleton instance
static LLShaderMgr * sInstance;

View File

@@ -38,11 +38,9 @@ LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image)
mImage(image),
mScaleRegion(0.f, 1.f, 1.f, 0.f),
mClipRegion(0.f, 1.f, 1.f, 0.f),
mUniformScaling(TRUE),
mNoClip(TRUE),
mImageLoaded(NULL)
{
}
mImageLoaded(NULL),
mScaleStyle(SCALE_INNER)
{}
LLUIImage::~LLUIImage()
{
@@ -52,44 +50,35 @@ LLUIImage::~LLUIImage()
void LLUIImage::setClipRegion(const LLRectf& region)
{
mClipRegion = region;
mNoClip = mClipRegion.mLeft == 0.f
&& mClipRegion.mRight == 1.f
&& mClipRegion.mBottom == 0.f
&& mClipRegion.mTop == 1.f;
}
void LLUIImage::setScaleRegion(const LLRectf& region)
{
mScaleRegion = region;
mUniformScaling = mScaleRegion.mLeft == 0.f
&& mScaleRegion.mRight == 1.f
&& mScaleRegion.mBottom == 0.f
&& mScaleRegion.mTop == 1.f;
}
void LLUIImage::setScaleStyle(LLUIImage::EScaleStyle style)
{
mScaleStyle = style;
}
//TODO: move drawing implementation inside class
void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) const
{
gl_draw_scaled_image(x, y, getWidth(), getHeight(), mImage, color, mClipRegion);
draw(x, y, getWidth(), getHeight(), color);
}
void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
{
if (mUniformScaling)
{
gl_draw_scaled_image(x, y, width, height, mImage, color, mClipRegion);
}
else
{
gl_draw_scaled_image_with_border(
x, y,
width, height,
mImage,
color,
FALSE,
mClipRegion,
mScaleRegion);
}
gl_draw_scaled_image_with_border(
x, y,
width, height,
mImage,
color,
FALSE,
mClipRegion,
mScaleRegion,
mScaleStyle == SCALE_INNER);
}
void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
@@ -101,7 +90,8 @@ void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& c
color,
TRUE,
mClipRegion,
mScaleRegion);
mScaleRegion,
mScaleStyle == SCALE_INNER);
}
void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const
@@ -112,6 +102,50 @@ void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4&
drawSolid(border_rect, color);
}
void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis,
const LLRect& rect, const LLColor4& color)
{
F32 border_scale = 1.f;
F32 border_height = (1.f - mScaleRegion.getHeight()) * getHeight();
F32 border_width = (1.f - mScaleRegion.getWidth()) * getWidth();
if (rect.getHeight() < border_height || rect.getWidth() < border_width)
{
if(border_height - rect.getHeight() > border_width - rect.getWidth())
{
border_scale = (F32)rect.getHeight() / border_height;
}
else
{
border_scale = (F32)rect.getWidth() / border_width;
}
}
LLRender2D::pushMatrix();
{
LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis);
LLRender2D::translate(rect_origin.mV[VX],
rect_origin.mV[VY],
rect_origin.mV[VZ]);
gGL.getTexUnit(0)->bind(getImage());
gGL.color4fv(color.mV);
LLRectf center_uv_rect(mClipRegion.mLeft + mScaleRegion.mLeft * mClipRegion.getWidth(),
mClipRegion.mBottom + mScaleRegion.mTop * mClipRegion.getHeight(),
mClipRegion.mLeft + mScaleRegion.mRight * mClipRegion.getWidth(),
mClipRegion.mBottom + mScaleRegion.mBottom * mClipRegion.getHeight());
gl_segmented_rect_3d_tex(mClipRegion,
center_uv_rect,
LLRectf(border_width * border_scale * 0.5f / (F32)rect.getWidth(),
(rect.getHeight() - (border_height * border_scale * 0.5f)) / (F32)rect.getHeight(),
(rect.getWidth() - (border_width * border_scale * 0.5f)) / (F32)rect.getWidth(),
(border_height * border_scale * 0.5f) / (F32)rect.getHeight()),
rect.getWidth() * x_axis,
rect.getHeight() * y_axis);
} LLRender2D::popMatrix();
}
S32 LLUIImage::getWidth() const
{
// return clipped dimensions of actual image area

View File

@@ -45,6 +45,12 @@ extern const LLColor4 UI_VERTEX_COLOR;
class LLUIImage : public LLRefCount
{
public:
enum EScaleStyle
{
SCALE_INNER,
SCALE_OUTER
};
typedef boost::signals2::signal<void (void)> image_loaded_signal_t;
LLUIImage(const std::string& name, LLPointer<LLTexture> image);
@@ -52,6 +58,7 @@ public:
void setClipRegion(const LLRectf& region);
void setScaleRegion(const LLRectf& region);
void setScaleStyle(EScaleStyle style);
LLPointer<LLTexture> getImage() { return mImage; }
const LLPointer<LLTexture>& getImage() const { return mImage; }
@@ -67,7 +74,9 @@ public:
void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;
void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }
void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); }
void draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis, const LLRect& rect, const LLColor4& color);
const std::string& getName() const { return mName; }
virtual S32 getWidth() const;
@@ -84,12 +93,11 @@ public:
protected:
image_loaded_signal_t* mImageLoaded;
std::string mName;
LLRectf mScaleRegion;
LLRectf mClipRegion;
LLPointer<LLTexture> mImage;
BOOL mUniformScaling;
BOOL mNoClip;
std::string mName;
LLRectf mScaleRegion;
LLRectf mClipRegion;
LLPointer<LLTexture> mImage;
EScaleStyle mScaleStyle;
};
namespace LLInitParam