bool ImageData::GetUniqueFileName(string &retString) const { //Set the initial image name retString = ""; //Append the image type switch(glType) { case(GL_TEXTURE_1D): retString = retString + "1D_"; break; case(GL_TEXTURE_2D): retString = retString + "2D_"; break; case(GL_TEXTURE_3D): retString = retString + "3D_"; break; case(GL_TEXTURE_CUBE_MAP): retString = retString + "CUBE_"; break; case(GL_TEXTURE_RECTANGLE): retString = retString + "NVRECT_"; break; case(GL_TEXTURE_1D_ARRAY): retString = retString + "1D_ARRAY_"; break; case(GL_TEXTURE_2D_ARRAY): retString = retString + "2D_ARRAY_"; break; case(GL_TEXTURE_BUFFER): retString = retString + "TEX_BUFFER_"; break; default: retString = retString + "UNKNOWN_"; break; } //Add an extra flag for p-buffers if(IsPBufferBound()) { retString = retString + "PBuf_"; } //Add the texture ID string bufString; StringPrintF(bufString,"%04u_",id); retString = retString + bufString; //Add the save count static uint saveCount=0; saveCount++; StringPrintF(bufString,"%04u",saveCount); retString = retString + bufString; return true; }
void ShaderUtilsGLSL::AppendShaderStrings(const vector<ShaderStrData> & srcStrings, string & retString) { // Append the strings based on shader types - vertex shader, geometry shader, fragment shader string knownShaderTypes[NUM_SHADER_TYPE_MAP]; string unknownShaderTypes; // Loop for all the shader strings for(uint i = 0; i < srcStrings.size(); i++) { // Get the type string int typeIndex = GetShaderTypeIndex(srcStrings[i].shaderType); if(typeIndex >= 0) { knownShaderTypes[typeIndex] += "\n[" + string(s_shaderTypeMappings[typeIndex].shaderTypeName) + " Shader]\n"; knownShaderTypes[typeIndex] += srcStrings[i].shaderStr; } else { // Format the unknown type string typeStr; StringPrintF(typeStr, "\n[Type = 0x%X Shader]\n", srcStrings[i].shaderType); unknownShaderTypes += typeStr; unknownShaderTypes += srcStrings[i].shaderStr; } } // Append all strings to the return string for(uint i = 0; i < NUM_SHADER_TYPE_MAP; i++) { retString += knownShaderTypes[i]; } retString += unknownShaderTypes; }
void ShaderEditASM::FormatCompileErrorLocation(const string &programSource, GLint errorPos, string &retLog) { //Get the number of lines uint lineNum = 1; uint charNum = 1; for(GLint i=0; i<errorPos && i<(int)programSource.size(); i++) { //Count the number of new lines if(programSource[i] == '\n') { lineNum++; charNum = 1; } else { charNum++; } } //Copy five characters near the error string errorData(programSource,errorPos,5); //Append the error string data string buffer; StringPrintF(buffer,"line %u, column %u: Compile error near >%s< char (%d)\n", lineNum, charNum, errorData.c_str(), errorPos); retLog += buffer; }
bool DisplayListData::GetUniqueFileName(string &retString) const { //Set the initial display list name retString = "DisplayList_"; //Add the display list ID string bufString; StringPrintF(bufString,"%04u_",id); retString = retString + bufString; //Add the save count static uint saveCount=0; saveCount++; StringPrintF(bufString,"%04u",saveCount); retString = retString + bufString; return true; }
bool ShaderData::GetUniqueFileName(string &retString) const { //Set the initial shader name retString = ""; //Append the shader type switch(glType) { //NV vertex programs have the same token case(GL_VERTEX_PROGRAM_ARB): retString = retString + "VP_"; break; case(GL_FRAGMENT_PROGRAM_ARB): retString = retString + "FP_"; break; case(GL_FRAGMENT_PROGRAM_NV): retString = retString + "FPNV_"; break; case(GL_VERTEX_STATE_PROGRAM_NV): retString = retString + "VPSTATENV_"; break; default: retString = retString + "UNKNOWN_"; break; } //Add the shader ID string bufString; StringPrintF(bufString,"%04u_",id); retString = retString + bufString; //Add the save count static uint saveCount=0; saveCount++; StringPrintF(bufString,"%04u",saveCount); retString = retString + bufString; return true; }
bool SubstituteShaderGLSL::TestUniformDataCopy(UniformData &remapData, string &retLog) const { string bufferStr; //Test for OpenGL errors during copy if(gliCallBacks->GetCoreGLFunctions()->glGetError() != GL_NO_ERROR) { StringPrintF(bufferStr,"Existing OpenGL error - fix application?\n"); retLog += bufferStr; } //Check the size if(remapData.size > remapData.indexData.size()) { StringPrintF(bufferStr,"%s - Invalid uniform size values\n",remapData.name.c_str()); retLog += bufferStr; return false; } //Get the uniform data from the old program //Note: This may crash on some implementations (eg ATI Cat 5.9) // if the new array is smaller than the old uniform data array. // (ATI returns the complete array size on each glGetUniform call - which may // overwrite the end of the array if the array size has shrunk in the new program). shaderUtils.GetUniformValues(oldProgramID, remapData); //If a error occured during retrieval if(gliCallBacks->GetCoreGLFunctions()->glGetError() != GL_NO_ERROR) { StringPrintF(bufferStr," %s - OpenGL error on uniform copy - (broken drivers?)\n", remapData.name.c_str()); retLog += bufferStr; return false; } return true; }
void InterceptLog::GetErrorStringValue(uint errorCode, string &retString) { //If we do no have the index of glGetError yet, get it if(glGetErrorFuncIndex < 0) { //Get the index of the function glGetErrorFuncIndex = functionTable->FindFunction("glGetError"); } //If there is a valid index const FunctionData * glGetErrorFuncData = NULL; if(glGetErrorFuncIndex != -1) { //Get the function data // (Note: The returned pointer is not permanent (as future calls may add to the table) // so we can only store the function index) glGetErrorFuncData = functionTable->GetFunctionData(glGetErrorFuncIndex); } //If the function is still not found, just log the number if(glGetErrorFuncData == NULL || glGetErrorFuncData->returnType.type != PT_enum) { StringPrintF(retString,"0x%04x",errorCode); } else { //Get the return parameter const ParameterData * returnData = &glGetErrorFuncData->returnType; //Get the string version ParamValue value; value.enumValue = errorCode; retString = ConvertParam(value, false, returnData); } }
bool ShaderUtilsGLSL::GetUniformData(GLuint programHandle, UniformDataArray &retData) const { //Empty the return array retData.clear(); //Get if OpenGL calls can be made if(!gliCallBacks->GetGLInternalCallState()) { return false; } //Get the number of uniforms for the program GLint numUniforms = 0; iglGetProgramiv(programHandle, GL_ACTIVE_UNIFORMS, &numUniforms); if(numUniforms <= 0) { return true; } //Get the max uniform string size GLint maxUniformSize = 0; iglGetProgramiv(programHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize); if(maxUniformSize <= 0) { return false; } //Allocate the array to get the uniform strings GLchar * readUniformName = new GLchar[maxUniformSize+1]; //Loop for the number of uniforms in the program for(uint i=0;i<(uint)numUniforms;i++) { GLint typeSize=0; GLenum type; GLsizei lengthWritten=0; string newUniformName; //Call GetActiveUniform to get the name,type and size of the type iglGetActiveUniform(programHandle,i,maxUniformSize,&lengthWritten,&typeSize,&type,readUniformName); if(lengthWritten > 0) { //Convert to a string newUniformName = (char*)readUniformName; //Nvidia/ATI Hack ====================================== // Nvidia (in 69.xx drivers) and ATI Cat 5.9 return a uniform for every element of arrays. // Only take note of the first one and ignore the rest bool ignoreUniform = false; if(newUniformName.length() > 3 && newUniformName[newUniformName.length()-1] == ']') { //If the characters end with "[0]" if(newUniformName[newUniformName.length()-2] == '0' && newUniformName[newUniformName.length()-3] == '[') { //Erase the last three characters newUniformName.erase(newUniformName.length()-3, 3); LOGERR(("Nvidia/ATI uniform array workaround for %s",newUniformName.c_str())); } else { //Don't process this uniform ignoreUniform = true; } } //End Hack ====================================== //Ignore built in gl types if(newUniformName.find("gl_") != 0 && !ignoreUniform) { //Loop for the array size for the type vector<uint> indexDataArray; for(GLint s=0; s<typeSize; s++) { string testUniformName = newUniformName; if(s > 0) { //If it is an array type, get the index of each component string strBuffer; StringPrintF(strBuffer, "[%u]",s); testUniformName += strBuffer; } //Get the location of the uniform GLint uniLocation = iglGetUniformLocation(programHandle,(const GLchar*)testUniformName.c_str()); if(uniLocation < 0) { LOGERR(("GetUniformData - Uniform %s does not exist?",testUniformName.c_str())); //Clean up the uniform name delete [] readUniformName; return false; } //Add to the index data array indexDataArray.push_back(uniLocation); } UniformData newData; newData.indexData = indexDataArray; newData.remapIndex = 0; newData.name = newUniformName; newData.size = typeSize; newData.type = type; //Check that the type is known if(!GetTypeData(newData.type, newData.numTypeElements, newData.baseFormat)) { LOGERR(("GetUniformData - %s - Uniform is not a known type: 0x%x\n", newData.name.c_str(), newData.type)); //Clean up the uniform name delete [] readUniformName; return false; } //Add the new data to the return array retData.push_back(newData); } } } //Clean up the uniform name delete [] readUniformName; return true; }
string EnumData::GetDisplayString(uint value) const { //Check for a bit mask if(!isBitMask) { //Look for the value int index = GetEnumIndex(value); if(index != -1) { return enumValues[index].name; } else { //Add the value to the buffer string retString; StringPrintF(retString,"0x%04x",value); return retString; } } else { string bitMaskStr; bool firstBit =true; //Loop and test all bits for(uint i=0;i<sizeof(uint)*8;i++) { uint mask = ((uint)1 << i); //Test if the mask value is used if(value & mask) { //Add a seperator if(!firstBit) { bitMaskStr = bitMaskStr + " | "; } else { firstBit =false; } //Look-up the mask value int index = GetEnumIndex(mask); if(index != -1) { bitMaskStr = bitMaskStr + enumValues[index].name; } else { //Add the mask value to the buffer string retString; StringPrintF(retString,"0x%04x",mask); bitMaskStr = bitMaskStr + retString; } } } //Assign a zero string for no bits if(firstBit) { //Ensure this is no "zero mask" value int index = GetEnumIndex(value); if(index != -1) { return enumValues[index].name; } else { bitMaskStr = "0x000000"; } } //Return the mask return bitMaskStr; } }
void BacteroidsState::Render() { Renderer &renderer = GetRenderer(); renderer.SetTime(m_time.GetTimeMicros()); renderer.SetView(m_playView); renderer.BindColorShader(); renderer.SetColor(Color(0.05f, 0.13f, 0.15f)); renderer.DrawFilledRectangle(PLAY_AREA_LEFT, PLAY_AREA_BOTTOM, PLAY_AREA_RIGHT, PLAY_AREA_TOP); for (size_t_32 i = 0; i < m_objects.Size(); i++) { GameObject *obj = m_objects[i]; vec2f p = obj->GetPosition(); float r = obj->GetRadius() * 1.1f; if ((p.x > PLAY_AREA_LEFT - r && p.x < PLAY_AREA_RIGHT + r && p.y > PLAY_AREA_BOTTOM - r && p.y < PLAY_AREA_TOP + r) == false) { continue; } renderer.BindShader(obj->GetShader()); const vec2f vel2 = obj->GetVelocity(); const vec4f velocity(vel2.x, vel2.y, 0.0f, 0.0f); renderer.GetGraphics()->SetUniform(m_uniforms.m_velocity, velocity); obj->Render(&renderer, m_uniforms); } renderer.BindColorShader(); m_damageFade.Render(&renderer); m_pauseFade.Render(&renderer); renderer.SetView(GetDefaultView()); if (m_time.IsPaused()) { RenderPause(); } else if (m_player.IsDead()) { RenderGameOver(); } { TextLayout layout(renderer, 0.0f, 0.0f); renderer.BindFontShader(); renderer.SetColor(Color(1.0f, 1.0f, 1.0f)); renderer.SetFontScale(1.0f); char buf[64]; StringPrintF(buf, "Score: %i", m_score); layout.AddText(buf, 0.0f); layout.AddLine(); StringPrintF(buf, "Kills: %i", m_kills); layout.AddText(buf, 0.0f); layout.AddLine(); const float ptPerKill = (m_kills) ? (m_score / float(m_kills)) : 0; StringPrintF(buf, "pt per kill: %.1f", ptPerKill); layout.AddText(buf, 0.0f); layout.AddLine(); const float hx = 10.0f; const float hy = layout.m_cursor.y + 10.0f; renderer.BindColorShader(); renderer.SetColor(Color(0.5f, 0.5f, 0.5f)); renderer.DrawFilledRectangle(hx, hy, hx + 100.0f, hy + 10.0f); renderer.SetColor(Color(0.85f, 0.05f, 0.05f)); renderer.DrawFilledRectangle(hx, hy, hx + m_player.GetHealth(), hy + 10.0f); } { const Viewport vp = renderer.GetView().m_viewport; TextLayout layout(renderer, 0.0f, vp.h); renderer.BindFontShader(); renderer.SetColor(Color(1.0f, 1.0f, 1.0f)); renderer.SetFontScale(1.0f); char buf[64]; StringPrintF(buf, "[M] - Muted: %s", GetAudio().IsMuted() ? "yes" : "no"); layout.AddLines(-1); layout.AddText(buf, 0.0f); } }
void GLDriver::ProcessFrameEnd() { #ifdef GLI_BUILD_LINUX //Update the X-Windows keyboard state inputUtils.Update(GLW.glXGetCurrentDisplay()); #endif //GLI_BUILD_LINUX //Increment the frame number frameNumber++; //Check if we log per-frame bool logStateChange =false; if(configData.logPerFrame) { static bool previousState=false; //Check if the key state has changed if(inputUtils.IsAllKeyDown(configData.logFrameKeys) != previousState) { previousState = !previousState; //Only toggle the logging on the key down if(previousState) { logStateChange = true; } } //If we are only logging one frame at a time if(configData.logOneFrameOnly) { //Disable the logger if it was enabled from a pervious frame if(loggingEnabled) { logStateChange = true; } } } //Check if the limit of how many frame can be logged has been reached. if(loggingEnabled && configData.logMaxFrameLoggingEnabled && frameNumber - loggingStartFrameNum >= configData.logMaxNumLogFrames) { logStateChange = true; } //If a change in per-frame saving occured if(logStateChange) { //If the log is not currently enabled if(!loggingEnabled) { //Flag logging as enabled loggingEnabled = true; loggingStartFrameNum = frameNumber; //Assign the current logging directory string dirString; StringPrintF(dirString,"Frame_%06u",frameNumber); currLogDir = configData.logPath + dirString + FileUtils::dirSeparator; //Loop through all the contexts and set all data as dirty for(uint i=0;i<glContextArray.size();i++) { glContextArray[i]->SetLoggerDataDirty(); } //Init the logger if(configData.logEnabled) { InitFunctionLog(); } //Activate the context if(glContext) { glContext->ActivateLoggers(currLogDir); } } else { // Flag logging as disabled loggingEnabled = false; //Delete the existing logger (if any) if(interceptLog) { delete interceptLog; interceptLog = NULL; } //Suspend the context if(glContext) { glContext->SuspendLoggers(); } } } }
void SubstituteShaderGLSL::GenerateUniformRemapArray(string &initLog) { uint i; string bufferStr; //Get the uniforms of the old program UniformDataArray oldUniformData; if(!shaderUtils.GetUniformData(oldProgramID, oldUniformData)) { initLog += "Unble to get old program unform data\n"; return; } //Get the uniforms of the new program UniformDataArray newUniformData; if(!shaderUtils.GetUniformData(programID, newUniformData)) { initLog += "Unble to get new program unform data\n"; return; } //Clear the mapping array remapUniformArray.clear(); //Loop for all values in the old array for(i=0; i<oldUniformData.size(); i++) { bool foundFlag = false; const UniformData & oldData = oldUniformData[i]; //Loop for all new values for(uint i2=0; i2<newUniformData.size(); i2++) { const UniformData & newData = newUniformData[i2]; //Check for a name match if(oldData.name == newData.name) { foundFlag = true; //Check the types and abort if not equal if(oldData.type != newData.type) { StringPrintF(bufferStr," %s - Uniforms types are different\n",oldData.name.c_str()); initLog += bufferStr; break; } //Check the sizes uint addDataTypeSize = oldData.size; if(oldData.size != newData.size) { StringPrintF(bufferStr," %s - Uniform sizes are different (%u != %u)\n", oldData.name.c_str(),oldData.size,newData.size); initLog += bufferStr; //Take the minimum of the two sizes if(newData.size < addDataTypeSize) { addDataTypeSize = newData.size; } } //Check the type size if(addDataTypeSize == 0) { StringPrintF(bufferStr," %s - Uniform size is zero?\n", oldData.name.c_str()); initLog += bufferStr; break; } //Create a new entry in the mapping array UniformData addData; addData.indexData = oldData.indexData; addData.remapIndex = newData.indexData[0]; addData.name = newData.name; addData.size = addDataTypeSize; addData.type = newData.type; //Get the data about the type if(!shaderUtils.GetTypeData(addData.type, addData.numTypeElements, addData.baseFormat)) { StringPrintF(bufferStr," %s - Uniform is not a known type: 0x%x\n", addData.name.c_str(),addData.type); initLog += bufferStr; break; } //Test if the data can be copied without OpenGL errors (ATI bug) if(TestUniformDataCopy(addData, initLog)) { //Add the data to the array remapUniformArray.push_back(addData); } #ifdef GLI_ATI_UNIFORM_GLSL_BUG //If it is just a single variable (hopefully a sampler), use the ATI override else if(addData.baseFormat == GL_INT && addData.numTypeElements == 1) { initLog += string("Using ATI uniform override on ") + addData.name + string("\n"); addData.isATIUniformOverride = true; remapUniformArray.push_back(addData); } #endif //GLI_ATI_UNIFORM_GLSL_BUG break; } } //If not found if(!foundFlag) { StringPrintF(bufferStr," %s - Uniform not found in new program\n", oldData.name.c_str()); initLog += bufferStr; } } //Log all the new uniforms not in the old program for(i=0; i<newUniformData.size(); i++) { bool foundFlag = false; const UniformData & newData = newUniformData[i]; //Loop for all old values for(uint i2=0; i2<oldUniformData.size(); i2++) { const UniformData & oldData = oldUniformData[i2]; //Check for a name match if(oldData.name == newData.name) { foundFlag = true; break; } } //If not found if(!foundFlag) { StringPrintF(bufferStr," %s - Uniform in new program -not in old program\n", newData.name.c_str()); initLog += bufferStr; } } }
string InterceptLog::ConvertParam(const ParamValue &data, bool isPointer,const ParameterData *paramData) { string retString; //If the data is a custom type, attempt to handle it if(paramData->IsCustomType() && ConvertCustomParam(data,isPointer,paramData,retString)) { return retString; } //If this is a pointer, out-put the address if(isPointer) { //Just get the pointer's address StringPrintF(retString,"%p",data.pointerValue); } else { //Do a big switch statement ParameterType pType=paramData->GetGLType(); switch(pType) { case(PT_enum): { //Get the enum data const EnumData * enumData=functionTable->GetEnumData(paramData->index); //If the index is invalid, Just print the hex values if(enumData ==NULL) { StringPrintF(retString,"0x%04x", data.enumValue); } else { retString = enumData->GetDisplayString(data.enumValue); } } break; case(PT_bitfield): { //Get the enum data const EnumData * enumData=functionTable->GetEnumData(paramData->index); //If the index is invalid, Just print the hex values if(enumData ==NULL) { StringPrintF(retString,"0x%04x", data.bitfieldValue); } else { retString = enumData->GetDisplayString(data.bitfieldValue); } } break; case(PT_boolean): { int num = data.booleanValue; //Check the value if(num == 0) { retString = "false"; } else if(num == 1) { retString = "true"; } else { StringPrintF(retString,"Invalid boolean %u",num); } break; } case(PT_void): break; case(PT_byte): { StringPrintF(retString,"%d",data.byteValue); break; } case(PT_short): { StringPrintF(retString,"%d",data.shortValue); break; } case(PT_int): { StringPrintF(retString,"%d",data.intValue); break; } case(PT_sizei): { CASSERT(sizeof(data.sizeiValue) == sizeof(int), __Update_type_printf__); StringPrintF(retString,"%d",data.sizeiValue); break; } case(PT_ubyte): { StringPrintF(retString,"%u",data.ubyteValue); break; } case(PT_char): { StringPrintF(retString,"%c",data.charValue); break; } case(PT_ushort): { StringPrintF(retString,"%u",data.ushortValue); break; } case(PT_uint): case(PT_handle): { StringPrintF(retString,"%u",data.uintValue); break; } case(PT_intptr): { ostringstream s1; s1 << data.intptrValue; retString = s1.str(); break; } case(PT_sizeiptr): { ostringstream s1; s1 << data.sizeiptrValue; retString = s1.str(); break; } case(PT_int64): { ostringstream s1; s1 << data.int64Value; retString = s1.str(); break; } case(PT_uint64): { ostringstream s1; s1 << data.uint64Value; retString = s1.str(); break; } case(PT_sync): { ostringstream s1; s1 << data.syncValue; retString = s1.str(); break; } case(PT_float): { StringPrintF(retString,"%f",data.floatValue); break; } case(PT_double): { StringPrintF(retString,"%f",data.doubleValue); break; } default: LOGERR(("InterceptLog::ConvertParam - Unhandled parameter in function of type %d",(int)pType)); } } return retString; }