void CLevel::CreateEntitiesFromData(const CData* pData) { m_aLevelEntities.clear(); m_iNextHandle = 0; for (size_t i = 0; i < pData->GetNumChildren(); i++) { CData* pChildData = pData->GetChild(i); if (pChildData->GetKey() != "Entity") continue; m_aLevelEntities.push_back(CLevelEntity(m_iNextHandle++, pChildData->GetValueString())); CLevelEntity* pEntity = &m_aLevelEntities.back(); pEntity->m_iHandle = m_aLevelEntities.size()-1; for (size_t k = 0; k < pChildData->GetNumChildren(); k++) { CData* pField = pChildData->GetChild(k); tstring sHandle = pField->GetKey(); tstring sValue = pField->GetValueString(); if (sHandle == "Output") { tstring sTarget; tstring sInput; tstring sArgs; bool bKill = false; for (size_t o = 0; o < pField->GetNumChildren(); o++) { CData* pOutputData = pField->GetChild(o); if (pOutputData->GetKey() == "Target") sTarget = pOutputData->GetValueString(); else if (pOutputData->GetKey() == "Input") sInput = pOutputData->GetValueString(); else if (pOutputData->GetKey() == "Args") sArgs = pOutputData->GetValueString(); else if (pOutputData->GetKey() == "Kill") bKill = pOutputData->GetValueBool(); } CLevelEntity::CLevelEntityOutput& oOutput = pEntity->GetOutputs().push_back(); oOutput.m_sOutput = sValue; oOutput.m_sTargetName = sTarget; oOutput.m_sInput = sInput; oOutput.m_sArgs = sArgs; oOutput.m_bKill = bKill; } else { pEntity->SetParameterValue(sHandle, sValue); } } } }
bool CShader::Compile() { string sShaderHeader = CShaderLibrary::GetShaderHeader(); if (CShaderLibrary::Get()->m_iSamples) sShaderHeader += "#define USE_MULTISAMPLE_TEXTURES 1\n"; sShaderHeader += CShaderLibrary::GetShaderFunctions(); FILE* f = tfopen("shaders/" + m_sVertexFile + ".vs", "r"); TAssert(f); if (!f) return false; string sVertexShader = sShaderHeader; sVertexShader += "uniform mat4x4 mProjection;\n"; sVertexShader += "uniform mat4x4 mView;\n"; sVertexShader += "uniform mat4x4 mGlobal;\n"; string sLine; while (fgetts(sLine, f)) sVertexShader += sLine; fclose(f); f = tfopen("shaders/" + m_sFragmentFile + ".fs", "r"); TAssert(f); if (!f) return false; string sFragmentShader = sShaderHeader; sFragmentShader += "out vec4 vecOutputColor;\n"; while (fgetts(sLine, f)) sFragmentShader += sLine; fclose(f); size_t iVShader = glCreateShader(GL_VERTEX_SHADER); const char* pszStr = sVertexShader.c_str(); glShaderSource((GLuint)iVShader, 1, &pszStr, NULL); glCompileShader((GLuint)iVShader); int iVertexCompiled; glGetShaderiv((GLuint)iVShader, GL_COMPILE_STATUS, &iVertexCompiled); if (iVertexCompiled != GL_TRUE || Application()->HasCommandLineSwitch("--debug-gl")) { int iLogLength = 0; char szLog[1024]; glGetShaderInfoLog((GLuint)iVShader, 1024, &iLogLength, szLog); CShaderLibrary::Get()->WriteLog(m_sVertexFile + ".vs", szLog, pszStr); } size_t iFShader = glCreateShader(GL_FRAGMENT_SHADER); pszStr = sFragmentShader.c_str(); glShaderSource((GLuint)iFShader, 1, &pszStr, NULL); glCompileShader((GLuint)iFShader); int iFragmentCompiled; glGetShaderiv((GLuint)iFShader, GL_COMPILE_STATUS, &iFragmentCompiled); if (iFragmentCompiled != GL_TRUE || Application()->HasCommandLineSwitch("--debug-gl")) { int iLogLength = 0; char szLog[1024]; glGetShaderInfoLog((GLuint)iFShader, 1024, &iLogLength, szLog); CShaderLibrary::Get()->WriteLog(m_sFragmentFile + ".fs", szLog, pszStr); } size_t iProgram = glCreateProgram(); glBindAttribLocation(iProgram, 0, "vecPosition"); // Force position at location 0. ATI cards won't work without this. glAttachShader((GLuint)iProgram, (GLuint)iVShader); glAttachShader((GLuint)iProgram, (GLuint)iFShader); glLinkProgram((GLuint)iProgram); int iProgramLinked; glGetProgramiv((GLuint)iProgram, GL_LINK_STATUS, &iProgramLinked); if (iProgramLinked != GL_TRUE || Application()->HasCommandLineSwitch("--debug-gl")) { int iLogLength = 0; char szLog[1024]; glGetProgramInfoLog((GLuint)iProgram, 1024, &iLogLength, szLog); CShaderLibrary::Get()->WriteLog("link", szLog, "link"); } if (iVertexCompiled != GL_TRUE || iFragmentCompiled != GL_TRUE || iProgramLinked != GL_TRUE) { TAssert(false); // Shader compilation failed. Check shaders.txt Destroy(); return false; } m_iProgram = iProgram; m_iVShader = iVShader; m_iFShader = iFShader; m_iPositionAttribute = glGetAttribLocation(m_iProgram, "vecPosition"); m_iNormalAttribute = glGetAttribLocation(m_iProgram, "vecNormal"); m_iTangentAttribute = glGetAttribLocation(m_iProgram, "vecTangent"); m_iBitangentAttribute = glGetAttribLocation(m_iProgram, "vecBitangent"); for (size_t i = 0; i < MAX_TEXTURE_CHANNELS; i++) m_aiTexCoordAttributes[i] = glGetAttribLocation(m_iProgram, sprintf("vecTexCoord%d", i).c_str()); m_iColorAttribute = glGetAttribLocation(m_iProgram, "vecVertexColor"); glBindFragDataLocation(m_iProgram, 0, "vecOutputColor"); TAssert(m_iPositionAttribute != ~0); int iNumUniforms; glGetProgramiv(m_iProgram, GL_ACTIVE_UNIFORMS, &iNumUniforms); char szUniformName[256]; GLsizei iLength; GLint iSize; GLenum iType; for (int i = 0; i < iNumUniforms; i++) { glGetActiveUniform(m_iProgram, i, sizeof(szUniformName), &iLength, &iSize, &iType, szUniformName); string sUniformName = szUniformName; if (sUniformName == "mProjection") continue; if (sUniformName == "mView") continue; if (sUniformName == "mGlobal") continue; CShader::CUniform& oUniform = m_asUniforms[sUniformName]; oUniform.m_pDefault = nullptr; switch (iType) { case GL_FLOAT: oUniform.m_sUniformType = "float"; break; case GL_FLOAT_VEC2: oUniform.m_sUniformType = "vec2"; break; case GL_FLOAT_VEC3: oUniform.m_sUniformType = "vec3"; break; case GL_FLOAT_VEC4: oUniform.m_sUniformType = "vec4"; break; case GL_INT: oUniform.m_sUniformType = "int"; break; case GL_BOOL: oUniform.m_sUniformType = "bool"; break; case GL_FLOAT_MAT4: oUniform.m_sUniformType = "mat4"; break; case GL_SAMPLER_2D: oUniform.m_sUniformType = "sampler2D"; break; default: TUnimplemented(); } } for (auto it = m_aParameters.begin(); it != m_aParameters.end(); it++) { for (size_t j = 0; j < it->second.m_aActions.size(); j++) { auto it2 = m_asUniforms.find(it->second.m_aActions[j].m_sName); TAssert(it2 != m_asUniforms.end()); if (it2 == m_asUniforms.end()) { TAssert(false); // A shader specifies a uniform that is not in the linked program. continue; } CShader::CUniform& oUniform = it2->second; // This is almost cheating CData d; d.SetValue(it->second.m_aActions[j].m_sValue); if (oUniform.m_sUniformType == "float") it->second.m_aActions[j].m_flValue = d.GetValueFloat(); else if (oUniform.m_sUniformType == "vec2") it->second.m_aActions[j].m_vec2Value = d.GetValueVector2D(); else if (oUniform.m_sUniformType == "vec3") it->second.m_aActions[j].m_vecValue = d.GetValueVector(); else if (oUniform.m_sUniformType == "vec4") it->second.m_aActions[j].m_vec4Value = d.GetValueVector4D(); else if (oUniform.m_sUniformType == "int") it->second.m_aActions[j].m_iValue = d.GetValueInt(); else if (oUniform.m_sUniformType == "bool") it->second.m_aActions[j].m_bValue = d.GetValueBool(); else if (oUniform.m_sUniformType == "mat4") { TUnimplemented(); } else if (oUniform.m_sUniformType == "sampler2D") { // No op. } else TUnimplemented(); } } for (auto it = m_aDefaults.begin(); it != m_aDefaults.end(); it++) { auto it2 = m_asUniforms.find(it->first); TAssert(it2 != m_asUniforms.end()); if (it2 == m_asUniforms.end()) { TAssert(false); // A shader specifies a default for a uniform that is not in the linked program. continue; } CShader::CUniform& oUniform = it2->second; oUniform.m_pDefault = &it->second; // Again with the cheating. CData d; d.SetValue(it->second.m_sValue); if (oUniform.m_sUniformType == "float") it->second.m_flValue = d.GetValueFloat(); else if (oUniform.m_sUniformType == "vec2") it->second.m_vec2Value = d.GetValueVector2D(); else if (oUniform.m_sUniformType == "vec3") it->second.m_vecValue = d.GetValueVector(); else if (oUniform.m_sUniformType == "vec4") it->second.m_vec4Value = d.GetValueVector4D(); else if (oUniform.m_sUniformType == "int") it->second.m_iValue = d.GetValueInt(); else if (oUniform.m_sUniformType == "bool") it->second.m_bValue = d.GetValueBool(); else if (oUniform.m_sUniformType == "mat4") { TUnimplemented(); } else if (oUniform.m_sUniformType == "sampler2D") { TUnimplemented(); // Can't set a default texture... yet. } else TUnimplemented(); } return true; }
void CInstructor::ReadLesson(const class CData* pData) { tstring sLessonName = pData->GetValueString(); if (!sLessonName.length()) { TError("Found a lesson with no name.\n"); return; } CLesson* pLesson = new CLesson(this, sLessonName); m_apLessons[sLessonName] = pLesson; for (size_t i = 0; i < pData->GetNumChildren(); i++) { CData* pChildData = pData->GetChild(i); if (pChildData->GetKey() == "Position") { tstring sPosition = pChildData->GetValueString(); if (sPosition == "top-center") pLesson->m_iPosition = POSITION_TOPCENTER; else if (sPosition == "top-left") pLesson->m_iPosition = POSITION_TOPLEFT; else if (sPosition == "left") pLesson->m_iPosition = POSITION_LEFT; } else if (pChildData->GetKey() == "Width") pLesson->m_iWidth = pChildData->GetValueInt(); else if (pChildData->GetKey() == "Next") pLesson->m_sNextLesson = pChildData->GetValueString(); else if (pChildData->GetKey() == "Text") pLesson->m_sText = pChildData->GetValueString(); else if (pChildData->GetKey() == "SlideAmount") pLesson->m_flSlideAmount = pChildData->GetValueFloat(); else if (pChildData->GetKey() == "SlideX") pLesson->m_bSlideX = pChildData->GetValueBool(); else if (pChildData->GetKey() == "Rotation") pLesson->m_bRotation = pChildData->GetValueBool(); else if (pChildData->GetKey() == "Output") ReadLessonOutput(pChildData, pLesson); else if (pChildData->GetKey() == "Priority") pLesson->m_iPriority = pChildData->GetValueInt(); else if (pChildData->GetKey() == "LessonType") { tstring sLessonType = pChildData->GetValueString(); if (sLessonType == "button") pLesson->m_iLessonType = CLesson::LESSON_BUTTON; else if (sLessonType == "info") pLesson->m_iLessonType = CLesson::LESSON_INFO; else if (sLessonType == "environment") pLesson->m_iLessonType = CLesson::LESSON_ENVIRONMENT; } else if (pChildData->GetKey() == "LearningMethod") { tstring sLearningMethod = pChildData->GetValueString(); if (sLearningMethod == "displaying") pLesson->m_iLearningMethod = CLesson::LEARN_DISPLAYING; else if (sLearningMethod == "display") pLesson->m_iLearningMethod = CLesson::LEARN_DISPLAYING; else if (sLearningMethod == "performing") pLesson->m_iLearningMethod = CLesson::LEARN_PERFORMING; else if (sLearningMethod == "perform") pLesson->m_iLearningMethod = CLesson::LEARN_PERFORMING; } else if (pChildData->GetKey() == "TimesToLearn") pLesson->m_iTimesToLearn = pChildData->GetValueInt(); else if (pChildData->GetKey() == "Conditions") pLesson->m_pfnConditions = Game_GetInstructorConditions(pChildData->GetValueString()); // A dirty hack, but not a scary one. } }