blob: 6277e84f74361bfabb4371da34517161eebcaa1c [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
daniel@transgaming.com2cdf8332012-02-17 18:00:50 +00002// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Shader.cpp: Implements the gl::Shader class and its derived classes
8// VertexShader and FragmentShader. Implements GL shader objects and related
9// functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
10
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000011#include "libGLESv2/Shader.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000012
alokp@chromium.org91b72322010-06-02 15:50:56 +000013#include <string>
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000014
alokp@chromium.org91b72322010-06-02 15:50:56 +000015#include "GLSLANG/Shaderlang.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000016#include "libGLESv2/main.h"
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +000017#include "libGLESv2/utilities.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000018
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000019namespace gl
20{
21void *Shader::mFragmentCompiler = NULL;
22void *Shader::mVertexCompiler = NULL;
23
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000024Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000025{
26 mSource = NULL;
27 mHlsl = NULL;
daniel@transgaming.comcba50572010-03-28 19:36:09 +000028 mInfoLog = NULL;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000029
daniel@transgaming.com938009c2012-02-17 18:02:15 +000030 uncompile();
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +000031 initializeCompiler();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000032
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000033 mRefCount = 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000034 mDeleteStatus = false;
35}
36
37Shader::~Shader()
38{
39 delete[] mSource;
40 delete[] mHlsl;
daniel@transgaming.comcba50572010-03-28 19:36:09 +000041 delete[] mInfoLog;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000042}
43
daniel@transgaming.com6c785212010-03-30 03:36:17 +000044GLuint Shader::getHandle() const
45{
46 return mHandle;
47}
48
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000049void Shader::setSource(GLsizei count, const char **string, const GLint *length)
50{
51 delete[] mSource;
52 int totalLength = 0;
53
54 for (int i = 0; i < count; i++)
55 {
56 if (length && length[i] >= 0)
57 {
58 totalLength += length[i];
59 }
60 else
61 {
62 totalLength += (int)strlen(string[i]);
63 }
64 }
65
66 mSource = new char[totalLength + 1];
67 char *code = mSource;
68
69 for (int i = 0; i < count; i++)
70 {
71 int stringLength;
72
73 if (length && length[i] >= 0)
74 {
75 stringLength = length[i];
76 }
77 else
78 {
79 stringLength = (int)strlen(string[i]);
80 }
81
82 strncpy(code, string[i], stringLength);
83 code += stringLength;
84 }
85
86 mSource[totalLength] = '\0';
87}
88
daniel@transgaming.comcba50572010-03-28 19:36:09 +000089int Shader::getInfoLogLength() const
90{
91 if (!mInfoLog)
92 {
93 return 0;
94 }
95 else
96 {
97 return strlen(mInfoLog) + 1;
98 }
99}
100
101void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
102{
103 int index = 0;
104
105 if (mInfoLog)
106 {
107 while (index < bufSize - 1 && index < (int)strlen(mInfoLog))
108 {
109 infoLog[index] = mInfoLog[index];
110 index++;
111 }
112 }
113
114 if (bufSize)
115 {
116 infoLog[index] = '\0';
117 }
118
119 if (length)
120 {
121 *length = index;
122 }
123}
124
125int Shader::getSourceLength() const
126{
127 if (!mSource)
128 {
129 return 0;
130 }
131 else
132 {
133 return strlen(mSource) + 1;
134 }
135}
136
zmo@google.coma574f782011-10-03 21:45:23 +0000137int Shader::getTranslatedSourceLength() const
138{
139 if (!mHlsl)
140 {
141 return 0;
142 }
143 else
144 {
145 return strlen(mHlsl) + 1;
146 }
147}
148
149void Shader::getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000150{
151 int index = 0;
152
zmo@google.coma574f782011-10-03 21:45:23 +0000153 if (source)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000154 {
zmo@google.coma574f782011-10-03 21:45:23 +0000155 while (index < bufSize - 1 && index < (int)strlen(source))
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000156 {
zmo@google.coma574f782011-10-03 21:45:23 +0000157 buffer[index] = source[index];
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000158 index++;
159 }
160 }
161
162 if (bufSize)
163 {
zmo@google.coma574f782011-10-03 21:45:23 +0000164 buffer[index] = '\0';
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000165 }
166
167 if (length)
168 {
169 *length = index;
170 }
171}
172
zmo@google.coma574f782011-10-03 21:45:23 +0000173void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer)
174{
175 getSourceImpl(mSource, bufSize, length, buffer);
176}
177
178void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
179{
180 getSourceImpl(mHlsl, bufSize, length, buffer);
181}
182
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000183bool Shader::isCompiled()
184{
185 return mHlsl != NULL;
186}
187
daniel@transgaming.com0e3358a2010-04-05 20:32:42 +0000188const char *Shader::getHLSL()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000189{
190 return mHlsl;
191}
192
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000193void Shader::addRef()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000194{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000195 mRefCount++;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000196}
197
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000198void Shader::release()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000199{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000200 mRefCount--;
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000201
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000202 if (mRefCount == 0 && mDeleteStatus)
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000203 {
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000204 mResourceManager->deleteShader(mHandle);
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000205 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000206}
207
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000208unsigned int Shader::getRefCount() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000209{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000210 return mRefCount;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000211}
212
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000213bool Shader::isFlaggedForDeletion() const
214{
215 return mDeleteStatus;
216}
217
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000218void Shader::flagForDeletion()
219{
220 mDeleteStatus = true;
221}
222
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000223// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
224void Shader::initializeCompiler()
225{
226 if (!mFragmentCompiler)
227 {
228 int result = ShInitialize();
229
230 if (result)
231 {
232 ShBuiltInResources resources;
233 ShInitBuiltInResources(&resources);
234 Context *context = getContext();
235
236 resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
237 resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
238 resources.MaxVaryingVectors = context->getMaximumVaryingVectors();
239 resources.MaxVertexTextureImageUnits = context->getMaximumVertexTextureImageUnits();
240 resources.MaxCombinedTextureImageUnits = context->getMaximumCombinedTextureImageUnits();
241 resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
242 resources.MaxFragmentUniformVectors = context->getMaximumFragmentUniformVectors();
243 resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
244 resources.OES_standard_derivatives = 1;
245 // resources.OES_EGL_image_external = getDisplay()->isD3d9ExDevice() ? 1 : 0; // TODO: commented out until the extension is actually supported.
246
247 mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
248 mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
249 }
250 }
251}
252
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000253void Shader::releaseCompiler()
254{
255 ShDestruct(mFragmentCompiler);
256 ShDestruct(mVertexCompiler);
257
258 mFragmentCompiler = NULL;
259 mVertexCompiler = NULL;
alokp@chromium.org90033b92010-05-24 15:02:43 +0000260
261 ShFinalize();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000262}
263
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000264void Shader::parseVaryings()
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000265{
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000266 if (mHlsl)
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000267 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000268 const char *input = strstr(mHlsl, "// Varyings") + 12;
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000269
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000270 while(true)
271 {
272 char varyingType[256];
273 char varyingName[256];
274
daniel@transgaming.com7ea933f2010-12-12 08:52:42 +0000275 int matches = sscanf(input, "static %255s %255s", varyingType, varyingName);
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000276
277 if (matches != 2)
278 {
279 break;
280 }
281
282 char *array = strstr(varyingName, "[");
283 int size = 1;
284
285 if (array)
286 {
287 size = atoi(array + 1);
288 *array = '\0';
289 }
290
daniel@transgaming.comcde6a612012-02-17 18:01:10 +0000291 mVaryings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL));
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000292
293 input = strstr(input, ";") + 2;
294 }
295
296 mUsesFragCoord = strstr(mHlsl, "GL_USES_FRAG_COORD") != NULL;
297 mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL;
daniel@transgaming.combe5a0862010-07-28 19:20:37 +0000298 mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
299 mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL;
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000300 }
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000301}
302
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000303// initialize/clean up previous state
304void Shader::uncompile()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000305{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000306 // set by compileToHLSL
307 delete[] mHlsl;
308 mHlsl = NULL;
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000309 delete[] mInfoLog;
310 mInfoLog = NULL;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000311
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000312 // set by parseVaryings
313 mVaryings.clear();
314
315 mUsesFragCoord = false;
316 mUsesFrontFacing = false;
317 mUsesPointSize = false;
318 mUsesPointCoord = false;
319}
320
321void Shader::compileToHLSL(void *compiler)
322{
323 // ensure we don't pass a NULL source to the compiler
324 char *source = "\0";
325 if (mSource)
326 {
327 source = mSource;
328 }
329
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000330 // ensure the compiler is loaded
331 initializeCompiler();
332
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000333 int compileOptions = SH_OBJECT_CODE;
334 std::string sourcePath;
335 if (perfActive())
336 {
337 sourcePath = getTempPath();
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000338 writeFile(sourcePath.c_str(), source, strlen(source));
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000339 compileOptions |= SH_LINE_DIRECTIVES;
340 }
341
342 int result;
343 if (sourcePath.empty())
344 {
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000345 result = ShCompile(compiler, &source, 1, compileOptions);
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000346 }
347 else
348 {
349 const char* sourceStrings[2] =
350 {
351 sourcePath.c_str(),
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000352 source
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000353 };
354
355 result = ShCompile(compiler, sourceStrings, 2, compileOptions | SH_SOURCE_PATH);
356 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000357
358 if (result)
359 {
alokp@chromium.org7beea402010-09-15 21:18:34 +0000360 int objCodeLen = 0;
361 ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
362 mHlsl = new char[objCodeLen];
363 ShGetObjectCode(compiler, mHlsl);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000364 }
365 else
366 {
alokp@chromium.org7beea402010-09-15 21:18:34 +0000367 int infoLogLen = 0;
368 ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
369 mInfoLog = new char[infoLogLen];
370 ShGetInfoLog(compiler, mInfoLog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000371
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000372 TRACE("\n%s", mInfoLog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000373 }
374}
375
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000376GLenum Shader::parseType(const std::string &type)
377{
378 if (type == "float")
379 {
380 return GL_FLOAT;
381 }
382 else if (type == "float2")
383 {
384 return GL_FLOAT_VEC2;
385 }
386 else if (type == "float3")
387 {
388 return GL_FLOAT_VEC3;
389 }
390 else if (type == "float4")
391 {
392 return GL_FLOAT_VEC4;
393 }
394 else if (type == "float2x2")
395 {
396 return GL_FLOAT_MAT2;
397 }
398 else if (type == "float3x3")
399 {
400 return GL_FLOAT_MAT3;
401 }
402 else if (type == "float4x4")
403 {
404 return GL_FLOAT_MAT4;
405 }
406 else UNREACHABLE();
407
408 return GL_NONE;
409}
410
411// true if varying x has a higher priority in packing than y
412bool Shader::compareVarying(const Varying &x, const Varying &y)
413{
414 if(x.type == y.type)
415 {
416 return x.size > y.size;
417 }
418
419 switch (x.type)
420 {
421 case GL_FLOAT_MAT4: return true;
422 case GL_FLOAT_MAT2:
423 switch(y.type)
424 {
425 case GL_FLOAT_MAT4: return false;
426 case GL_FLOAT_MAT2: return true;
427 case GL_FLOAT_VEC4: return true;
428 case GL_FLOAT_MAT3: return true;
429 case GL_FLOAT_VEC3: return true;
430 case GL_FLOAT_VEC2: return true;
431 case GL_FLOAT: return true;
432 default: UNREACHABLE();
433 }
434 break;
435 case GL_FLOAT_VEC4:
436 switch(y.type)
437 {
438 case GL_FLOAT_MAT4: return false;
439 case GL_FLOAT_MAT2: return false;
440 case GL_FLOAT_VEC4: return true;
441 case GL_FLOAT_MAT3: return true;
442 case GL_FLOAT_VEC3: return true;
443 case GL_FLOAT_VEC2: return true;
444 case GL_FLOAT: return true;
445 default: UNREACHABLE();
446 }
447 break;
448 case GL_FLOAT_MAT3:
449 switch(y.type)
450 {
451 case GL_FLOAT_MAT4: return false;
452 case GL_FLOAT_MAT2: return false;
453 case GL_FLOAT_VEC4: return false;
454 case GL_FLOAT_MAT3: return true;
455 case GL_FLOAT_VEC3: return true;
456 case GL_FLOAT_VEC2: return true;
457 case GL_FLOAT: return true;
458 default: UNREACHABLE();
459 }
460 break;
461 case GL_FLOAT_VEC3:
462 switch(y.type)
463 {
464 case GL_FLOAT_MAT4: return false;
465 case GL_FLOAT_MAT2: return false;
466 case GL_FLOAT_VEC4: return false;
467 case GL_FLOAT_MAT3: return false;
468 case GL_FLOAT_VEC3: return true;
469 case GL_FLOAT_VEC2: return true;
470 case GL_FLOAT: return true;
471 default: UNREACHABLE();
472 }
473 break;
474 case GL_FLOAT_VEC2:
475 switch(y.type)
476 {
477 case GL_FLOAT_MAT4: return false;
478 case GL_FLOAT_MAT2: return false;
479 case GL_FLOAT_VEC4: return false;
480 case GL_FLOAT_MAT3: return false;
481 case GL_FLOAT_VEC3: return false;
482 case GL_FLOAT_VEC2: return true;
483 case GL_FLOAT: return true;
484 default: UNREACHABLE();
485 }
486 break;
487 case GL_FLOAT: return false;
488 default: UNREACHABLE();
489 }
490
491 return false;
492}
493
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000494VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000495{
496}
497
498VertexShader::~VertexShader()
499{
500}
501
502GLenum VertexShader::getType()
503{
504 return GL_VERTEX_SHADER;
505}
506
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000507void VertexShader::uncompile()
508{
509 Shader::uncompile();
510
511 // set by ParseAttributes
512 mAttributes.clear();
513};
514
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000515void VertexShader::compile()
516{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000517 uncompile();
518
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000519 compileToHLSL(mVertexCompiler);
520 parseAttributes();
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000521 parseVaryings();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000522}
523
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000524int VertexShader::getSemanticIndex(const std::string &attributeName)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000525{
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000526 if (!attributeName.empty())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000527 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000528 int semanticIndex = 0;
529 for (AttributeArray::iterator attribute = mAttributes.begin(); attribute != mAttributes.end(); attribute++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000530 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000531 if (attribute->name == attributeName)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000532 {
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000533 return semanticIndex;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000534 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000535
536 semanticIndex += VariableRowCount(attribute->type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000537 }
538 }
539
540 return -1;
541}
542
543void VertexShader::parseAttributes()
544{
daniel@transgaming.com2cdf8332012-02-17 18:00:50 +0000545 const char *hlsl = getHLSL();
546 if (hlsl)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000547 {
daniel@transgaming.com2cdf8332012-02-17 18:00:50 +0000548 const char *input = strstr(hlsl, "// Attributes") + 14;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000549
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000550 while(true)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000551 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000552 char attributeType[256];
553 char attributeName[256];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000554
daniel@transgaming.com7ea933f2010-12-12 08:52:42 +0000555 int matches = sscanf(input, "static %255s _%255s", attributeType, attributeName);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000556
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000557 if (matches != 2)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000558 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000559 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000560 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000561
562 mAttributes.push_back(Attribute(parseType(attributeType), attributeName));
563
564 input = strstr(input, ";") + 2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000565 }
566 }
567}
568
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000569FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000570{
571}
572
573FragmentShader::~FragmentShader()
574{
575}
576
577GLenum FragmentShader::getType()
578{
579 return GL_FRAGMENT_SHADER;
580}
581
582void FragmentShader::compile()
583{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000584 uncompile();
585
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000586 compileToHLSL(mFragmentCompiler);
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000587 parseVaryings();
daniel@transgaming.comcde6a612012-02-17 18:01:10 +0000588 mVaryings.sort(compareVarying);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000589}
590}