void Shader::build() { m_vertexShader = compileVertexShader(m_strVertexShader->cstr()); m_fragmentShader = compileFragmentShader(m_strFragmentShader->cstr()); m_shaderProgram = linkShaderProgram(m_vertexShader, m_fragmentShader); const SPVRTPFXUniformSemantic* semantics = PVRTPFXSemanticsGetSemanticList(); for (int i = 0; i < m_uniforms->count(); ++i) { SPVRTPFXUniform& uniform = m_uniforms->get(i); const SPVRTPFXUniformSemantic& semantic = semantics[uniform.nSemantic]; if (semantic.isAttrib) { uniform.nLocation = glGetAttribLocation(m_shaderProgram, uniform.sValueName->cstr()); m_isAttributeRequired[semantic.n] = true; ++m_numAttributesRequired; } else { uniform.nLocation = glGetUniformLocation(m_shaderProgram, uniform.sValueName->cstr()); // Check for array. Workaround for some OpenGL:ES implementations which require array element appended to uniform name // in order to return the correct location. if (uniform.nLocation == -1) { ByteArray* szTmpUniformName = ByteArray::create(uniform.sValueName->cstr()); szTmpUniformName->append("[0]"); uniform.nLocation = glGetUniformLocation(m_shaderProgram, szTmpUniformName->cstr()); } } } }
void Shader::processShader(StreamReader* reader, const char* endtag, ByteArray* soureCode) { while (!reader->endOfStream()) { ByteArray* line = reader->readLineToBytes(); if (line) { line->trim(); if (line->equals(endtag)) { return; } else if (line->equals("[GLSL]")) { while (!reader->endOfStream()) { ByteArray* line = reader->readLineToBytes(); if (line) { line->trim(); if (line->equals("[/GLSL]")) { break; } else { soureCode->append(line->cstr()); } } } } } } }
void Shader::processEffectInfo(StreamReader* reader) { while (!reader->endOfStream()) { ByteArray* line = reader->readLineToBytes(); if (line) { line->trim(); if (line->equals("[/EFFECT]")) { return; } else { List* params = line->split(NULL, 0); if (params->count() >= 2) { ByteArray* param0 = (ByteArray*)params->get(0); ByteArray* param1 = (ByteArray*)params->get(1); param0->toUpper(); // Name if (param0->equals("NAME")) { m_name = param1; m_name->retain(); } // Depth sorting else if (param0->equals("RENDERQUEUE")) { m_renderQueue = parseRenderQueueFromString(param1); } // Z-Writing else if (param0->equals("ZWRITE")) { m_isZWriting = param1->equalsIgnoreCase("On"); } // Face Culling else if (param0->equals("FACECULL")) { m_faceCullingMode = cullModeFromString(param1); } else if (param0->equals("ZTEST")) { if (param1->equalsIgnoreCase("Off")) { m_depthFunc = GL_ALWAYS; } else { m_depthFunc = depthFuncFromString(param1); } } else if (params->count() >= 3) { ByteArray* param2 = (ByteArray*)params->get(2); if (param0->equals("BLENDING")) { m_isAlphaBlending = true; m_blendingSource = alphaFactorFromString(param1); m_blendingDest = alphaFactorFromString(param2); } else if (param0->equals("ATTRIBUTE") || param0->equals("UNIFORM")) { SPVRTPFXUniform uniform; // Variable name uniform.sValueName = param1; param1->retain(); // Semantic index ByteArray* temp = ByteArray::create(param2->cstr()); if (ByteArray::isNumeric(temp->cstr()[param2->length() - 1])) { temp->subString(0, param2->length() - 1); } int len = 0; const SPVRTPFXUniformSemantic* semantics = PVRTPFXSemanticsGetSemanticList(); uniform.nSemantic = 0; for (int i = 0; i < ePVRTPFX_NumSemantics; ++i) { if (temp->equalsIgnoreCase(semantics[i].p)) { len = (int)strlen(semantics[i].p); uniform.nSemantic = i; break; } } uniform.nIdx = len < param2->length() ? param2->cstr()[len] - '0' : 0; // Location to be retrieve when compiling shader uniform.nLocation = 0; m_uniforms->add(uniform); } } } } } } }