summaryrefslogtreecommitdiff
path: root/indra/llrender/llglslshader.h
blob: 59edd7b36f0dce5cd572e103e291701bdcd27e7f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/** 
 * @file llglslshader.h
 * @brief GLSL shader wrappers
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#ifndef LL_LLGLSLSHADER_H
#define LL_LLGLSLSHADER_H

#include "llgl.h"
#include "llrender.h"
#include "llstaticstringtable.h"

class LLShaderFeatures
{
public:
	bool atmosphericHelpers;
	bool calculatesLighting;
	bool calculatesAtmospherics;
	bool hasLighting; // implies no transport (it's possible to have neither though)
	bool isAlphaLighting; // indicates lighting shaders need not be linked in (lighting performed directly in alpha shader to match deferred lighting functions)
	bool isShiny;
	bool isFullbright; // implies no lighting
	bool isSpecular;
	bool hasWaterFog; // implies no gamma
	bool hasTransport; // implies no lighting (it's possible to have neither though)
	bool hasSkinning;	
	bool hasObjectSkinning;
	bool hasAtmospherics;
	bool hasGamma;
	bool hasSrgb;
    bool encodesNormal;
    bool decodesNormal;
	S32 mIndexedTextureChannels;
	bool disableTextureIndex;
	bool hasAlphaMask;
	bool attachNothing;

	// char numLights;
	
	LLShaderFeatures();
};

class LLGLSLShader
{
public:

	enum 
	{
		SG_DEFAULT = 0,
		SG_SKY,
		SG_WATER
	};
	
	static std::set<LLGLSLShader*> sInstances;
	static bool sProfileEnabled;

	LLGLSLShader();
	~LLGLSLShader();

	static GLhandleARB sCurBoundShader;
	static LLGLSLShader* sCurBoundShaderPtr;
	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,
						const char** varyings = NULL);
	BOOL attachObject(std::string object);
	void attachObject(GLhandleARB object);
	void attachObjects(GLhandleARB* objects = NULL, S32 count = 0);
	BOOL mapAttributes(const std::vector<LLStaticHashedString> * attributes);
	BOOL mapUniforms(const std::vector<LLStaticHashedString> *);
	void mapUniform(GLint index, const std::vector<LLStaticHashedString> *);
	void uniform1i(U32 index, GLint i);
	void uniform1f(U32 index, GLfloat v);
	void uniform2f(U32 index, GLfloat x, GLfloat y);
	void uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z);
	void uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
	void uniform1iv(U32 index, U32 count, const GLint* i);
	void uniform1fv(U32 index, U32 count, const GLfloat* v);
	void uniform2fv(U32 index, U32 count, const GLfloat* v);
	void uniform3fv(U32 index, U32 count, const GLfloat* v);
	void uniform4fv(U32 index, U32 count, const GLfloat* v);
	void uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j);
	void uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
	void uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
	void uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
	void uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
	void uniform1i(const LLStaticHashedString& uniform, GLint i);
	void uniform1f(const LLStaticHashedString& uniform, GLfloat v);
	void uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y);
	void uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z);
	void uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
	void uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
	void uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
	void uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
	void uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat *v);

	void setMinimumAlpha(F32 minimum);

	void vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
	void vertexAttrib4fv(U32 index, GLfloat* v);
	
	//GLint getUniformLocation(const std::string& uniform);
	GLint getUniformLocation(const LLStaticHashedString& uniform);	
	GLint getUniformLocation(U32 index);

	GLint getAttribLocation(U32 attrib);
	GLint mapUniformTextureChannel(GLint location, GLenum type);
	
	void addPermutation(std::string name, std::string value);
	void removePermutation(std::string name);
	
	//enable/disable texture channel for specified uniform
	//if given texture uniform is active in the shader, 
	//the corresponding channel will be active upon return
	//returns channel texture is enabled in from [0-MAX)
	S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
	S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
	
	// bindTexture returns the texture unit we've bound the texture to.
	// You can reuse the return value to unbind a texture when required.
	S32 bindTexture(const std::string& uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
	S32 bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
	S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
	S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
	
    BOOL link(BOOL suppress_errors = FALSE);
	void bind();
	void unbind();

	// Unbinds any previously bound shader by explicitly binding no shader.
	static void bindNoShader(void);

	U32 mMatHash[LLRender::NUM_MATRIX_MODES];
	U32 mLightHash;

    typedef std::map<S32, GLint> uniforms_index_t;
    typedef std::pair<U32, U32>  magmin_values_t;

    typedef std::map < S32, magmin_values_t> magmin_filter_t;

	GLhandleARB mProgramObject;
#if LL_RELEASE_WITH_DEBUG_INFO
	struct attr_name
	{
		GLint loc;
		const char *name;
		void operator = (GLint _loc) { loc = _loc; }
		operator GLint () { return loc; }
	};
	std::vector<attr_name> mAttribute; //lookup table of attribute enum to attribute channel
#else
	std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
#endif
	U32 mAttributeMask;  //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
    uniforms_index_t mUniform;
    uniforms_index_t mTexture;

	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
	std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value
	S32 mTotalUniformSize;
	S32 mActiveTextureChannels;
	S32 mShaderLevel;
	S32 mShaderGroup;
	BOOL mUniformsDirty;
	LLShaderFeatures mFeatures;
	std::vector< std::pair< std::string, GLenum > > mShaderFiles;
	std::string mName;
	boost::unordered_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;
    magmin_filter_t mTextureMagMinFilter;

    GLhandleARB mExtraLinkObject = 0;

private:
	void unloadInternal();

    inline GLint getLocationForIndex(S32 index)
    {
        if (!mProgramObject)
            return -1;
        uniforms_index_t::iterator it = mUniform.find(index);
        if (it == mUniform.end())
            return -1;
        return (*it).second;
    }

    inline GLint getTexChannelForIndex(S32 index)
    {
        if (!mProgramObject)
            return -1;
        uniforms_index_t::iterator it = mTexture.find(index);
        if (it == mTexture.end())
            return -1;
        return (*it).second;
    }
};

//UI shader (declared here so llui_libtest will link properly)
extern LLGLSLShader			gUIProgram;
//output vec4(color.rgb,color.a*tex0[tc0].a)
extern LLGLSLShader			gSolidColorProgram;
//Alpha mask shader (declared here so llappearance can access properly)
extern LLGLSLShader			gAlphaMaskProgram;


#endif