blob: 9b65301e4a3ecab956f531ef4be12eb042d3ff26 [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();
31
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000032 // Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
33 if (!mFragmentCompiler)
34 {
35 int result = ShInitialize();
36
37 if (result)
38 {
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000039 ShBuiltInResources resources;
40 ShInitBuiltInResources(&resources);
zmo@google.com5601ea02011-06-10 18:23:25 +000041 Context *context = getContext();
daniel@transgaming.com396c6432010-11-26 16:26:12 +000042
alokp@chromium.org94a86ad2010-08-25 20:02:11 +000043 resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
44 resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
daniel@transgaming.com396c6432010-11-26 16:26:12 +000045 resources.MaxVaryingVectors = context->getMaximumVaryingVectors();
daniel@transgaming.comaf29cac2011-05-11 15:36:31 +000046 resources.MaxVertexTextureImageUnits = context->getMaximumVertexTextureImageUnits();
47 resources.MaxCombinedTextureImageUnits = context->getMaximumCombinedTextureImageUnits();
alokp@chromium.org94a86ad2010-08-25 20:02:11 +000048 resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
daniel@transgaming.com458da142010-11-28 02:03:02 +000049 resources.MaxFragmentUniformVectors = context->getMaximumFragmentUniformVectors();
alokp@chromium.org94a86ad2010-08-25 20:02:11 +000050 resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
alokp@chromium.orgd303ef92010-09-09 17:30:15 +000051 resources.OES_standard_derivatives = 1;
apatrick@chromium.org65756022012-01-17 21:45:38 +000052 // resources.OES_EGL_image_external = getDisplay()->isD3d9ExDevice() ? 1 : 0; // TODO: commented out until the extension is actually supported.
alokp@chromium.orge4249f02010-07-26 18:13:52 +000053
zmo@google.com5601ea02011-06-10 18:23:25 +000054 mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
55 mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000056 }
57 }
58
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000059 mRefCount = 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000060 mDeleteStatus = false;
61}
62
63Shader::~Shader()
64{
65 delete[] mSource;
66 delete[] mHlsl;
daniel@transgaming.comcba50572010-03-28 19:36:09 +000067 delete[] mInfoLog;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000068}
69
daniel@transgaming.com6c785212010-03-30 03:36:17 +000070GLuint Shader::getHandle() const
71{
72 return mHandle;
73}
74
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000075void Shader::setSource(GLsizei count, const char **string, const GLint *length)
76{
77 delete[] mSource;
78 int totalLength = 0;
79
80 for (int i = 0; i < count; i++)
81 {
82 if (length && length[i] >= 0)
83 {
84 totalLength += length[i];
85 }
86 else
87 {
88 totalLength += (int)strlen(string[i]);
89 }
90 }
91
92 mSource = new char[totalLength + 1];
93 char *code = mSource;
94
95 for (int i = 0; i < count; i++)
96 {
97 int stringLength;
98
99 if (length && length[i] >= 0)
100 {
101 stringLength = length[i];
102 }
103 else
104 {
105 stringLength = (int)strlen(string[i]);
106 }
107
108 strncpy(code, string[i], stringLength);
109 code += stringLength;
110 }
111
112 mSource[totalLength] = '\0';
113}
114
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000115int Shader::getInfoLogLength() const
116{
117 if (!mInfoLog)
118 {
119 return 0;
120 }
121 else
122 {
123 return strlen(mInfoLog) + 1;
124 }
125}
126
127void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
128{
129 int index = 0;
130
131 if (mInfoLog)
132 {
133 while (index < bufSize - 1 && index < (int)strlen(mInfoLog))
134 {
135 infoLog[index] = mInfoLog[index];
136 index++;
137 }
138 }
139
140 if (bufSize)
141 {
142 infoLog[index] = '\0';
143 }
144
145 if (length)
146 {
147 *length = index;
148 }
149}
150
151int Shader::getSourceLength() const
152{
153 if (!mSource)
154 {
155 return 0;
156 }
157 else
158 {
159 return strlen(mSource) + 1;
160 }
161}
162
zmo@google.coma574f782011-10-03 21:45:23 +0000163int Shader::getTranslatedSourceLength() const
164{
165 if (!mHlsl)
166 {
167 return 0;
168 }
169 else
170 {
171 return strlen(mHlsl) + 1;
172 }
173}
174
175void Shader::getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000176{
177 int index = 0;
178
zmo@google.coma574f782011-10-03 21:45:23 +0000179 if (source)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000180 {
zmo@google.coma574f782011-10-03 21:45:23 +0000181 while (index < bufSize - 1 && index < (int)strlen(source))
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000182 {
zmo@google.coma574f782011-10-03 21:45:23 +0000183 buffer[index] = source[index];
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000184 index++;
185 }
186 }
187
188 if (bufSize)
189 {
zmo@google.coma574f782011-10-03 21:45:23 +0000190 buffer[index] = '\0';
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000191 }
192
193 if (length)
194 {
195 *length = index;
196 }
197}
198
zmo@google.coma574f782011-10-03 21:45:23 +0000199void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer)
200{
201 getSourceImpl(mSource, bufSize, length, buffer);
202}
203
204void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
205{
206 getSourceImpl(mHlsl, bufSize, length, buffer);
207}
208
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000209bool Shader::isCompiled()
210{
211 return mHlsl != NULL;
212}
213
daniel@transgaming.com0e3358a2010-04-05 20:32:42 +0000214const char *Shader::getHLSL()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000215{
216 return mHlsl;
217}
218
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000219void Shader::addRef()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000220{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000221 mRefCount++;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000222}
223
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000224void Shader::release()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000225{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000226 mRefCount--;
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000227
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000228 if (mRefCount == 0 && mDeleteStatus)
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000229 {
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000230 mResourceManager->deleteShader(mHandle);
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000231 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000232}
233
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000234unsigned int Shader::getRefCount() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000235{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000236 return mRefCount;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000237}
238
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000239bool Shader::isFlaggedForDeletion() const
240{
241 return mDeleteStatus;
242}
243
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000244void Shader::flagForDeletion()
245{
246 mDeleteStatus = true;
247}
248
249void Shader::releaseCompiler()
250{
251 ShDestruct(mFragmentCompiler);
252 ShDestruct(mVertexCompiler);
253
254 mFragmentCompiler = NULL;
255 mVertexCompiler = NULL;
alokp@chromium.org90033b92010-05-24 15:02:43 +0000256
257 ShFinalize();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000258}
259
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000260void Shader::parseVaryings()
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000261{
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000262 if (mHlsl)
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000263 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000264 const char *input = strstr(mHlsl, "// Varyings") + 12;
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000265
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000266 while(true)
267 {
268 char varyingType[256];
269 char varyingName[256];
270
daniel@transgaming.com7ea933f2010-12-12 08:52:42 +0000271 int matches = sscanf(input, "static %255s %255s", varyingType, varyingName);
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000272
273 if (matches != 2)
274 {
275 break;
276 }
277
278 char *array = strstr(varyingName, "[");
279 int size = 1;
280
281 if (array)
282 {
283 size = atoi(array + 1);
284 *array = '\0';
285 }
286
daniel@transgaming.comcde6a612012-02-17 18:01:10 +0000287 mVaryings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL));
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000288
289 input = strstr(input, ";") + 2;
290 }
291
292 mUsesFragCoord = strstr(mHlsl, "GL_USES_FRAG_COORD") != NULL;
293 mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL;
daniel@transgaming.combe5a0862010-07-28 19:20:37 +0000294 mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
295 mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL;
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000296 }
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +0000297}
298
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000299// initialize/clean up previous state
300void Shader::uncompile()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000301{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000302 // set by compileToHLSL
303 delete[] mHlsl;
304 mHlsl = NULL;
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000305 delete[] mInfoLog;
306 mInfoLog = NULL;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000307
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000308 // set by parseVaryings
309 mVaryings.clear();
310
311 mUsesFragCoord = false;
312 mUsesFrontFacing = false;
313 mUsesPointSize = false;
314 mUsesPointCoord = false;
315}
316
317void Shader::compileToHLSL(void *compiler)
318{
319 // ensure we don't pass a NULL source to the compiler
320 char *source = "\0";
321 if (mSource)
322 {
323 source = mSource;
324 }
325
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000326 int compileOptions = SH_OBJECT_CODE;
327 std::string sourcePath;
328 if (perfActive())
329 {
330 sourcePath = getTempPath();
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000331 writeFile(sourcePath.c_str(), source, strlen(source));
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000332 compileOptions |= SH_LINE_DIRECTIVES;
333 }
334
335 int result;
336 if (sourcePath.empty())
337 {
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000338 result = ShCompile(compiler, &source, 1, compileOptions);
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000339 }
340 else
341 {
342 const char* sourceStrings[2] =
343 {
344 sourcePath.c_str(),
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000345 source
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000346 };
347
348 result = ShCompile(compiler, sourceStrings, 2, compileOptions | SH_SOURCE_PATH);
349 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000350
351 if (result)
352 {
alokp@chromium.org7beea402010-09-15 21:18:34 +0000353 int objCodeLen = 0;
354 ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
355 mHlsl = new char[objCodeLen];
356 ShGetObjectCode(compiler, mHlsl);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000357 }
358 else
359 {
alokp@chromium.org7beea402010-09-15 21:18:34 +0000360 int infoLogLen = 0;
361 ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
362 mInfoLog = new char[infoLogLen];
363 ShGetInfoLog(compiler, mInfoLog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000364
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000365 TRACE("\n%s", mInfoLog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000366 }
367}
368
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000369GLenum Shader::parseType(const std::string &type)
370{
371 if (type == "float")
372 {
373 return GL_FLOAT;
374 }
375 else if (type == "float2")
376 {
377 return GL_FLOAT_VEC2;
378 }
379 else if (type == "float3")
380 {
381 return GL_FLOAT_VEC3;
382 }
383 else if (type == "float4")
384 {
385 return GL_FLOAT_VEC4;
386 }
387 else if (type == "float2x2")
388 {
389 return GL_FLOAT_MAT2;
390 }
391 else if (type == "float3x3")
392 {
393 return GL_FLOAT_MAT3;
394 }
395 else if (type == "float4x4")
396 {
397 return GL_FLOAT_MAT4;
398 }
399 else UNREACHABLE();
400
401 return GL_NONE;
402}
403
404// true if varying x has a higher priority in packing than y
405bool Shader::compareVarying(const Varying &x, const Varying &y)
406{
407 if(x.type == y.type)
408 {
409 return x.size > y.size;
410 }
411
412 switch (x.type)
413 {
414 case GL_FLOAT_MAT4: return true;
415 case GL_FLOAT_MAT2:
416 switch(y.type)
417 {
418 case GL_FLOAT_MAT4: return false;
419 case GL_FLOAT_MAT2: return true;
420 case GL_FLOAT_VEC4: return true;
421 case GL_FLOAT_MAT3: return true;
422 case GL_FLOAT_VEC3: return true;
423 case GL_FLOAT_VEC2: return true;
424 case GL_FLOAT: return true;
425 default: UNREACHABLE();
426 }
427 break;
428 case GL_FLOAT_VEC4:
429 switch(y.type)
430 {
431 case GL_FLOAT_MAT4: return false;
432 case GL_FLOAT_MAT2: return false;
433 case GL_FLOAT_VEC4: return true;
434 case GL_FLOAT_MAT3: return true;
435 case GL_FLOAT_VEC3: return true;
436 case GL_FLOAT_VEC2: return true;
437 case GL_FLOAT: return true;
438 default: UNREACHABLE();
439 }
440 break;
441 case GL_FLOAT_MAT3:
442 switch(y.type)
443 {
444 case GL_FLOAT_MAT4: return false;
445 case GL_FLOAT_MAT2: return false;
446 case GL_FLOAT_VEC4: return false;
447 case GL_FLOAT_MAT3: return true;
448 case GL_FLOAT_VEC3: return true;
449 case GL_FLOAT_VEC2: return true;
450 case GL_FLOAT: return true;
451 default: UNREACHABLE();
452 }
453 break;
454 case GL_FLOAT_VEC3:
455 switch(y.type)
456 {
457 case GL_FLOAT_MAT4: return false;
458 case GL_FLOAT_MAT2: return false;
459 case GL_FLOAT_VEC4: return false;
460 case GL_FLOAT_MAT3: return false;
461 case GL_FLOAT_VEC3: return true;
462 case GL_FLOAT_VEC2: return true;
463 case GL_FLOAT: return true;
464 default: UNREACHABLE();
465 }
466 break;
467 case GL_FLOAT_VEC2:
468 switch(y.type)
469 {
470 case GL_FLOAT_MAT4: return false;
471 case GL_FLOAT_MAT2: return false;
472 case GL_FLOAT_VEC4: return false;
473 case GL_FLOAT_MAT3: return false;
474 case GL_FLOAT_VEC3: return false;
475 case GL_FLOAT_VEC2: return true;
476 case GL_FLOAT: return true;
477 default: UNREACHABLE();
478 }
479 break;
480 case GL_FLOAT: return false;
481 default: UNREACHABLE();
482 }
483
484 return false;
485}
486
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000487VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000488{
489}
490
491VertexShader::~VertexShader()
492{
493}
494
495GLenum VertexShader::getType()
496{
497 return GL_VERTEX_SHADER;
498}
499
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000500void VertexShader::uncompile()
501{
502 Shader::uncompile();
503
504 // set by ParseAttributes
505 mAttributes.clear();
506};
507
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000508void VertexShader::compile()
509{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000510 uncompile();
511
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000512 compileToHLSL(mVertexCompiler);
513 parseAttributes();
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000514 parseVaryings();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000515}
516
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000517int VertexShader::getSemanticIndex(const std::string &attributeName)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000518{
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000519 if (!attributeName.empty())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000520 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000521 int semanticIndex = 0;
522 for (AttributeArray::iterator attribute = mAttributes.begin(); attribute != mAttributes.end(); attribute++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000523 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000524 if (attribute->name == attributeName)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000525 {
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000526 return semanticIndex;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000527 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000528
529 semanticIndex += VariableRowCount(attribute->type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000530 }
531 }
532
533 return -1;
534}
535
536void VertexShader::parseAttributes()
537{
daniel@transgaming.com2cdf8332012-02-17 18:00:50 +0000538 const char *hlsl = getHLSL();
539 if (hlsl)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000540 {
daniel@transgaming.com2cdf8332012-02-17 18:00:50 +0000541 const char *input = strstr(hlsl, "// Attributes") + 14;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000542
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000543 while(true)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000544 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000545 char attributeType[256];
546 char attributeName[256];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000547
daniel@transgaming.com7ea933f2010-12-12 08:52:42 +0000548 int matches = sscanf(input, "static %255s _%255s", attributeType, attributeName);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000549
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000550 if (matches != 2)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000551 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000552 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000553 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000554
555 mAttributes.push_back(Attribute(parseType(attributeType), attributeName));
556
557 input = strstr(input, ";") + 2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000558 }
559 }
560}
561
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000562FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000563{
564}
565
566FragmentShader::~FragmentShader()
567{
568}
569
570GLenum FragmentShader::getType()
571{
572 return GL_FRAGMENT_SHADER;
573}
574
575void FragmentShader::compile()
576{
daniel@transgaming.com938009c2012-02-17 18:02:15 +0000577 uncompile();
578
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000579 compileToHLSL(mFragmentCompiler);
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000580 parseVaryings();
daniel@transgaming.comcde6a612012-02-17 18:01:10 +0000581 mVaryings.sort(compareVarying);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000582}
583}