blob: 1087f11b4af9e545c3467cff3e3a427957165aa2 [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
daniel@transgaming.com29ab9522012-08-27 16:25:37 +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
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000105 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000106 {
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000107 if (mInfoLog)
108 {
109 index = std::min(bufSize - 1, (int)strlen(mInfoLog));
110 memcpy(infoLog, mInfoLog, index);
111 }
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000112
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000113 infoLog[index] = '\0';
114 }
115
116 if (length)
117 {
118 *length = index;
119 }
120}
121
122int Shader::getSourceLength() const
123{
124 if (!mSource)
125 {
126 return 0;
127 }
128 else
129 {
130 return strlen(mSource) + 1;
131 }
132}
133
zmo@google.coma574f782011-10-03 21:45:23 +0000134int Shader::getTranslatedSourceLength() const
135{
136 if (!mHlsl)
137 {
138 return 0;
139 }
140 else
141 {
142 return strlen(mHlsl) + 1;
143 }
144}
145
146void Shader::getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000147{
148 int index = 0;
149
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000150 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000151 {
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000152 if (source)
153 {
154 index = std::min(bufSize - 1, (int)strlen(source));
155 memcpy(buffer, source, index);
156 }
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000157
zmo@google.coma574f782011-10-03 21:45:23 +0000158 buffer[index] = '\0';
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000159 }
160
161 if (length)
162 {
163 *length = index;
164 }
165}
166
zmo@google.coma574f782011-10-03 21:45:23 +0000167void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer)
168{
169 getSourceImpl(mSource, bufSize, length, buffer);
170}
171
172void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
173{
174 getSourceImpl(mHlsl, bufSize, length, buffer);
175}
176
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000177bool Shader::isCompiled()
178{
179 return mHlsl != NULL;
180}
181
daniel@transgaming.com0e3358a2010-04-05 20:32:42 +0000182const char *Shader::getHLSL()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000183{
184 return mHlsl;
185}
186
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000187void Shader::addRef()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000188{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000189 mRefCount++;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000190}
191
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000192void Shader::release()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000193{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000194 mRefCount--;
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000195
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000196 if (mRefCount == 0 && mDeleteStatus)
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000197 {
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000198 mResourceManager->deleteShader(mHandle);
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000199 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000200}
201
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000202unsigned int Shader::getRefCount() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000203{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000204 return mRefCount;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000205}
206
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000207bool Shader::isFlaggedForDeletion() const
208{
209 return mDeleteStatus;
210}
211
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000212void Shader::flagForDeletion()
213{
214 mDeleteStatus = true;
215}
216
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000217// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
218void Shader::initializeCompiler()
219{
220 if (!mFragmentCompiler)
221 {
222 int result = ShInitialize();
223
224 if (result)
225 {
226 ShBuiltInResources resources;
227 ShInitBuiltInResources(&resources);
228 Context *context = getContext();
229
230 resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
231 resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
232 resources.MaxVaryingVectors = context->getMaximumVaryingVectors();
233 resources.MaxVertexTextureImageUnits = context->getMaximumVertexTextureImageUnits();
234 resources.MaxCombinedTextureImageUnits = context->getMaximumCombinedTextureImageUnits();
235 resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
236 resources.MaxFragmentUniformVectors = context->getMaximumFragmentUniformVectors();
237 resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
238 resources.OES_standard_derivatives = 1;
239 // resources.OES_EGL_image_external = getDisplay()->isD3d9ExDevice() ? 1 : 0; // TODO: commented out until the extension is actually supported.
240
241 mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
242 mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
243 }
244 }
245}
246
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000247void Shader::releaseCompiler()
248{
249 ShDestruct(mFragmentCompiler);
250 ShDestruct(mVertexCompiler);
251
252 mFragmentCompiler = NULL;
253 mVertexCompiler = NULL;
alokp@chromium.org90033b92010-05-24 15:02:43 +0000254
255 ShFinalize();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000256}
257
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000258void Shader::parseVaryings()
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000259{
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000260 if (mHlsl)
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000261 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000262 const char *input = strstr(mHlsl, "// Varyings") + 12;
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000263
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000264 while(true)
265 {
266 char varyingType[256];
267 char varyingName[256];
268
daniel@transgaming.com7ea933f2010-12-12 08:52:42 +0000269 int matches = sscanf(input, "static %255s %255s", varyingType, varyingName);
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000270
271 if (matches != 2)
272 {
273 break;
274 }
275
276 char *array = strstr(varyingName, "[");
277 int size = 1;
278
279 if (array)
280 {
281 size = atoi(array + 1);
282 *array = '\0';
283 }
284
daniel@transgaming.comcde6a612012-02-17 18:01:10 +0000285 mVaryings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL));
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000286
287 input = strstr(input, ";") + 2;
288 }
289
290 mUsesFragCoord = strstr(mHlsl, "GL_USES_FRAG_COORD") != NULL;
291 mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL;
daniel@transgaming.combe5a0862010-07-28 19:20:37 +0000292 mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
293 mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL;
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000294 }
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000295}
296
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000297// initialize/clean up previous state
298void Shader::uncompile()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000299{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000300 // set by compileToHLSL
301 delete[] mHlsl;
302 mHlsl = NULL;
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000303 delete[] mInfoLog;
304 mInfoLog = NULL;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000305
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000306 // set by parseVaryings
307 mVaryings.clear();
308
309 mUsesFragCoord = false;
310 mUsesFrontFacing = false;
311 mUsesPointSize = false;
312 mUsesPointCoord = false;
313}
314
315void Shader::compileToHLSL(void *compiler)
316{
317 // ensure we don't pass a NULL source to the compiler
318 char *source = "\0";
319 if (mSource)
320 {
321 source = mSource;
322 }
323
daniel@transgaming.com0725e7d2012-02-17 18:02:20 +0000324 // ensure the compiler is loaded
325 initializeCompiler();
326
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000327 int compileOptions = SH_OBJECT_CODE;
328 std::string sourcePath;
329 if (perfActive())
330 {
331 sourcePath = getTempPath();
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000332 writeFile(sourcePath.c_str(), source, strlen(source));
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000333 compileOptions |= SH_LINE_DIRECTIVES;
334 }
335
336 int result;
337 if (sourcePath.empty())
338 {
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000339 result = ShCompile(compiler, &source, 1, compileOptions);
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000340 }
341 else
342 {
343 const char* sourceStrings[2] =
344 {
345 sourcePath.c_str(),
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000346 source
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000347 };
348
349 result = ShCompile(compiler, sourceStrings, 2, compileOptions | SH_SOURCE_PATH);
350 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000351
352 if (result)
353 {
alokp@chromium.org7beea402010-09-15 21:18:34 +0000354 int objCodeLen = 0;
355 ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
356 mHlsl = new char[objCodeLen];
357 ShGetObjectCode(compiler, mHlsl);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000358 }
359 else
360 {
alokp@chromium.org7beea402010-09-15 21:18:34 +0000361 int infoLogLen = 0;
362 ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
363 mInfoLog = new char[infoLogLen];
364 ShGetInfoLog(compiler, mInfoLog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000365
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000366 TRACE("\n%s", mInfoLog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000367 }
368}
369
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000370GLenum Shader::parseType(const std::string &type)
371{
372 if (type == "float")
373 {
374 return GL_FLOAT;
375 }
376 else if (type == "float2")
377 {
378 return GL_FLOAT_VEC2;
379 }
380 else if (type == "float3")
381 {
382 return GL_FLOAT_VEC3;
383 }
384 else if (type == "float4")
385 {
386 return GL_FLOAT_VEC4;
387 }
388 else if (type == "float2x2")
389 {
390 return GL_FLOAT_MAT2;
391 }
392 else if (type == "float3x3")
393 {
394 return GL_FLOAT_MAT3;
395 }
396 else if (type == "float4x4")
397 {
398 return GL_FLOAT_MAT4;
399 }
400 else UNREACHABLE();
401
402 return GL_NONE;
403}
404
405// true if varying x has a higher priority in packing than y
406bool Shader::compareVarying(const Varying &x, const Varying &y)
407{
408 if(x.type == y.type)
409 {
410 return x.size > y.size;
411 }
412
413 switch (x.type)
414 {
415 case GL_FLOAT_MAT4: return true;
416 case GL_FLOAT_MAT2:
417 switch(y.type)
418 {
419 case GL_FLOAT_MAT4: return false;
420 case GL_FLOAT_MAT2: return true;
421 case GL_FLOAT_VEC4: return true;
422 case GL_FLOAT_MAT3: return true;
423 case GL_FLOAT_VEC3: return true;
424 case GL_FLOAT_VEC2: return true;
425 case GL_FLOAT: return true;
426 default: UNREACHABLE();
427 }
428 break;
429 case GL_FLOAT_VEC4:
430 switch(y.type)
431 {
432 case GL_FLOAT_MAT4: return false;
433 case GL_FLOAT_MAT2: return false;
434 case GL_FLOAT_VEC4: return true;
435 case GL_FLOAT_MAT3: return true;
436 case GL_FLOAT_VEC3: return true;
437 case GL_FLOAT_VEC2: return true;
438 case GL_FLOAT: return true;
439 default: UNREACHABLE();
440 }
441 break;
442 case GL_FLOAT_MAT3:
443 switch(y.type)
444 {
445 case GL_FLOAT_MAT4: return false;
446 case GL_FLOAT_MAT2: return false;
447 case GL_FLOAT_VEC4: return false;
448 case GL_FLOAT_MAT3: return true;
449 case GL_FLOAT_VEC3: return true;
450 case GL_FLOAT_VEC2: return true;
451 case GL_FLOAT: return true;
452 default: UNREACHABLE();
453 }
454 break;
455 case GL_FLOAT_VEC3:
456 switch(y.type)
457 {
458 case GL_FLOAT_MAT4: return false;
459 case GL_FLOAT_MAT2: return false;
460 case GL_FLOAT_VEC4: return false;
461 case GL_FLOAT_MAT3: return false;
462 case GL_FLOAT_VEC3: return true;
463 case GL_FLOAT_VEC2: return true;
464 case GL_FLOAT: return true;
465 default: UNREACHABLE();
466 }
467 break;
468 case GL_FLOAT_VEC2:
469 switch(y.type)
470 {
471 case GL_FLOAT_MAT4: return false;
472 case GL_FLOAT_MAT2: return false;
473 case GL_FLOAT_VEC4: return false;
474 case GL_FLOAT_MAT3: return false;
475 case GL_FLOAT_VEC3: return false;
476 case GL_FLOAT_VEC2: return true;
477 case GL_FLOAT: return true;
478 default: UNREACHABLE();
479 }
480 break;
481 case GL_FLOAT: return false;
482 default: UNREACHABLE();
483 }
484
485 return false;
486}
487
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000488VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000489{
490}
491
492VertexShader::~VertexShader()
493{
494}
495
496GLenum VertexShader::getType()
497{
498 return GL_VERTEX_SHADER;
499}
500
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000501void VertexShader::uncompile()
502{
503 Shader::uncompile();
504
505 // set by ParseAttributes
506 mAttributes.clear();
507};
508
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000509void VertexShader::compile()
510{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000511 uncompile();
512
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000513 compileToHLSL(mVertexCompiler);
514 parseAttributes();
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000515 parseVaryings();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000516}
517
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000518int VertexShader::getSemanticIndex(const std::string &attributeName)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000519{
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000520 if (!attributeName.empty())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000521 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000522 int semanticIndex = 0;
523 for (AttributeArray::iterator attribute = mAttributes.begin(); attribute != mAttributes.end(); attribute++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000524 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000525 if (attribute->name == attributeName)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000526 {
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000527 return semanticIndex;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000528 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000529
530 semanticIndex += VariableRowCount(attribute->type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000531 }
532 }
533
534 return -1;
535}
536
537void VertexShader::parseAttributes()
538{
daniel@transgaming.com2cdf8332012-02-17 18:00:50 +0000539 const char *hlsl = getHLSL();
540 if (hlsl)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000541 {
daniel@transgaming.com2cdf8332012-02-17 18:00:50 +0000542 const char *input = strstr(hlsl, "// Attributes") + 14;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000543
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000544 while(true)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000545 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000546 char attributeType[256];
547 char attributeName[256];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000548
daniel@transgaming.com7ea933f2010-12-12 08:52:42 +0000549 int matches = sscanf(input, "static %255s _%255s", attributeType, attributeName);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000550
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000551 if (matches != 2)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000552 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000553 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000554 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000555
556 mAttributes.push_back(Attribute(parseType(attributeType), attributeName));
557
558 input = strstr(input, ";") + 2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000559 }
560 }
561}
562
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000563FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000564{
565}
566
567FragmentShader::~FragmentShader()
568{
569}
570
571GLenum FragmentShader::getType()
572{
573 return GL_FRAGMENT_SHADER;
574}
575
576void FragmentShader::compile()
577{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000578 uncompile();
579
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000580 compileToHLSL(mFragmentCompiler);
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000581 parseVaryings();
daniel@transgaming.comcde6a612012-02-17 18:01:10 +0000582 mVaryings.sort(compareVarying);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000583}
584}