int ShaderModuleRepository::releaseProgram(IProgram *p) { if(!p) return -1; ProgVec::iterator it = m_programs.begin(); while(it != m_programs.end()) { if((*it).p == p) { int a = p->getProgram(); //for debug int c = --(*it).refCnt; #ifdef _DEBUG LOGD("Program %d (", (*it).p->getProgram() ); IShader* pshd; for(int ii=0; pshd = (*it).p->getShader(ii); ii++) LOGD("%s ", pshd->getName()); LOGD(") "); #endif if(c <= 0) { #ifdef _DEBUG LOGD("no more used. REMOVING it from ShaderModuleRepository\n", a); #endif m_programs.erase(it); return 0; } else #ifdef _DEBUG LOGD("still used (%d). KEEPING it in ShaderModuleRepository\n", a, c); #endif return c; } ++it; } return -1; }
void construct_shaders() { IShader* global_shader = shader_for_remap("*"); unsigned int numSurfaces = m_model->GetNumSurfaces(); m_shaders.reserve(numSurfaces); // now go through our surface and find our shaders, remap if needed for(unsigned int j = 0; j < numSurfaces; j++ ) { const char* surfShaderName = m_model->GetShaderNameForSurface(j); IShader* shader = shader_for_remap(surfShaderName); // Determine which shader it is going to be if( !shader ) { if( global_shader ) { shader = global_shader; } else { shader = QERApp_Shader_ForName(surfShaderName); } } // Add reference shader->IncRef(); // Done, continue m_shaders.push_back( shader ); } }
void AddFaceWithTextureScaled(scene::Node* brush, vec3_t va, vec3_t vb, vec3_t vc, const char* texture, bool bVertScale, bool bHorScale, float minX, float minY, float maxX, float maxY) { qtexture_t* pqtTexInfo; // TTimo: there used to be a call to pfnHasShader here // this was not necessary. In Radiant everything is shader. // If a texture doesn't have a shader script, a default shader object is used. // The IShader object was leaking also // collect texture info: sizes, etc IShader* i = QERApp_Shader_ForName(texture); pqtTexInfo = i->getTexture(); // shader width/height doesn't come out properly if(pqtTexInfo) { float scale[2] = {0.5f, 0.5f}; float shift[2] = {0, 0}; if(bHorScale) { int texWidth = pqtTexInfo->width; float width = maxX - minX; scale[0] = width/texWidth; shift[0] = -(float)((int)maxX%(int)width)/scale[0]; } if(bVertScale) { int texHeight = pqtTexInfo->height; float height = maxY - minY; scale[1] = height/texHeight; shift[1] = (float)((int)minY%(int)height)/scale[1]; } _QERFaceData addFace; FillDefaultTexture(&addFace, va, vb, vc, texture); addFace.m_texdef.scale[0] = scale[0]; addFace.m_texdef.scale[1] = scale[1]; addFace.m_texdef.shift[0] = shift[0]; addFace.m_texdef.shift[1] = shift[1]; #if 0 brush->m_brush->addPlane(addFace.m_p0, addFace.m_p1, addFace.m_p2, addFace.m_texdef); #endif } else { // shouldn't even get here, as default missing texture should be returned if // texture doesn't exist, but just in case AddFaceWithTexture(brush, va, vb, vc, texture, FALSE); Sys_ERROR("BobToolz::Invalid Texture Name-> %s", texture); } // the IShader is not kept referenced, DecRef it i->DecRef(); }
void AddFaceWithTextureScaled(scene::Node& brush, vec3_t va, vec3_t vb, vec3_t vc, const char* texture, bool bVertScale, bool bHorScale, float minX, float minY, float maxX, float maxY) { qtexture_t* pqtTexInfo; // TTimo: there used to be a call to pfnHasShader here // this was not necessary. In Radiant everything is shader. // If a texture doesn't have a shader script, a default shader object is used. // The IShader object was leaking also // collect texture info: sizes, etc IShader* i = GlobalShaderSystem().getShaderForName(texture); pqtTexInfo = i->getTexture(); // shader width/height doesn't come out properly if(pqtTexInfo) { float scale[2] = {0.5f, 0.5f}; float shift[2] = {0, 0}; if(bHorScale) { float width = maxX - minX; scale[0] = width/pqtTexInfo->width; shift[0] = -(float)((int)maxX%(int)width)/scale[0]; } if(bVertScale) { float height = maxY - minY; scale[1] = height/pqtTexInfo->height; shift[1] = (float)((int)minY%(int)height)/scale[1]; } _QERFaceData addFace; FillDefaultTexture(&addFace, va, vb, vc, texture); addFace.m_texdef.scale[0] = scale[0]; addFace.m_texdef.scale[1] = scale[1]; addFace.m_texdef.shift[0] = shift[0]; addFace.m_texdef.shift[1] = shift[1]; GlobalBrushCreator().Brush_addFace(brush, addFace); } else { // shouldn't even get here, as default missing texture should be returned if // texture doesn't exist, but just in case AddFaceWithTexture(brush, va, vb, vc, texture, false); globalErrorStream() << "BobToolz::Invalid Texture Name-> " << texture; } // the IShader is not kept referenced, DecRef it i->DecRef(); }
// GTK CALLBACKS void TexturePreviewCombo::_onExpose (GtkWidget* widget, GdkEventExpose* ev, TexturePreviewCombo* self) { // Grab the GLWidget with sentry gtkutil::GLWidgetSentry sentry(widget); // Initialise viewport glClearColor(0.3, 0.3, 0.3, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable( GL_DEPTH_TEST); glEnable( GL_TEXTURE_2D); // If no texture is loaded, leave window blank if (self->_texName.empty()) return; glMatrixMode( GL_PROJECTION); glLoadIdentity(); glOrtho(0, 1, 0, 1, -1, 1); // Get a reference to the selected shader IShader* shader = GlobalShaderSystem().getShaderForName(self->_texName); // Bind the texture from the shader GLTexture* tex = shader->getTexture(); glBindTexture(GL_TEXTURE_2D, tex->texture_number); // Calculate the correct aspect ratio for preview float aspect = float(tex->width) / float(tex->height); float hfWidth, hfHeight; if (aspect > 1.0) { hfWidth = 0.5; hfHeight = 0.5 / aspect; } else { hfHeight = 0.5; hfWidth = 0.5 * aspect; } // Draw a polygon glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glColor3f(1, 1, 1); glBegin( GL_QUADS); glTexCoord2i(0, 1); glVertex2f(0.5 - hfWidth, 0.5 - hfHeight); glTexCoord2i(1, 1); glVertex2f(0.5 + hfWidth, 0.5 - hfHeight); glTexCoord2i(1, 0); glVertex2f(0.5 + hfWidth, 0.5 + hfHeight); glTexCoord2i(0, 0); glVertex2f(0.5 - hfWidth, 0.5 + hfHeight); glEnd(); shader->DecRef(); }
void CShaderArray::ReleaseForShaderFile( const char *name ){ int i; // decref for ( i = 0; i < CPtrArray::GetSize(); i++ ) { IShader *pShader = static_cast < IShader * >( CPtrArray::GetAt( i ) ); if ( !strcmp( name, pShader->getShaderFileName() ) ) { pShader->DecRef(); CPtrArray::RemoveAt( i ); i--; // get ready for next loop } } }
void Triangle(Matrix43f float_clip_coords, IShader& shader) { Matrix43i clip_coords = Round(float_clip_coords); Vector2i min_bound = { Min(clip_coords[0]), Min(clip_coords[1]) }; Vector2i max_bound = { Max(clip_coords[0]), Max(clip_coords[1]) }; min_bound.x = std::max(min_bound.x, 0); min_bound.y = std::max(min_bound.y, 0); max_bound.x = std::min(max_bound.x, this->get_width() - 1); max_bound.y = std::min(max_bound.y, this->get_height() - 1); Vector2i a = { clip_coords[0][0], clip_coords[1][0] }; Vector2i b = { clip_coords[0][1], clip_coords[1][1] }; Vector2i c = { clip_coords[0][2], clip_coords[1][2] }; TGAColor color; for (int x = min_bound.x; x <= max_bound.x; ++x) { for (int y = min_bound.y; y <= max_bound.y; ++y) { Vector3f bc = Barycentric(a, b, c, Vector2i{ x, y }); if (bc.x < 0 || bc.y < 0 || bc.z < 0) { continue; } bool discard = shader.Fragment(bc, color); if (!discard) { float z_depth = bc * float_clip_coords[2]; this->Set(x, y, z_depth, color); } } } }
static void find_clicked( GtkWidget *widget, gpointer data ){ GtkWidget *menu, *item; menu = gtk_menu_new(); for ( int i = 0; i < QERApp_GetActiveShaderCount(); i++ ) { IShader *pShader = QERApp_ActiveShader_ForIndex( i ); item = gtk_menu_item_new_with_label( pShader->getName() ); g_signal_connect( G_OBJECT( item ), "activate", G_CALLBACK( popup_selected ), data ); gtk_widget_show( item ); gtk_menu_shell_append( GTK_MENU_SHELL( menu ), item ); } gtk_menu_popup( GTK_MENU( menu ), NULL, NULL, NULL, NULL, 1, GDK_CURRENT_TIME ); }
void PrintShaderContents( int dllID ) { IShaderDLLInternal *pShaderDLL = g_ShaderDLLs[dllID].m_pInternal; int nShaders = pShaderDLL->ShaderCount(); int i; printf( "<H2>%s</H2><BR>\n", g_ShaderDLLs[dllID].m_Filename ); printf( "<dl>\n" ); // define list for( i = 0; i < nShaders; i++ ) { IShader *pShader = pShaderDLL->GetShader( i ); printf( "<A HREF=\"#%s_%s\">\n", g_ShaderDLLs[dllID].m_Filename, pShader->GetName() ); printf( "<dt>%s</A>\n", pShader->GetName() ); // int nParams = pShader->GetNumParams(); } printf( "</dl>\n" ); // end define list }
IShader* ResMgr::LoadShader(const std::string& vsh, const std::string& fsh) { std::string key = vsh + fsh; std::map<std::string , IShader*>::iterator result = m_shaders.find(key); if(result!= m_shaders.end()) { IShader* pRes = result->second; return pRes; } IShader* pShader = (IShader*)GetMgr()->Create("Shader"); pShader->SetResMgr(this); pShader->Load(vsh.c_str(), fsh.c_str()); m_shaders[key] = pShader; return pShader; }
void SceneManager::DrawWaypoints(IShader& shader) { std::map<unsigned int, AIPath>::iterator iter = m_AIPaths.begin(); for (iter; iter != m_AIPaths.end(); ++iter) { if (iter->second.IsVisible()) { std::vector<glm::vec3> path = iter->second.GetWaypoints(); for (int i = 0; i < path.size(); ++i) { glm::mat4 translation; translation = glm::translate(translation, path[i]); shader.SetWorldMatrix(translation); m_miscObjects["waypoint"]->Draw(); if (iter->second.IsClosed()) { if (path.size() > 1 && (i - 1) < path.size()) { glBegin(GL_LINES); glm::vec3 cpos = path[i - 1]; glm::vec3 npos = path[i]; glm::vec3 min = cpos - npos; glVertex3f(0, 5, 0); glVertex3f(min.x, min.y + 5, min.z); glEnd(); } if (path.size() > 2 && (i) == path.size() - 1) { glBegin(GL_LINES); glm::vec3 cpos = path[0]; glm::vec3 npos = path[path.size() - 1]; glm::vec3 min = cpos - npos; glVertex3f(0, 5, 0); glVertex3f(min.x, min.y + 5, min.z); glEnd(); } } else { if (path.size() > 1 && (i - 1) < path.size()) { glBegin(GL_LINES); glm::vec3 cpos = path[i - 1]; glm::vec3 npos = path[i]; glm::vec3 min = cpos - npos; glVertex3f(0, 5, 0); glVertex3f(min.x, min.y + 5, min.z); glEnd(); } } } } } }
void PrintShaderHelp( int dllID ) { IShaderDLLInternal *pShaderDLL = g_ShaderDLLs[dllID].m_pInternal; int nShaders = pShaderDLL->ShaderCount(); int i; printf( "<H2>%s</H2><BR>\n", g_ShaderDLLs[dllID].m_Filename ); printf( "<dl>\n" ); // define list for( i = 0; i < nShaders; i++ ) { IShader *pShader = pShaderDLL->GetShader( i ); printf( "<A NAME=\"%s_%s\"></A>\n", g_ShaderDLLs[dllID].m_Filename, pShader->GetName() ); printf( "<dt>%s<dl>\n", pShader->GetName() ); int nParams = pShader->GetNumParams(); int j; for( j = 0; j < nParams; j++ ) { printf( "<dt>%s\n<dd>%s\n", pShader->GetParamName( j ), pShader->GetParamHelp( j ) ); } printf( "</dl><br>\n" ); // end define list } printf( "</dl>\n" ); // end define list }
void ShaderChooser::shaderSelectionChanged(const std::string& shaderName, GtkListStore* listStore) { if (_targetEntry != NULL) { const char *value = shaderName.c_str(); if (_stripTextureDir) value += GlobalTexturePrefix_get().size(); gtk_entry_set_text(GTK_ENTRY(_targetEntry), value); } // Propagate the call up to the client (e.g. SurfaceInspector) if (_client != NULL) { _client->shaderSelectionChanged(shaderName); } // Get the shader, and its image map if possible IShader* shader = _selector.getSelectedShader(); if (shader != NULL) { // Pass the call to the static member ShaderSelector::displayShaderInfo(shader, listStore); shader->DecRef(); } }
IProgram* ShaderModuleRepository::findProgram(ShaderType type, int numShaders, IShader ** pShaders) { int sz = (int)m_programs.size(); for(int i=0; i<sz; i++) { IProgram* p = m_programs[i].p; if(numShaders != p->getNumShaders()) continue; int j; for(j=0; j<numShaders; j++) { ShaderType t; IShader* pShd; pShd = p->getShader(0, &t); if(t != type) return NULL; if((pShd == NULL) || (findShader(pShd->getName()) == NULL) ) break; } if(j == numShaders) return p; } return NULL; }
void SceneManager::DrawTempWaypoints(IShader& shader, AIPath& tempPath) { std::vector<glm::vec3> path = tempPath.GetWaypoints(); for (int i = 0; i < path.size(); ++i) { glm::mat4 translation; translation = glm::translate(translation, path[i]); shader.SetWorldMatrix(translation); m_miscObjects["waypoint"]->Draw(); if (tempPath.IsClosed()) { if (path.size() > 1 && (i - 1) < path.size()) { glBegin(GL_LINES); glm::vec3 cpos = path[i - 1]; glm::vec3 npos = path[i]; glm::vec3 min = cpos - npos; glVertex3f(0, 5, 0); glVertex3f(min.x, min.y + 5, min.z); glEnd(); } if (path.size() > 2 && (i) == path.size()-1) { glBegin(GL_LINES); glm::vec3 cpos = path[0]; glm::vec3 npos = path[path.size() - 1]; glm::vec3 min = cpos - npos; glVertex3f(0, 5, 0); glVertex3f(min.x, min.y + 5, min.z); glEnd(); } } else { if (path.size() > 1 && (i - 1) < path.size()) { glBegin(GL_LINES); glm::vec3 cpos = path[i - 1]; glm::vec3 npos = path[i]; glm::vec3 min = cpos - npos; glVertex3f(0, 5, 0); glVertex3f(min.x, min.y + 5, min.z); glEnd(); } } } }
void SceneManager::DrawBoundingBoxes(IShader& shader) { std::map<unsigned int, StaticMesh*>::const_iterator iter = models.begin(); for (iter; iter != models.end(); ++iter) { if (iter->second->m_bDrawBoundingBox) { glm::mat4 worldM; glm::vec3 rotation = iter->second->GetRotation(); glm::vec3 rotationInRadians = (rotation * glm::pi<float>()) / 180.0f; worldM = glm::translate(worldM, iter->second->GetPosition()); worldM = glm::rotate(worldM, rotationInRadians.x, glm::vec3(1.0f, 0.0f, 0.0f)); worldM = glm::rotate(worldM, rotationInRadians.y, glm::vec3(0.0f, 1.0f, 0.0f)); worldM = glm::rotate(worldM, rotationInRadians.z, glm::vec3(0.0f, 0.0f, 1.0f)); shader.SetWorldMatrix(worldM); iter->second->GetModelData()->boundingbox.Draw(); } } }
void SceneManager::Draw(IShader& shader) { std::map<unsigned int, StaticMesh*>::iterator iter = models.begin(); for (iter; iter != models.end(); ++iter) { BoundingBox transformedBox = iter->second->GetModelData()->boundingbox; glm::vec3 objRot = iter->second->GetRotation(); glm::mat4 rotMat; objRot = (objRot * glm::pi<float>()) / 180.0f; rotMat = glm::rotate(rotMat, objRot.x, glm::vec3(1.0f, 0.0f, 0.0f)); rotMat = glm::rotate(rotMat, objRot.y, glm::vec3(0.0f, 1.0f, 0.0f)); rotMat = glm::rotate(rotMat, objRot.z, glm::vec3(0.0f, 0.0f, 1.0f)); glm::vec4 transformedMaxPoint = rotMat * glm::vec4(transformedBox.max, 0); glm::vec4 transformedMinPoint = rotMat * glm::vec4(transformedBox.min, 0); transformedBox.max = glm::vec3(transformedMaxPoint.x, transformedMaxPoint.y, transformedMaxPoint.z); transformedBox.min = glm::vec3(transformedMinPoint.x, transformedMinPoint.y, transformedMinPoint.z); transformedBox.max += iter->second->GetPosition(); transformedBox.min += iter->second->GetPosition(); //TestResult t = m_Frustum.Intersect(transformedBox); //if (t != TEST_OUTSIDE) //{ glm::mat4 worldM; glm::vec3 rotation = iter->second->GetRotation(); glm::vec3 rotationInRadians = (rotation * glm::pi<float>()) / 180.0f; worldM = glm::translate(worldM, iter->second->GetPosition()); worldM = glm::rotate(worldM, rotationInRadians.x, glm::vec3(1.0f, 0.0f, 0.0f)); worldM = glm::rotate(worldM, rotationInRadians.y, glm::vec3(0.0f, 1.0f, 0.0f)); worldM = glm::rotate(worldM, rotationInRadians.z, glm::vec3(0.0f, 0.0f, 1.0f)); shader.SetWorldMatrix(worldM); iter->second->Draw(); //} } }
//------------------------------------- // Called when the service is registered in the kernel // rv - return true on succes, // when false is returned then the service gets deleted bool CServiceGame::Start() { Fab_LogWrite(FLOG_LVL_INFO, FLOG_ID_APP, "Game Service: Starting" ); SendMsg(SM_INPUT, this); SendMsg(SM_RENDERER, this); SMsgTimer msg(TimerCallback); Fab_KernelSendMessage(&msg); // just quit when the renderer or input wasn't filled in if(m_pInput == nullptr || m_pRenderer == nullptr) return false; m_pRenderer->SetVSync(true); // make needed object accesable for user Fab_GlobalAccessorAddObject("Input", m_pInput); m_pContent = Fab_ContentCreateManager(m_pRenderer); if( !m_pContent->StartLoading() ) { Fab_LogWrite(FLOG_LVL_ERROR, FLOG_ID_APP, "Game Service: Starting content loading failed." ); return false; } IShader *pShader = m_pContent->LoadShader("Shaders/SimpleShader"); pShader->Apply(); pShader->SetVarVec3( pShader->GetVarId("LightPosition_worldspace"), glm::vec3(0, 100, 0)); pShader->SetVarF1( pShader->GetVarId("LightPower"), 1.0f); pShader->SetVarVec4( pShader->GetVarId("LightColor"), glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); IImage *pImage = m_pContent->LoadImage("Textures/CarDiffuseMap.png"), *pImageFloor = m_pContent->LoadImage("Textures/FloorDif.png"), *pImageWall = m_pContent->LoadImage("Textures/WallDif.png"), *pImageFinish = m_pContent->LoadImage("Textures/FinishDif.png"), *pImageWater = m_pContent->LoadImage("Textures/WaterDif.png"), *pImagePlayer = m_pContent->LoadImage("Textures/PlayerDif.png"), *pImageBug01 = m_pContent->LoadImage("Textures/Bug01Dif.png"); g_pMatDefault = Fab_MatCreateDifTexture(pShader, pImage); g_pMatGround = Fab_MatCreateDifTexture(pShader, pImageFloor); g_pMatWall = Fab_MatCreateDifTexture(pShader, pImageWall); g_pMatFinish = Fab_MatCreateDifTexture(pShader, pImageFinish); g_pMatWater = Fab_MatCreateDifTexture(pShader, pImageWater); g_pMatPlayer = Fab_MatCreateDifTexture(pShader, pImagePlayer); g_pMatBug01 = Fab_MatCreateDifTexture(pShader, pImageBug01); CGameObject *pGo = new CGameObject(); pGo->Init(); CCompCamera* pCam = new CCompCamera(); pGo->AddComponent( pCam ); pGo->Transform()->SetPos( glm::vec3(0, 1 * Grid::SCALE, 0) ); pGo->Transform()->SetRot( glm::vec3(glm::radians(-90.0f), 0, 0) ); g_vpGameObjects.push_back(pGo); Fab_GlobalAccessorAddObject("Camera", pGo); g_pCam = pCam; LoadLevel("level.lvl"); for (CGameObject* go : g_vpGameObjects) go->Init(); m_pContent->EndLoading(); Fab_LogWrite(FLOG_LVL_INFO, FLOG_ID_APP, "Game Service: Started" ); return true; }
bool CResourceLoader::loadPipeline(const std::string& fullpath, const IResourceXmlParser::SPipelineCreateParams& createParams) const { /* if the pipeline with the same name has already been loaded, maybe some mistake has occurred. such as two pipeline file with the same pipeline name. */ IPipeline* pipeline = mPipelineManager->get(createParams.Name); if (pipeline) { GF_PRINT_CONSOLE_INFO("Pipeline '%s' (in the file '%s') has already been loaded. It can't been loaded again. \ Do you put the pipelines with same names in different files ?\n", createParams.Name, fullpath.c_str()); return false; } u32 shaderCount = createParams.Shaders.size(); IShader* shaders[5]; IShader* vertexShader; for (u32 i = 0; i < shaderCount; i++) { const IResourceXmlParser::SShaderCreateParams shaderCreateParams = createParams.Shaders[i]; std::string shaderName = shaderCreateParams.FileName + std::string("-") + shaderCreateParams.FunctionName; IShader* shader = mShaderManager->get(shaderName); /* if the shader has not been loaded. Load it first. */ if (!shader) { std::string shaderFullPath; if (!mResourceGroupManager->getFullPath(shaderCreateParams.FileName, shaderFullPath)) { GF_PRINT_CONSOLE_INFO("Pipeline '%s' creation failed. Because the shader file '%s' doesn't exist.\n", createParams.Name.c_str(), shaderCreateParams.FileName.c_str()); return false; } shader = mShaderManager->load(shaderCreateParams.Type, shaderFullPath, shaderCreateParams.FunctionName, shaderName); if (shader == nullptr) { GF_PRINT_CONSOLE_INFO("Pipeline '%s' creation failed. Due to the '%s' function in '%s' shader file.\n", createParams.Name.c_str(), shaderCreateParams.FunctionName.c_str(), shaderFullPath.c_str()); return false; } } shaders[i] = shader; /* find the vertex shader, which will be used to create input-layout soon.*/ if (shader->getType() == EST_VERTEX_SHADER) { vertexShader = shader; } } /* create the input-layout. */ /* if the input-layout with the same layout has been created before, just get it.*/ IInputLayout* inputLayout = mInputlayoutManager->get(createParams.InputLayoutElements); // if there is no input-layout with the same vertex formats. just create it. if (!inputLayout) { inputLayout = mInputlayoutManager->create(createParams.InputLayoutElements, vertexShader); if (!inputLayout) { GF_PRINT_CONSOLE_INFO("Pipeline '%s' creation failed. Due to the input-layout create failure in file '%s'.\n", createParams.Name, fullpath.c_str()); return false; } } /* create render state */ std::string rsname = createParams.Name + ".rs"; IRenderState* pRenderState = mRenderStateManager->get(rsname); if (!pRenderState) { pRenderState = mRenderStateManager->create(rsname); if (!pRenderState) { GF_PRINT_CONSOLE_INFO("Pipeline '%s' creation failed. Due to the render-state create failure in file '%s'.\n", createParams.Name, fullpath.c_str()); return false; } } // set all the render states. for (u32 i = 0; i < createParams.RenderStates.size(); i++) { const IResourceXmlParser::SRenderStateCreateParams& rsCreateParam = createParams.RenderStates[i]; switch (rsCreateParam.StateType) { /* if the render-state need a float value */ case ERS_DEPTH_BIAS_CLAMP: pRenderState->setFloat(rsCreateParam.StateType, rsCreateParam.FloatValue); break; /* others are unsigned int. */ default: pRenderState->set(rsCreateParam.StateType, rsCreateParam.DwordValue); break; } } pRenderState->confirm(); // create the pipeline object pipeline = mPipelineManager->create(createParams.Name, shaders, shaderCount, inputLayout, createParams.PrimitiveType, pRenderState); if (!pipeline) { GF_PRINT_CONSOLE_INFO("Pipeline '%s' creation failed (in file '%s').\n", createParams.Name, fullpath.c_str()); // TODO: should drop pRenderState object. return false; } /* set the shader auto-inject variables. */ for (u32 i = 0; i < createParams.ShaderAutoVariables.size(); i++) { pipeline->addShaderAutoVariable(createParams.ShaderAutoVariables[i]); } return true; }
/*************************************************************************/ /** ** ** **/ /*************************************************************************/ void Container::consolidateShaders() { ShaderModuleRepository* pShdRep = static_cast<ShaderModuleRepository*>(getShaderModuleRepositorySingleton()); std::set<IProgram *> usedPrograms; int sz = (int)m_shaderprograms.size(); for(int i=0; i<sz; i++) { //assert(m_shaderprograms[i]); CHECK_POINTER(m_shaderprograms[i]); usedPrograms.insert(m_shaderprograms[i]); } // Clear the table : we are about to re-create it m_shaderprograms.clear(); // Walk through techs/passes and check if any pass is using it TechVec::iterator it = m_techniques.begin(); while(it != m_techniques.end()) { Technique::PassVec::iterator ip = (*it)->m_passes.begin(); while(ip != (*it)->m_passes.end()) { Pass::StatesLayerMap::iterator isl = ip->pass->m_statesLayers.begin(); while(isl != ip->pass->m_statesLayers.end()) { IProgram* p; CHECK_TRUE_MSG(isl->second.program == NULL, "TODO: handle consolidation for non-separable programs"); if(isl->second.programPipeline) for(int i=0; p = isl->second.programPipeline->getShaderProgram(i); i++) { std::set<IProgram *>::iterator iip; // at last we have a program iip = usedPrograms.find(p); #ifdef _DEBUG //LOGD("Program %d (", p->getProgram() ); //IShader* pshd; //for(int ii=0; pshd = p->getShader(ii); ii++) // LOGD("%s ", pshd->getName()); #endif if(iip != usedPrograms.end()) { #ifdef _DEBUG LOGD("Program %d (", p->getProgram() ); IShader* pshd; for(int ii=0; pshd = p->getShader(ii); ii++) LOGD("%s ", pshd->getName()); LOGD(") Found as used by some pass (%s)\n", ip->pass->getName()); #endif usedPrograms.erase(iip); m_shaderprograms.push_back(p); // add it back, because used here } else { #ifdef _DEBUG //LOGD(") used in pass %s BUT not found\n", ip->pass->getName()); #endif } } // for() ++isl; } ++ip; } ++it; } std::set<IProgram *>::iterator iip = usedPrograms.begin(); while(iip != usedPrograms.end()) { #ifdef _DEBUG LOGD("Program %d (", (*iip)->getProgram() ); IShader* pshd; for(int ii=0; pshd = (*iip)->getShader(ii); ii++) LOGD("%s ", pshd->getName()); #endif int c = pShdRep->releaseProgram(*iip); if(c <= 0) { #ifdef _DEBUG LOGD(") Not used anymore anywhere. DELETING it\n"); #endif // good enough : query the first shader in the program switch((*iip)->getShader(0)->getType()) { case TGLSL: case THLSL: delete_Program(*iip); break; case TCUDA: delete_ProgramCUDA(*iip); break; } } else { #ifdef _DEBUG LOGD(") Still used as Global (%d)\n", c); #endif } ++iip; } }
int main(int argc, const char **argv) { // Command line parameters bool editor = false; core::stringc levelFileName; // Mac passes a -psn (process serial number) argument when running from a .app directory, // which messes this up. So we just ignore command line arguments on mac for now. // Ideally though, we'd just strip that out and ignore it. #ifndef __APPLE__ if (argc == 3) { // Edit? if (core::stringc(argv[1]) == "-e") { editor = true; globalIsInEditor = true; } levelFileName = argv[2]; } else if (argc == 2) { levelFileName = argv[1]; } #endif VariantMap settings; settings["appName"] = "Puzzle Moppet"; settings["screenWidth"] = 1024; settings["screenHeight"] = 768; settings["fullScreen"] = false; IEngine *engine = CreateEngine(argc, argv, &settings); engine->GetIrrlichtDevice()->getFileSystem()->addFileArchive(PROJECT_DIR"/Puzzle/media/"); IWorld *world = engine->GetWorld(); IRenderSystem *renderSystem = engine->GetRenderSystem(); renderSystem->SetShaderLevel(ESL_LOW); // Loading text. Hacked in! Uses add_static_text2 from MainState.cpp { video::IVideoDriver *driver = engine->GetIrrlichtDevice()->getVideoDriver(); gui::IGUIEnvironment *guienv = engine->GetIrrlichtDevice()->getGUIEnvironment(); s32 screenHeight = driver->getScreenSize().Height; s32 screenWidth = driver->getScreenSize().Width; gui::IGUIElement *loadingGUI = add_static_text(L"Loading..."); core::rect<s32> rect = loadingGUI->getRelativePosition(); rect += core::vector2di( screenWidth/2 - rect.getWidth()/2, screenHeight/2 - rect.getHeight()/2 ); loadingGUI->setRelativePosition(rect); // Render the gui once. driver->beginScene(true, true, video::SColor(0,0,0,0)); guienv->drawAll(); driver->endScene(); // We can remove the element now we've rendered. loadingGUI->remove(); } // Set up post processing. if (renderSystem->ShadersAreAvailable() && renderSystem->PostProcessingEnabled()) { // bool flag indicates whether rendering to screen still occurs first before post processing IPostProcessingChain *chain = renderSystem->CreatePostProcessingChain(true); // Materials need: // - Lighting = false // - ZBuffer = false // - ZWriteEnable = false // For bloom, need: // - bright filter // - BlurH // - BlurV // (final one blended additively on to the screen) video::SMaterial material; material.Lighting = false; material.ZBuffer = false; material.ZWriteEnable = false; material.AntiAliasing = video::EAAM_OFF; IShader *shader; // Bright filter shader = renderSystem->CreateShader("ScreenQuad.vert", "Brightfilter.frag"); chain->AddEffect(material, shader, 2); shader->drop(); // Horizontal blur shader = renderSystem->CreateShader("ScreenQuad.vert", "BlurH.frag"); chain->AddEffect(material, shader, 2); shader->drop(); // Vertical blur // As this is the last effect it is rendered additively on to the screen. shader = renderSystem->CreateShader("ScreenQuad.vert", "BlurV.frag", video::EMT_TRANSPARENT_ADD_COLOR); chain->AddEffect(material, shader, 2); shader->drop(); renderSystem->SetActivePostProcessingChain(chain); chain->drop(); } // Some sky // Maybe this should be in Level? // --> move it only when it is needed... core::stringc skyDir = "skies/Set 42/"; core::stringc skyExt = "png"; world->SetSkyBox( skyDir+"6."+skyExt, skyDir+"5."+skyExt, skyDir+"1."+skyExt, skyDir+"3."+skyExt, skyDir+"2."+skyExt, skyDir+"4."+skyExt ); // load sky effects enabled flag { VariantMap creationSettings = engine->GetCreationSettings(); if (creationSettings.count("skyEffects")) skyEffectsEnabled = creationSettings["skyEffects"]; else skyEffectsEnabled = true; } if (renderSystem->ShadersAreAvailable() && skyEffectsEnabled) { IShader *skyShader = renderSystem->CreateShader("SkyBox.vert", "SkyBox.frag", video::EMT_SOLID); LowLevelShaderRegisterMap rmap; rmap.PushSingleRegister("rippleScroll", "brightness", nullptr,nullptr); skyShader->SetPixelRegisterMap(rmap); IShaderCallback *skyShaderCallback = new SkyBoxShaderCallback(engine); skyShader->SetCallback( skyShaderCallback ); skyShaderCallback->drop(); world->SetSkyBoxShader(skyShader); skyShader->drop(); // sky box ripple texture !! video::IVideoDriver *driver = engine->GetIrrlichtDevice()->getVideoDriver(); video::ITexture *rippleTexture = driver->getTexture("cloudshadow.png"); for (u8 i = 0; i < 6; i ++) world->GetSkyBoxMaterial(i).setTexture(1, rippleTexture); } // ********** PRELOAD EVERYTHING!! *********** NOTE << "Preloading media..."; // Meshes { scene::ISceneManager *smgr = engine->GetIrrlichtDevice()->getSceneManager(); smgr->getMesh("ground_single_sideless.b3d"); smgr->getMesh("ground_single.b3d"); smgr->getMesh("ground_single_fall.b3d"); smgr->getMesh("box.b3d"); smgr->getMesh("icybox.irrmesh"); smgr->getMesh("icybox_inner.irrmesh"); smgr->getMesh("balloon.irrmesh"); smgr->getMesh("magicfan_base.b3d"); smgr->getMesh("magicfan_blades.b3d"); smgr->getMesh("magicfan_orb.irrmesh"); smgr->getMesh("lift.b3d"); smgr->getMesh("lift_glow.irrmesh"); smgr->getMesh("nothing.irrmesh"); smgr->getMesh("teleport.irrmesh"); smgr->getMesh("player.b3d"); smgr->getMesh("sea.b3d"); smgr->getMesh("land.irrmesh"); smgr->getMesh("cliff.irrmesh"); smgr->getMesh("titletext.b3d"); smgr->getMesh("gridarrow.irrmesh"); } // Textures (stand alone, others are loaded with meshes) { video::IVideoDriver *driver = engine->GetIrrlichtDevice()->getVideoDriver(); driver->getTexture("brass_spheremap.png"); driver->getTexture("watersand.png"); driver->getTexture("water.png"); driver->getTexture("watersand_add.png"); driver->getTexture("dust.png"); driver->getTexture("sparkle.png"); driver->getTexture("fog.png"); driver->getTexture("cloudshadow.png"); driver->getTexture("mud.jpg"); // Final sky box textures { core::stringc skyDir = "skies/Set 26/final_"; core::stringc skyExt = "png"; driver->getTexture(skyDir+"6."+skyExt); driver->getTexture(skyDir+"5."+skyExt); driver->getTexture(skyDir+"1."+skyExt); driver->getTexture(skyDir+"3."+skyExt); driver->getTexture(skyDir+"2."+skyExt); driver->getTexture(skyDir+"4."+skyExt); } } // Fonts { gui::IGUIEnvironment *guienv = engine->GetIrrlichtDevice()->getGUIEnvironment(); guienv->getFont("font2.xml"); guienv->getFont("fontlarge2.xml"); } // Sounds { ISoundSystem *soundSystem = engine->GetSoundSystem(); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/sea.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/beep.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/fallblock.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/buttonflutter_micro.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/hithard.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/liftrun.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/balloonpush.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/slide.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/windy.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/speedcore.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/bell.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/stepballoon.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/step.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/appear.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/laugh.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/fair.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/good.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/excellent.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/perfect.ogg"); soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/sfx/extraordinary.ogg"); //soundSystem->PreloadSound(PROJECT_DIR"/Puzzle/media/music.ogg"); } // Shaders!? /* if (renderSystem->ShadersAreAvailable()) { IShader *shader; shader = renderSystem->CreateShader("Hemisphere.vert", "Hemisphere.frag", video::EMT_SOLID); shader->drop(); shader = renderSystem->CreateShader("HemisphereBalloon.vert", "HemisphereBalloon.frag", video::EMT_SOLID); shader->drop(); shader = renderSystem->CreateShader("HemisphereLand.vert", "Hemisphere.frag", video::EMT_SOLID); shader->drop(); shader = renderSystem->CreateShader("Hemisphere.vert", "HemisphereWood.frag", video::EMT_SOLID); shader->drop(); shader = renderSystem->CreateShader("PlainWithAlpha.vert", "PlainWithAlpha.frag", video::EMT_SOLID); shader->drop(); } */ NOTE << "Finished preloading!"; // Default sound volume engine->GetSoundSystem()->SetGlobalVolume(5.0); // background sfx bgAmbientSound = engine->GetSoundSystem()->CreateSound2D(); bgAmbientSound->SetIsLooped(true); //bgAmbientSound->SetVolume(0.035); bgMusic = engine->GetSoundSystem()->CreateSound2D(); bgMusic->SetIsLooped(true); // Load sfx volume set_volumes_from_settings(engine->GetCreationSettings()); bgAmbientSound->Play(PROJECT_DIR"/Puzzle/media/sfx/windy.ogg"); bgMusic->Play(PROJECT_DIR"/Puzzle/media/sfx/speedcore.ogg"); // load default movement type { VariantMap creationSettings = engine->GetCreationSettings(); if (creationSettings.count("gridBasedMovement")) gridBasedMovement = creationSettings["gridBasedMovement"]; else gridBasedMovement = true; // mouse axis inversion? if (creationSettings.count("invertMouseX")) invertMouseX = creationSettings["invertMouseX"]; else invertMouseX = false; if (creationSettings.count("invertMouseY")) invertMouseY = creationSettings["invertMouseY"]; else invertMouseY = false; } // Now, instead of going straight into the game we have a start screen. // ...unless the game was started by command line, in which case we jump straight in. MainState *mainState = nullptr; if (levelFileName.size()) { NOTE << "Started with command line parameter, will skip start screen."; mainState = new MainState(&mainState); mainState->StartLevel(levelFileName, editor); } else { NOTE << "Entering start screen..."; // StartScreen *MAY* create a MainState, returning the pointer to mainState // so that we can delete it from here in main.cpp // (why do we want to delete it from main? because we always have...) StartScreen *startScreen = new StartScreen(&mainState); engine->GetLogicUpdater().AddUpdatable(startScreen); startScreen->drop(); } // Main loop engine->Run(); // MainState may not exist if StartScreen was entered but no level was played. if (mainState) delete mainState; if (bgAmbientSound) bgAmbientSound->drop(); if (bgMusic) bgMusic->drop(); engine->drop(); return 0; }
/*************************************************************************/ /** ** ** **/ /*************************************************************************/ bool CUDAProgram::link(IContainer* pContainer) { CUresult cuStatus; if(m_linkNeeded) { // // add common parts for line-number conversion :-( // std::vector<CUDAShader::codeInfo> codeBlocks; int lineOffset = 0; ShaderMap::iterator iShd, iEnd; //nvFX::printf("=====================================\n" ); iShd = m_shaders.begin(); iEnd = m_shaders.end(); //nvFX::printf("%s Shader code : \n", s==0 ? "Vertex" : "Fragment"); for(;iShd != iEnd; iShd++) { //nvFX::printf("----\n%s\n", iShd->second->m_shaderCode.c_str() ); for(int n=0; n<(int)iShd->second->m_startLineNumbers.size(); n++) codeBlocks.push_back(iShd->second->m_startLineNumbers[n]); } m_fullCode.clear(); // Add common header code IShader *pShd; for(int i=0; pShd = static_cast<CUDAShader*>(pContainer->findShader(i)); i++) if((*(pShd->getName()) == '\0') && (pShd->getType() == TCUDA) ) { m_fullCode += pShd->getShaderCode(); } iShd = m_shaders.begin(); iEnd = m_shaders.end(); std::string tempName(pContainer->getName()); for(;iShd != iEnd; iShd++) { m_fullCode += iShd->second->getShaderCode(); tempName += std::string("_"); tempName += iShd->second->getName(); } // // Save the temp file and compile it // unsigned int checksum = saveTempFile(tempName.c_str(), m_fullCode.c_str()); std::string targetName = compileCUDA(tempName.c_str(), checksum); m_fullCode.clear(); m_linkNeeded = false; if(targetName.empty()) { return false; } // // load the compiled file // FILE *fp = fopen(targetName.c_str(), "rb"); fseek(fp, 0, SEEK_END); int file_size = ftell(fp); char *buf = new char[file_size+1]; fseek(fp, 0, SEEK_SET); fread(buf, sizeof(char), file_size, fp); fclose(fp); buf[file_size] = '\0'; std::string ptx_source(buf); delete[] buf; if (targetName.rfind(".ptx") != std::string::npos) { // in this branch we use compilation with parameters const unsigned int jitNumOptions = 3; CUjit_option *jitOptions = new CUjit_option[jitNumOptions]; void **jitOptVals = new void*[jitNumOptions]; // set up size of compilation log buffer jitOptions[0] = CU_JIT_INFO_LOG_BUFFER_SIZE_BYTES; int jitLogBufferSize = 1024; jitOptVals[0] = (void *)jitLogBufferSize; // set up pointer to the compilation log buffer jitOptions[1] = CU_JIT_INFO_LOG_BUFFER; char *jitLogBuffer = new char[jitLogBufferSize]; jitOptVals[1] = jitLogBuffer; // set up pointer to set the Maximum # of registers for a particular kernel jitOptions[2] = CU_JIT_MAX_REGISTERS; int jitRegCount = 32; jitOptVals[2] = (void *)jitRegCount; cuStatus = cuModuleLoadDataEx(&m_cuModule, ptx_source.c_str(), jitNumOptions, jitOptions, (void **)jitOptVals); if (cuStatus != CUDA_SUCCESS) { printf("cuModuleLoadDataEx error!\n"); return false; } //printf("> PTX JIT log:\n%s\n", jitLogBuffer); } else { cuStatus = cuModuleLoad(&m_cuModule, targetName.c_str()); if (cuStatus != CUDA_SUCCESS) { m_cuModule = NULL; printf("cuModuleLoad error!\n"); return false; } } printf(">> modInitCTX<%s> initialized %s", targetName.c_str(), (cuStatus == CUDA_SUCCESS) ? "SUCCESS!\n" : "FAILED\n"); } //if(m_linkNeeded) return true; }
// Callback to redraw the GL widget void ShaderSelector::_onExpose(GtkWidget* widget, GdkEventExpose* ev, ShaderSelector* self) { // The scoped object making the GL widget the current one gtkutil::GLWidgetSentry sentry(widget); // Get the viewport size from the GL widget GtkRequisition req; gtk_widget_size_request(widget, &req); glViewport(0, 0, req.width, req.height); // Initialise glClearColor(0.3f, 0.3f, 0.3f, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, req.width, 0, req.height, -100, 100); glEnable(GL_TEXTURE_2D); // Get the selected texture, and set up OpenGL to render it on // the quad. IShader* shader = self->getSelectedShader(); if (shader == NULL) return; shader->DecRef(); bool drawQuad = false; // This is an "ordinary" texture, take the editor image GLTexture* tex = shader->getTexture(); if (tex != NULL) { glBindTexture(GL_TEXTURE_2D, tex->texture_number); drawQuad = true; } if (drawQuad) { // Calculate the correct aspect ratio for preview. float aspect = float(tex->width) / float(tex->height); float hfWidth, hfHeight; if (aspect > 1.0) { hfWidth = 0.5 * req.width; hfHeight = 0.5 * req.height / aspect; } else { hfHeight = 0.5 * req.width; hfWidth = 0.5 * req.height * aspect; } // Draw a quad to put the texture on glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glColor3f(1, 1, 1); glBegin(GL_QUADS); glTexCoord2i(0, 1); glVertex2f(0.5*req.width - hfWidth, 0.5*req.height - hfHeight); glTexCoord2i(1, 1); glVertex2f(0.5*req.width + hfWidth, 0.5*req.height - hfHeight); glTexCoord2i(1, 0); glVertex2f(0.5*req.width + hfWidth, 0.5*req.height + hfHeight); glTexCoord2i(0, 0); glVertex2f(0.5*req.width - hfWidth, 0.5*req.height + hfHeight); glEnd(); } }
void XCShaderContainer::LoadShaders() { IShader* binShader; FlatBuffersSystem& fbSystem = SystemLocator::GetInstance()->RequestSystem<FlatBuffersSystem>("FlatBuffersSystem"); fbSystem.ParseAndLoadFile(SHADER_SCHEMA_FILEPATH, m_fbBuffer); fbSystem.ParseAndLoadFile(SHADER_DATA_FILEPATH, m_fbBuffer); #if defined(LOAD_SHADERS_FROM_DATA) auto FBShadersRoot = GetFBRootShader(m_fbBuffer.GetBufferFromLoadedData()); for (auto it = FBShadersRoot->FBShaders()->begin(); it != FBShadersRoot->FBShaders()->end(); ++it) { binShader = XCNEW(XCShaderHandle)(); binShader->Load((void*) *it); m_Shaders[it->ShaderUsage()] = binShader; } #else for (u32 shaderIndex = 0; shaderIndex < ShaderType_Max; shaderIndex++) { switch (shaderIndex) { case ShaderType_DEFAULT: { binShader = new DefaultShader(m_device); binShader->LoadShader(); binShader->CreateConstantBuffers(); m_Shaders[ShaderType_DEFAULT] = binShader; break; } case ShaderType_SolidColor: { binShader = new SolidColorShader(m_device); binShader->LoadShader(); binShader->CreateConstantBuffers(); m_Shaders[ShaderType_SolidColor] = binShader; break; } case ShaderType_LightTexture: { binShader = new LightTextureShader(m_device); binShader->LoadShader(); binShader->CreateConstantBuffers(); m_Shaders[ShaderType_LightTexture] = binShader; break; } case ShaderType_REFELECTED_LIGHTTEXTURE: { binShader = new XCShaderHandle(m_device); binShader->LoadShader(); binShader->CreateConstantBuffers(); m_Shaders[ShaderType_REFELECTED_LIGHTTEXTURE] = binShader; break; } case ShaderType_TerrainMultiTexture: { binShader = new TerrainMultiTex(m_device); binShader->LoadShader(); binShader->CreateConstantBuffers(); m_Shaders[ShaderType_TerrainMultiTexture] = binShader; break; } case ShaderType_SimpleCubeMap: { binShader = new CubeMapShader(m_device); binShader->LoadShader(); binShader->CreateConstantBuffers(); m_Shaders[ShaderType_SimpleCubeMap] = binShader; break; } case ShaderType_SkinnedCharacter: { binShader = new SkinnedCharacterShader(m_device); binShader->LoadShader(); binShader->CreateConstantBuffers(); m_Shaders[ShaderType_SkinnedCharacter] = binShader; break; } case ShaderType_Max: break; default: break; } } #endif }
/*************************************************************************/ /** ** ** TODO: in SHADERCONCAT_USE, add error log with proper line numbers to nvFX files ** **/ /*************************************************************************/ bool GLSLProgram::link(IContainer* pContainer) { char localBuf[1024]; int len; char* buf = localBuf; buf[0] = '\0'; if(m_linkNeeded) { // // add common parts for line-number conversion :-( // std::vector<GLSLShader::codeInfo> codeBlocks; int lineOffset = 0; ShaderMap::iterator iShd, iEnd; //nvFX::printf("=====================================\n" ); for(int s=0; s<6; s++) { switch(s) { case 0: iShd = m_vtxShaders.begin(); iEnd = m_vtxShaders.end(); break; case 1: iShd = m_fragShaders.begin(); iEnd = m_fragShaders.end(); break; case 2: iShd = m_computeShaders.begin(); iEnd = m_computeShaders.end(); break; case 3: iShd = m_geomShaders.begin(); iEnd = m_geomShaders.end(); break; case 4: iShd = m_tcsShaders.begin(); iEnd = m_tcsShaders.end(); break; case 5: iShd = m_tesShaders.begin(); iEnd = m_tesShaders.end(); break; } for(;iShd != iEnd; iShd++) { //nvFX::printf("----\n%s\n", iShd->second->m_shaderCode.c_str() ); for(int n=0; n<(int)iShd->second->m_startLineNumbers.size(); n++) codeBlocks.push_back(iShd->second->m_startLineNumbers[n]); } } #ifdef SHADERCONCAT_USE //------------------------------------------------------------------------------------------ // SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE #pragma MESSAGE("WARNING : No use of Compute in lame use !!") GLenum err = glGetError(); m_VPCode.clear(); m_FPCode.clear(); // Add common header code IShader *pShd; for(int i=0; pShd = static_cast<GLSLShader*>(pContainer->findShader(i)); i++) if((*(pShd->getName()) == '\0') && (pShd->getType() == TGLSL) ) { m_VPCode += pShd->getShaderCode(); m_FPCode += pShd->getShaderCode(); } iShd = m_vtxShaders.begin(); iEnd = m_vtxShaders.end(); for(;iShd != iEnd; iShd++) m_VPCode += iShd->second->getShaderCode(); iShd = m_fragShaders.begin(); iEnd = m_fragShaders.end(); for(;iShd != iEnd; iShd++) m_FPCode += iShd->second->getShaderCode(); #if 1 //def OGLES2 if(m_vtxShaders.size()) m_vtxShader = glCreateShader(GL_VERTEX_SHADER); if(m_fragShaders.size()) m_fragShader = glCreateShader(GL_FRAGMENT_SHADER); #else if(m_vtxShaders.size()) m_vtxShader = glCreateShaderObjectARB(GL_VERTEX_SHADER); if(m_fragShaders.size()) m_fragShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER); #endif GLint size[2] = { m_VPCode.length(), m_FPCode.length() }; const char* progString[2] = { m_VPCode.c_str(), m_FPCode.c_str() }; if(m_vtxShader) { //printf("===============================================================\nVP Code: \n%s", progString[0]); glShaderSource(m_vtxShader, 1, progString, size); glCompileShader(m_vtxShader); #if 1 //def OGLES2 glGetShaderInfoLog (m_vtxShader, 1024, &len, buf); #else glGetInfoLogARB(m_vtxShader, 1024, &len, buf); #endif if(len) nvFX::printf("Log for Shader: \n%s\n", buf); #if 1 //def OGLES2 glAttachShader(m_program, m_vtxShader); #else glAttachObjectARB(m_program, m_vtxShader); #endif } if(m_fragShader) { //printf("===============================================================\nFP Code: \n%s", progString[1]); glShaderSource(m_fragShader, 1, progString+1, size+1); glCompileShader(m_fragShader); #if 1 //def OGLES2 glGetShaderInfoLog (m_fragShader, 1024, &len, buf); #else glGetInfoLogARB(m_fragShader, 1024, &len, buf); #endif if(len) nvFX::printf("Log for Shader: \n%s\n", buf); #if 1 //def OGLES2 glAttachShader(m_program, m_fragShader); #else glAttachObjectARB(m_program, m_fragShader); #endif } err = glGetError(); if(err != GL_NONE) { nvFX::printf("Error while Attaching Shaders to the program %d :Error 0x%x\n", m_program, err); return false; } // SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE SHADERCONCAT_USE //------------------------------------------------------------------------------------------ #endif glLinkProgram(m_program); // // Get Log even if things went well... for warnings or other messages // #if 1 //def OGLES2 glGetProgramInfoLog (m_program, 1024, &len, buf); #else glGetInfoLogARB(m_program, 1023, &len, buf); #endif if(len) { //nvFX::printf("\n======================\n%s\n======================\n", buf); char *p = strstr(buf, "0("); //nvFX::printf("Log for Program %d (", m_program); for(int s=0; s<3; s++) { switch(s) { case 0: iShd = m_vtxShaders.begin(); iEnd = m_vtxShaders.end(); break; case 1: iShd = m_fragShaders.begin(); iEnd = m_fragShaders.end(); break; case 2: iShd = m_computeShaders.begin(); iEnd = m_computeShaders.end(); break; case 3: iShd = m_geomShaders.begin(); iEnd = m_geomShaders.end(); break; case 4: iShd = m_tcsShaders.begin(); iEnd = m_tcsShaders.end(); break; case 5: iShd = m_tesShaders.begin(); iEnd = m_tesShaders.end(); break; } for(;iShd != iEnd; iShd++) { nvFX::printf("%s, ", iShd->second->m_name.c_str() ); } } nvFX::printf(")\n"); #ifdef OGLES2 if(p==NULL) p = strstr(buf, "0:"); // iOS error display #endif if(p==NULL) nvFX::printf("%s\n", buf); while(p) { *p = '\0'; p+=2; char *pNum = p; while((*p != ')')&&(*p != ':')) p++; *p++ = '\0'; int num = atoi(pNum); # ifdef ES2EMU num -= 139; // WHY ?!?!?!?! # endif num--; CHECK_TRUE( num >= 0 ); int offsetNum = num; std::vector<GLSLShader::codeInfo>::iterator iCB; std::vector<GLSLShader::codeInfo>::iterator iCBFound = codeBlocks.end(); for(iCB = codeBlocks.begin(); iCB != codeBlocks.end(); iCB++) if(num >= iCB->lineinShader) { if(num < (iCB->lineinShader + iCB->totalLinesInFX)) { iCBFound = iCB; offsetNum = num - iCB->lineinShader; break; } } if/*assert*/( iCBFound != codeBlocks.end() ) nvFX::printf("%s(%d)", iCBFound->fname.c_str(), iCBFound->lineInFX + offsetNum); else nvFX::printf("()"); pNum = strstr(p, "0("); if(pNum==NULL) pNum = strstr(p, "0:"); while(pNum && (!isdigit(pNum[2]))) { char* pNum2 = strstr(pNum+2, "0("); if(pNum2==NULL) pNum = strstr(pNum+2, "0:"); else pNum = pNum2; } if(pNum) *pNum='\0'; nvFX::printf("%s", p); p = pNum; } //else nvFX::printf("Log for %d:\n%s\n", shaderObj, buf); } GLint status = GL_FALSE; glGetProgramiv(m_program, GL_LINK_STATUS, &status); if(status == GL_FALSE) { #if 1 //def OGLES2 glDeleteProgram(m_program); #else glDeleteObjectARB(m_program); #endif m_program = 0; //m_bound = false; return false; } else m_linkNeeded = false; } //if(m_linkNeeded) else // we still invoke link : needed after glBindAttribLocation { glLinkProgram(m_program); // // Get Log even if things went well... for warnings or other messages // localBuf[0] = '\0'; #if 1 //def OGLES2 glGetProgramInfoLog (m_program, 1024, &len, localBuf); #else glGetInfoLogARB(m_program, 1024, &len, localBuf); #endif if(len) { nvFX::printf("linking again messages : %s\n", localBuf); //assert(0); } } return true; }
int main() { IDevice* device = gf::createDevice(EDT_DIRECT3D11, 800, 600); IVideoDriver* driver = device->getVideoDriver(); ISceneManager* smgr = device->createSceneManager(); IResourceGroupManager* resourceGroupManager = driver->getResourceGroupManager(); resourceGroupManager->init("Resources.cfg"); ITimer* timer = device->getTimer(); timer->reset(); ITextureManager* textureManager = ITextureManager::getInstance(); IShaderManager* shaderMgr = driver->getShaderManager(); IShader* shader = shaderMgr->load(EST_COMPUTE_SHADER, "matmul.hlsl", "cs_main"); const u32 dimension = 512; const u32 sq_dimension = dimension * dimension; std::vector<f32> A(sq_dimension); std::vector<f32> B(sq_dimension); std::vector<f32> C(sq_dimension); std::vector<f32> D(sq_dimension); // init data for (u32 i = 0; i < sq_dimension; i++) { A[i] = math::RandomFloat(0, 10.0f); B[i] = math::RandomFloat(0, 10.0f); } f32 start_time, end_time; start_time = timer->getTime(); // store the right answers to D for (u32 i = 0; i < dimension; i++) { for (u32 j = 0; j < dimension; j++) { f32 sum = 0; for (u32 k = 0; k < dimension; k++) { sum += A[i * dimension + k] * B[k * dimension + j]; } D[i * dimension + j] = sum; } } end_time = timer->getTime(); printf("The computation time by CPU: %fs\n", end_time - start_time); start_time = timer->getTime(); ITexture* inputTexture1 = textureManager->createTexture2D("input1", dimension, dimension, ETBT_SHADER_RESOURCE, &A[0], 1, EGF_R32_FLOAT, 0); ITexture* inputTexture2 = textureManager->createTexture2D("input2", dimension, dimension, ETBT_SHADER_RESOURCE, &B[0], 1, EGF_R32_FLOAT, 0); ITexture* outputTexture = textureManager->createTexture2D("output", dimension, dimension, ETBT_UNORDERED_ACCESS, nullptr, 1, EGF_R32_FLOAT, 0); ITexture* copyTexture = textureManager->createTexture2D("copy", dimension, dimension, ETBT_CPU_ACCESS_READ, nullptr, 1, EGF_R32_FLOAT, 0); shader->setTexture("gInputA", inputTexture1); shader->setTexture("gInputB", inputTexture2); shader->setTexture("gOutput", outputTexture); u32 blockNum = dimension / 8; if (blockNum * 8 != dimension) blockNum++; driver->runComputeShader(shader, blockNum, blockNum, 1); //driver->resetRWTextures(); //driver->resetTextures(); outputTexture->copyDataToAnotherTexture(copyTexture); STextureData outputData; copyTexture->lock(ETLT_READ, &outputData); u8* data = (u8*)outputData.Data; for (u32 i = 0; i < dimension; i++) { // copy each row. memcpy(&C[i * dimension], data + outputData.RowPitch * i, dimension * sizeof(f32)); } copyTexture->unlock(); end_time = timer->getTime(); printf("The computation time by GPU: %fs\n", end_time - start_time); for (u32 i = 0; i < sq_dimension; i++) { assert(math::FloatEqual(C[i], D[i])); } // destory textures. if (!textureManager->destroy(inputTexture1)) printf("Destory texture failed!"); if (!textureManager->destroy(inputTexture2)) printf("Destory texture failed!"); if (!textureManager->destroy(outputTexture)) printf("Destory texture failed!"); if (!textureManager->destroy(copyTexture)) printf("Destory texture failed!"); //sphereMaterial.drop(); smgr->destroy(); device->drop(); system("pause"); return 0; }