void draw2DVertexPrimitiveList(video::ITexture *tex, const void* vertices, u32 vertexCount, const void* indexList, u32 primitiveCount, video::E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, video::E_INDEX_TYPE iType) { if (!irr_driver->isGLSL()) { irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); return; } GLuint tmpvao, tmpvbo, tmpibo; primitiveCount += 2; glGenVertexArrays(1, &tmpvao); glBindVertexArray(tmpvao); glGenBuffers(1, &tmpvbo); glBindBuffer(GL_ARRAY_BUFFER, tmpvbo); glBufferData(GL_ARRAY_BUFFER, vertexCount * getVertexPitchFromType(vType), vertices, GL_STREAM_DRAW); glGenBuffers(1, &tmpibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tmpibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, primitiveCount * sizeof(u16), indexList, GL_STREAM_DRAW); VertexUtils::bindVertexArrayAttrib(vType); glUseProgram(UIShader::Primitive2DList::getInstance()->Program); UIShader::Primitive2DList::getInstance()->setUniforms(); const video::SOverrideMaterial &m = irr_driver->getVideoDriver()->getOverrideMaterial(); compressTexture(tex, false); UIShader::Primitive2DList::getInstance()->SetTextureUnits({ getTextureGLuint(tex) }); glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0); glDeleteVertexArrays(1, &tmpvao); glDeleteBuffers(1, &tmpvbo); glDeleteBuffers(1, &tmpibo); }
void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) { CParticleSystemSceneNode::setEmitter(emitter); if (!emitter || !isGPUParticleType(emitter->getType())) return; has_height_map = false; flip = false; count = emitter->getMaxParticlesPerSecond() * emitter->getMaxLifeTime() / 1000; switch (emitter->getType()) { case scene::EPET_POINT: generateParticlesFromPointEmitter(emitter); break; case scene::EPET_BOX: generateParticlesFromBoxEmitter(static_cast<scene::IParticleBoxEmitter *>(emitter)); break; case scene::EPET_SPHERE: generateParticlesFromSphereEmitter(static_cast<scene::IParticleSphereEmitter *>(emitter)); break; default: assert(0 && "Wrong particle type"); } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); video::ITexture *tex = getMaterial(0).getTexture(0); compressTexture(tex, true, true); texture = getTextureGLuint(getMaterial(0).getTexture(0)); }
static void SetTexture(GLMesh &mesh, unsigned i, bool isSrgb) { if (!mesh.textures[i]) mesh.textures[i] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); compressTexture(mesh.textures[i], isSrgb); if (UserConfigParams::m_azdo) { if (!mesh.TextureHandles[i]) mesh.TextureHandles[i] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[i]), MeshShader::ObjectPass1Shader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(mesh.TextureHandles[i])) glMakeTextureHandleResidentARB(mesh.TextureHandles[i]); } }
void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix) { irr_driver->IncreaseObjectCount(); const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f; float transparency = 1.; GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; compressTexture(mesh.textures[0], true); setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); MeshShader::BubbleShader::setUniforms(ModelViewProjectionMatrix, 0, time, transparency); glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex); }
void STKMeshSceneNode::render() { irr::video::IVideoDriver* driver = irr_driver->getVideoDriver(); if (!Mesh || !driver) return; ++PassCount; updateNoGL(); updateGL(); bool isTransparent; for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) { scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); if (!mb) continue; video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType; video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type); isTransparent = rnd->isTransparent(); break; } if ((irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS) && immediate_draw && !isTransparent) { core::matrix4 invmodel; AbsoluteTransformation.getInverse(invmodel); glDisable(GL_CULL_FACE); if (update_each_frame) updatevbo(); glUseProgram(MeshShader::ObjectPass1Shader::getInstance()->Program); // Only untextured for (unsigned i = 0; i < GLmeshes.size(); i++) { irr_driver->IncreaseObjectCount(); GLMesh &mesh = GLmeshes[i]; GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; compressTexture(mesh.textures[0], true); if (UserConfigParams::m_azdo) { if (!mesh.TextureHandles[0]) mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); MeshShader::ObjectPass1Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0])); } else MeshShader::ObjectPass1Shader::getInstance()->SetTextureUnits(std::vector < GLuint > { getTextureGLuint(mesh.textures[0]) }); MeshShader::ObjectPass1Shader::getInstance()->setUniforms(AbsoluteTransformation, invmodel); assert(mesh.vao); glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); glBindVertexArray(0); } glEnable(GL_CULL_FACE); return; } if (irr_driver->getPhase() == SOLID_LIT_PASS && immediate_draw && !isTransparent) { core::matrix4 invmodel; AbsoluteTransformation.getInverse(invmodel); glDisable(GL_CULL_FACE); if (update_each_frame && !UserConfigParams::m_dynamic_lights) updatevbo(); glUseProgram(MeshShader::ObjectPass2Shader::getInstance()->Program); // Only untextured for (unsigned i = 0; i < GLmeshes.size(); i++) { irr_driver->IncreaseObjectCount(); GLMesh &mesh = GLmeshes[i]; GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; if (UserConfigParams::m_azdo) { GLuint64 DiffuseHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_DIFFUSE), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(DiffuseHandle)) glMakeTextureHandleResidentARB(DiffuseHandle); GLuint64 SpecularHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_SPECULAR), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[1]); if (!glIsTextureHandleResidentARB(SpecularHandle)) glMakeTextureHandleResidentARB(SpecularHandle); GLuint64 SSAOHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_HALF1_R), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[2]); if (!glIsTextureHandleResidentARB(SSAOHandle)) glMakeTextureHandleResidentARB(SSAOHandle); if (!mesh.TextureHandles[0]) mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); MeshShader::ObjectPass2Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, mesh.TextureHandles[0])); } else MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits(createVector<GLuint>( irr_driver->getRenderTargetTexture(RTT_DIFFUSE), irr_driver->getRenderTargetTexture(RTT_SPECULAR), irr_driver->getRenderTargetTexture(RTT_HALF1_R), getTextureGLuint(mesh.textures[0]))); MeshShader::ObjectPass2Shader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix); assert(mesh.vao); glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); glBindVertexArray(0); } glEnable(GL_CULL_FACE); return; } if (irr_driver->getPhase() == GLOW_PASS) { glUseProgram(MeshShader::ColorizeShader::getInstance()->Program); for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) { scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); if (!mb) continue; if (irr_driver->hasARB_base_instance()) glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD)); else glBindVertexArray(GLmeshes[i].vao); drawGlow(GLmeshes[i]); } } if (irr_driver->getPhase() == TRANSPARENT_PASS && isTransparent) { ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation); if (immediate_draw) { if (update_each_frame) updatevbo(); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); if (World::getWorld() && World::getWorld()->isFogEnabled()) { glUseProgram(MeshShader::TransparentFogShader::getInstance()->Program); for (unsigned i = 0; i < GLmeshes.size(); i++) { GLMesh &mesh = GLmeshes[i]; irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; const Track * const track = World::getWorld()->getTrack(); // This function is only called once per frame - thus no need for setters. const float fogmax = track->getFogMax(); const float startH = track->getFogStartHeight(); const float endH = track->getFogEndHeight(); const float start = track->getFogStart(); const float end = track->getFogEnd(); const video::SColor tmpcol = track->getFogColor(); video::SColorf col(tmpcol.getRed() / 255.0f, tmpcol.getGreen() / 255.0f, tmpcol.getBlue() / 255.0f); compressTexture(mesh.textures[0], true); if (UserConfigParams::m_azdo) { if (!mesh.TextureHandles[0]) mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); MeshShader::TransparentFogShader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0])); } else MeshShader::TransparentFogShader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(mesh.textures[0]) }); MeshShader::TransparentFogShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix, fogmax, startH, endH, start, end, col); assert(mesh.vao); glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); glBindVertexArray(0); } } else { glUseProgram(MeshShader::TransparentShader::getInstance()->Program); for (unsigned i = 0; i < GLmeshes.size(); i++) { irr_driver->IncreaseObjectCount(); GLMesh &mesh = GLmeshes[i]; GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; compressTexture(mesh.textures[0], true); if (UserConfigParams::m_azdo) { if (!mesh.TextureHandles[0]) mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentShader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); MeshShader::TransparentShader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0])); } else MeshShader::TransparentShader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(mesh.textures[0]) }); MeshShader::TransparentShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix); assert(mesh.vao); glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); glBindVertexArray(0); } } return; } } }
void IrrDriver::renderGLSL(float dt) { BoundingBoxes.clear(); World *world = World::getWorld(); // Never NULL. Track *track = world->getTrack(); for (unsigned i = 0; i < PowerupManager::POWERUP_MAX; i++) { scene::IMesh *mesh = powerup_manager->m_all_meshes[i]; if (!mesh) continue; for (unsigned j = 0; j < mesh->getMeshBufferCount(); j++) { scene::IMeshBuffer *mb = mesh->getMeshBuffer(j); if (!mb) continue; for (unsigned k = 0; k < 4; k++) { video::ITexture *tex = mb->getMaterial().getTexture(k); if (!tex) continue; compressTexture(tex, true); } } } // Overrides video::SOverrideMaterial &overridemat = m_video_driver->getOverrideMaterial(); overridemat.EnablePasses = scene::ESNRP_SOLID | scene::ESNRP_TRANSPARENT; overridemat.EnableFlags = 0; if (m_wireframe) { overridemat.Material.Wireframe = 1; overridemat.EnableFlags |= video::EMF_WIREFRAME; } if (m_mipviz) { overridemat.Material.MaterialType = m_shaders->getShader(ES_MIPVIZ); overridemat.EnableFlags |= video::EMF_MATERIAL_TYPE; overridemat.EnablePasses = scene::ESNRP_SOLID; } // Get a list of all glowing things. The driver's list contains the static ones, // here we add items, as they may disappear each frame. std::vector<GlowData> glows = m_glowing; ItemManager * const items = ItemManager::get(); const u32 itemcount = items->getNumberOfItems(); u32 i; for (i = 0; i < itemcount; i++) { Item * const item = items->getItem(i); if (!item) continue; const Item::ItemType type = item->getType(); if (type != Item::ITEM_NITRO_BIG && type != Item::ITEM_NITRO_SMALL && type != Item::ITEM_BONUS_BOX && type != Item::ITEM_BANANA && type != Item::ITEM_BUBBLEGUM) continue; LODNode * const lod = (LODNode *) item->getSceneNode(); if (!lod->isVisible()) continue; const int level = lod->getLevel(); if (level < 0) continue; scene::ISceneNode * const node = lod->getAllNodes()[level]; node->updateAbsolutePosition(); GlowData dat; dat.node = node; dat.r = 1.0f; dat.g = 1.0f; dat.b = 1.0f; const video::SColorf &c = ItemManager::getGlowColor(type); dat.r = c.getRed(); dat.g = c.getGreen(); dat.b = c.getBlue(); glows.push_back(dat); } // Start the RTT for post-processing. // We do this before beginScene() because we want to capture the glClear() // because of tracks that do not have skyboxes (generally add-on tracks) m_post_processing->begin(); RaceGUIBase *rg = world->getRaceGUI(); if (rg) rg->update(dt); if (!CVS->isDefferedEnabled()) { SColor clearColor(0, 150, 150, 150); if (World::getWorld() != NULL) clearColor = World::getWorld()->getClearColor(); glClear(GL_COLOR_BUFFER_BIT); glDepthMask(GL_TRUE); glBindFramebuffer(GL_FRAMEBUFFER, 0); glClearColor(clearColor.getRed() / 255.f, clearColor.getGreen() / 255.f, clearColor.getBlue() / 255.f, clearColor.getAlpha() / 255.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } for(unsigned int cam = 0; cam < Camera::getNumCameras(); cam++) { Camera * const camera = Camera::getCamera(cam); scene::ICameraSceneNode * const camnode = camera->getCameraSceneNode(); std::ostringstream oss; oss << "drawAll() for kart " << cam; PROFILER_PUSH_CPU_MARKER(oss.str().c_str(), (cam+1)*60, 0x00, 0x00); camera->activate(!CVS->isDefferedEnabled()); rg->preRenderCallback(camera); // adjusts start referee m_scene_manager->setActiveCamera(camnode); const core::recti &viewport = camera->getViewport(); if (World::getWorld() && World::getWorld()->getTrack()->hasShadows() && !SphericalHarmonicsTextures.empty()) irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0)); // TODO: put this outside of the rendering loop if (!m_skybox_ready) { prepareSkybox(); m_skybox_ready = true; } if (!CVS->isDefferedEnabled()) glEnable(GL_FRAMEBUFFER_SRGB); PROFILER_PUSH_CPU_MARKER("Update Light Info", 0xFF, 0x0, 0x0); unsigned plc = UpdateLightsInfo(camnode, dt); PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("UBO upload", 0x0, 0xFF, 0x0); computeMatrixesAndCameras(camnode, viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y); uploadLightingData(); PROFILER_POP_CPU_MARKER(); renderScene(camnode, plc, glows, dt, track->hasShadows(), false); // Render bounding boxes if (irr_driver->getBoundingBoxesViz()) { glUseProgram(UtilShader::ColoredLine::getInstance()->Program); glBindVertexArray(UtilShader::ColoredLine::getInstance()->vao); glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::getInstance()->vbo); UtilShader::ColoredLine::getInstance()->setUniforms(SColor(255, 255, 0, 0)); const float *tmp = BoundingBoxes.data(); for (unsigned int i = 0; i < BoundingBoxes.size(); i += 1024 * 6) { unsigned count = MIN2((int)BoundingBoxes.size() - i, 1024 * 6); glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), &tmp[i]); glDrawArrays(GL_LINES, 0, count / 3); } } // Debug physic // Note that drawAll must be called before rendering // the bullet debug view, since otherwise the camera // is not set up properly. This is only used for // the bullet debug view. if (UserConfigParams::m_artist_debug_mode) World::getWorld()->getPhysics()->draw(); if (world != NULL && world->getPhysics() != NULL) { IrrDebugDrawer* debug_drawer = world->getPhysics()->getDebugDrawer(); if (debug_drawer != NULL && debug_drawer->debugEnabled()) { const std::map<video::SColor, std::vector<float> >& lines = debug_drawer->getLines(); std::map<video::SColor, std::vector<float> >::const_iterator it; glUseProgram(UtilShader::ColoredLine::getInstance()->Program); glBindVertexArray(UtilShader::ColoredLine::getInstance()->vao); glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::getInstance()->vbo); for (it = lines.begin(); it != lines.end(); it++) { UtilShader::ColoredLine::getInstance()->setUniforms(it->first); const std::vector<float> &vertex = it->second; const float *tmp = vertex.data(); for (unsigned int i = 0; i < vertex.size(); i += 1024 * 6) { unsigned count = MIN2((int)vertex.size() - i, 1024 * 6); glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), &tmp[i]); glDrawArrays(GL_LINES, 0, count / 3); } } glUseProgram(0); glBindVertexArray(0); } } // Render the post-processed scene if (CVS->isDefferedEnabled()) { bool isRace = StateManager::get()->getGameState() == GUIEngine::GAME; FrameBuffer *fbo = m_post_processing->render(camnode, isRace); if (irr_driver->getNormals()) irr_driver->getFBO(FBO_NORMAL_AND_DEPTHS).BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y); else if (irr_driver->getSSAOViz()) { glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y); m_post_processing->renderPassThrough(m_rtts->getFBO(FBO_HALF1_R).getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y); } else if (irr_driver->getRSM()) { glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y); m_post_processing->renderPassThrough(m_rtts->getRSM().getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y); } else if (irr_driver->getShadowViz()) { renderShadowsDebug(); } else { glEnable(GL_FRAMEBUFFER_SRGB); glBindFramebuffer(GL_FRAMEBUFFER, 0); if (CVS->isDefferedEnabled()) camera->activate(); m_post_processing->renderPassThrough(fbo->getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y); glDisable(GL_FRAMEBUFFER_SRGB); } } // Save projection-view matrix for the next frame camera->setPreviousPVMatrix(m_ProjViewMatrix); PROFILER_POP_CPU_MARKER(); } // for i<world->getNumKarts() // Use full screen size float tmp[2]; tmp[0] = float(m_actual_screen_size.Width); tmp[1] = float(m_actual_screen_size.Height); glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::ViewProjectionMatrixesUBO); glBufferSubData(GL_UNIFORM_BUFFER, (16 * 9) * sizeof(float), 2 * sizeof(float), tmp); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glUseProgram(0); // Set the viewport back to the full screen for race gui m_video_driver->setViewPort(core::recti(0, 0, irr_driver->getActualScreenSize().Width, irr_driver->getActualScreenSize().Height)); for(unsigned int i=0; i<Camera::getNumCameras(); i++) { Camera *camera = Camera::getCamera(i); std::ostringstream oss; oss << "renderPlayerView() for kart " << i; PROFILER_PUSH_CPU_MARKER(oss.str().c_str(), 0x00, 0x00, (i+1)*60); rg->renderPlayerView(camera, dt); PROFILER_POP_CPU_MARKER(); } // for i<getNumKarts { ScopedGPUTimer Timer(getGPUTimer(Q_GUI)); PROFILER_PUSH_CPU_MARKER("GUIEngine", 0x75, 0x75, 0x75); // Either render the gui, or the global elements of the race gui. GUIEngine::render(dt); PROFILER_POP_CPU_MARKER(); } // Render the profiler if(UserConfigParams::m_profiler_enabled) { PROFILER_DRAW(); } #ifdef DEBUG drawDebugMeshes(); #endif PROFILER_PUSH_CPU_MARKER("EndSccene", 0x45, 0x75, 0x45); m_video_driver->endScene(); PROFILER_POP_CPU_MARKER(); getPostProcessing()->update(dt); }
void OBJBaker::createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry) { // Generating FBX Header Node FBXNode headerNode; headerNode.name = FBX_HEADER_EXTENSION; // Generating global settings node // Required for Unit Scale Factor FBXNode globalSettingsNode; globalSettingsNode.name = GLOBAL_SETTINGS_NODE_NAME; // Setting the tree hierarchy: GlobalSettings -> Properties70 -> P -> Properties FBXNode properties70Node; properties70Node.name = PROPERTIES70_NODE_NAME; FBXNode pNode; { pNode.name = P_NODE_NAME; pNode.properties.append({ "UnitScaleFactor", "double", "Number", "", UNIT_SCALE_FACTOR }); } properties70Node.children = { pNode }; globalSettingsNode.children = { properties70Node }; // Generating Object node FBXNode objectNode; objectNode.name = OBJECTS_NODE_NAME; // Generating Object node's child - Geometry node FBXNode geometryNode; geometryNode.name = GEOMETRY_NODE_NAME; NodeID geometryID; { geometryID = nextNodeID(); geometryNode.properties = { geometryID, GEOMETRY_NODE_NAME, MESH }; } // Compress the mesh information and store in dracoNode bool hasDeformers = false; // No concept of deformers for an OBJ FBXNode dracoNode; compressMesh(geometry.meshes[0], hasDeformers, dracoNode); geometryNode.children.append(dracoNode); // Generating Object node's child - Model node FBXNode modelNode; modelNode.name = MODEL_NODE_NAME; NodeID modelID; { modelID = nextNodeID(); modelNode.properties = { modelID, MODEL_NODE_NAME, MESH }; } objectNode.children = { geometryNode, modelNode }; // Generating Objects node's child - Material node auto& meshParts = geometry.meshes[0].parts; for (auto& meshPart : meshParts) { FBXNode materialNode; materialNode.name = MATERIAL_NODE_NAME; if (geometry.materials.size() == 1) { // case when no material information is provided, OBJReader considers it as a single default material for (auto& materialID : geometry.materials.keys()) { setMaterialNodeProperties(materialNode, materialID, geometry); } } else { setMaterialNodeProperties(materialNode, meshPart.materialID, geometry); } objectNode.children.append(materialNode); } // Generating Texture Node // iterate through mesh parts and process the associated textures auto size = meshParts.size(); for (int i = 0; i < size; i++) { QString material = meshParts[i].materialID; FBXMaterial currentMaterial = geometry.materials[material]; if (!currentMaterial.albedoTexture.filename.isEmpty() || !currentMaterial.specularTexture.filename.isEmpty()) { auto textureID = nextNodeID(); _mapTextureMaterial.emplace_back(textureID, i); FBXNode textureNode; { textureNode.name = TEXTURE_NODE_NAME; textureNode.properties = { textureID, "texture" + QString::number(textureID) }; } // Texture node child - TextureName node FBXNode textureNameNode; { textureNameNode.name = TEXTURENAME_NODE_NAME; QByteArray propertyString = (!currentMaterial.albedoTexture.filename.isEmpty()) ? "Kd" : "Ka"; textureNameNode.properties = { propertyString }; } // Texture node child - Relative Filename node FBXNode relativeFilenameNode; { relativeFilenameNode.name = RELATIVEFILENAME_NODE_NAME; } QByteArray textureFileName = (!currentMaterial.albedoTexture.filename.isEmpty()) ? currentMaterial.albedoTexture.filename : currentMaterial.specularTexture.filename; auto textureType = (!currentMaterial.albedoTexture.filename.isEmpty()) ? image::TextureUsage::Type::ALBEDO_TEXTURE : image::TextureUsage::Type::SPECULAR_TEXTURE; // Compress the texture using ModelBaker::compressTexture() and store compressed file's name in the node auto textureFile = compressTexture(textureFileName, textureType); if (textureFile.isNull()) { // Baking failed return handleError("Failed to compress texture: " + textureFileName); return; } relativeFilenameNode.properties = { textureFile }; textureNode.children = { textureNameNode, relativeFilenameNode }; objectNode.children.append(textureNode); } } // Generating Connections node FBXNode connectionsNode; connectionsNode.name = CONNECTIONS_NODE_NAME; // connect Geometry to Model FBXNode cNode; cNode.name = C_NODE_NAME; cNode.properties = { CONNECTIONS_NODE_PROPERTY, geometryID, modelID }; connectionsNode.children = { cNode }; // connect all materials to model for (auto& materialID : _materialIDs) { FBXNode cNode; cNode.name = C_NODE_NAME; cNode.properties = { CONNECTIONS_NODE_PROPERTY, materialID, modelID }; connectionsNode.children.append(cNode); } // Connect textures to materials for (const auto& texMat : _mapTextureMaterial) { FBXNode cAmbientNode; cAmbientNode.name = C_NODE_NAME; cAmbientNode.properties = { CONNECTIONS_NODE_PROPERTY_1, texMat.first, _materialIDs[texMat.second], "AmbientFactor" }; connectionsNode.children.append(cAmbientNode); FBXNode cDiffuseNode; cDiffuseNode.name = C_NODE_NAME; cDiffuseNode.properties = { CONNECTIONS_NODE_PROPERTY_1, texMat.first, _materialIDs[texMat.second], "DiffuseColor" }; connectionsNode.children.append(cDiffuseNode); } // Make all generated nodes children of rootNode rootNode.children = { globalSettingsNode, objectNode, connectionsNode }; }