// Renders the requested list of faces // Normal faces are rendered with vertex arrays and multitexturing. The first TMU handles the // lightmap, while the second TMU handles the surface texture itself. int GLDriver::drawGeometryList(GeometryList* l) { Assert(l != NULL); if(lastTime == 0) lastTime = timeGetTime(); renderTime = timeGetTime(); qmap = l->mapData; ShaderUtils::renderTime = renderTime; ShaderUtils::qmap = qmap; ShaderUtils::textureFactory = textureFactory; qsort(l->faces, l->faceCount, sizeof(int), TransSort); glActiveTextureARB(GL_TEXTURE1_ARB); glDisable(GL_TEXTURE_2D); glClientActiveTextureARB(GL_TEXTURE1_ARB); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glActiveTextureARB(GL_TEXTURE0_ARB); glEnable(GL_TEXTURE_2D); glClientActiveTextureARB(GL_TEXTURE0_ARB); glDepthFunc(GL_LEQUAL); float timeDiff = renderTime - lastTime; drawSky(l, timeDiff); drawFaces(l, timeDiff); drawMeshes(l, timeDiff); drawPatches(l); //drawFog(l); lastTime = renderTime; return 0; }
/*! Draws the the nodes meshes with SLNode::drawMeshes and calls recursively the drawRec method of the nodes children. The nodes object matrix (SLNode::_om) is multiplied before the meshes are drawn. This recursive drawing is more expensive than the flat drawing with the opaqueNodes vector because of the additional matrix multiplications. The order of drawing doesn't matter in flat drawing because the world matrix (SLNode::_wm) is used for transform. See also SLNode::drawMeshes. The drawRec method is <b>still used</b> for the rendering of the 2D menu! */ void SLNode::drawRec(SLSceneView* sv) { // Do frustum culling for all shapes except cameras & lights if (sv->doFrustumCulling() && !_aabb.isVisible()) return; _stateGL->pushModelViewMatrix(); _stateGL->modelViewMatrix.multiply(_om.m()); _stateGL->buildInverseAndNormalMatrix(); /////////////// drawMeshes(sv); /////////////// for (auto child : _children) child->drawRec(sv); _stateGL->popModelViewMatrix(); // Draw axis aligned bounding box SLbool showBBOX = sv->drawBit(SL_DB_BBOX) || drawBit(SL_DB_BBOX); SLbool showAXIS = sv->drawBit(SL_DB_AXIS) || drawBit(SL_DB_AXIS); SLbool showSELECT = drawBit(SL_DB_SELECTED); if (showBBOX || showAXIS || showSELECT) { _stateGL->pushModelViewMatrix(); _stateGL->modelViewMatrix.setMatrix(sv->camera()->updateAndGetVM().m()); // Draw AABB of all other shapes only if (showBBOX && !showSELECT) { if (_meshes.size() > 0) _aabb.drawWS(SLCol3f(1,0,0)); else _aabb.drawWS(SLCol3f(1,0,1)); } if (showAXIS) _aabb.drawAxisWS(); // Draw AABB if shapes is selected if (showSELECT) _aabb.drawWS(SLCol3f(1,1,0)); _stateGL->popModelViewMatrix(); } }
//////////////////////////////////////////////////////////////////////////////// // SoftShadowsRenderer::render() //////////////////////////////////////////////////////////////////////////////// void SoftShadowsRenderer::render(float deltaTime) { // Frame counter m_frameNumber++; // Bind all our textures and samplers for (GLuint unit = 0; unit < NumTextureUnits; ++unit) { glActiveTexture(GL_TEXTURE0 + unit); glBindTexture(GL_TEXTURE_2D, m_textures[unit]); glBindSampler(unit, m_samplers[unit]); } // // STEP 1: render shadow map from the light's point of view // if (m_shadowTechnique != None || m_visualizeDepthTexture) { GLuint prevFBO = 0; // Enum has MANY names based on extension/version // but they all map to 0x8CA6 glGetIntegerv(0x8CA6, (GLint*)&prevFBO); glBindFramebuffer(GL_FRAMEBUFFER, m_shadowMapFramebuffer); glViewport(0, 0, LIGHT_RES, LIGHT_RES); glClear(GL_DEPTH_BUFFER_BIT); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(4.0f, 32.0f); m_shadowMapShader->enable(); drawMeshes(*m_shadowMapShader); m_shadowMapShader->disable(); glDisable(GL_POLYGON_OFFSET_FILL); glBindFramebuffer(GL_FRAMEBUFFER, prevFBO); glViewport(0, 0, m_screenWidth, m_screenHeight); } // // STEP 2: render scene from the eye's point of view // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (m_visualizeDepthTexture) { m_visTexShader->enable(); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); NvDrawQuadGL( m_visTexShader->getPositionAttrHandle(), m_visTexShader->getTexCoordAttrHandle()); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); m_visTexShader->disable(); } else { // To reduce overdraw, do a depth prepass to layout z m_depthPrepassShader->enable(); drawMeshes(*m_depthPrepassShader); drawGround(*m_depthPrepassShader); m_depthPrepassShader->disable(); // Do the shading pass EyeShader *shader = 0; switch (m_shadowTechnique) { case None: shader = m_pcssShader; m_pcssShader->enable(); m_pcssShader->setShadowTechnique(static_cast<GLint>(m_shadowTechnique)); break; case PCSS: shader = m_pcssShader; m_pcssShader->enable(); m_pcssShader->setShadowTechnique(static_cast<GLint>(m_shadowTechnique)); m_pcssShader->setSamplePattern(static_cast<GLint>(m_pcssSamplePattern)); break; case PCF: shader = m_pcssShader; m_pcssShader->enable(); m_pcssShader->setShadowTechnique(static_cast<GLint>(m_shadowTechnique)); m_pcssShader->setSamplePattern(static_cast<GLint>(m_pcfSamplePattern)); break; } if (shader != 0) { glDepthFunc(GL_EQUAL); drawMeshes(*shader); drawGround(*shader); shader->disable(); glDepthFunc(GL_LEQUAL); } CHECK_GL_ERROR(); } for (GLuint unit = 0; unit < NumTextureUnits; ++unit) { glBindSampler(unit, 0); } }
void View3D::paintGL() { if (m_badOpenGL) return; QTime frameTimer; frameTimer.start(); // Get window size double dPR = getDevicePixelRatio(); int w = width() * dPR; int h = height() * dPR; // detecting a change in the device pixel ratio, since only the new QWindow (Qt5) would // provide a signal for screen changes and this is the easiest solution if (dPR != m_devicePixelRatio) { m_devicePixelRatio = dPR; resizeGL(w, h); } glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_incrementalFramebuffer); //-------------------------------------------------- // Draw main scene TransformState transState(Imath::V2i(w, h), m_camera.projectionMatrix(), m_camera.viewMatrix()); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glClearColor(m_backgroundColor.redF(), m_backgroundColor.greenF(), m_backgroundColor.blueF(), 1.0f); if (!m_incrementalDraw) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); std::vector<const Geometry*> geoms = selectedGeometry(); // Draw bounding boxes if(m_drawBoundingBoxes && !m_incrementalDraw) { if (m_boundingBoxShader->isValid()) { QGLShaderProgram &boundingBoxShader = m_boundingBoxShader->shaderProgram(); // shader boundingBoxShader.bind(); // matrix stack transState.setUniforms(boundingBoxShader.programId()); for (size_t i = 0; i < geoms.size(); ++i) { drawBoundingBox(transState, geoms[i]->getVAO("boundingbox"), geoms[i]->boundingBox().min, Imath::C3f(1), geoms[i]->shaderId("boundingbox")); //boundingBoxShader.programId() } } } // Draw meshes and lines if (!m_incrementalDraw) { drawMeshes(transState, geoms); // Generic draw for any other geometry // (TODO: make all geometries use this interface, or something similar) // FIXME - Do generic quality scaling const double quality = 1; for (size_t i = 0; i < geoms.size(); ++i) geoms[i]->draw(transState, quality); } // Aim for 40ms frame time - an ok tradeoff for desktop usage const double targetMillisecs = 40; double quality = m_drawCostModel.quality(targetMillisecs, geoms, transState, m_incrementalDraw); // Render points DrawCount drawCount = drawPoints(transState, geoms, quality, m_incrementalDraw); // Measure frame time to update estimate for how much geometry we can draw // with a reasonable frame rate glFinish(); int frameTime = frameTimer.elapsed(); if (!geoms.empty()) m_drawCostModel.addSample(drawCount, frameTime); // Debug: print bar showing how well we're sticking to the frame time // int barSize = 40; // std::string s = std::string(barSize*frameTime/targetMillisecs, '='); // if ((int)s.size() > barSize) // s[barSize] = '|'; // tfm::printfln("%12f %4d %s", quality, frameTime, s); // TODO: this should really render a texture onto a quad and not use glBlitFramebuffer glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, m_incrementalFramebuffer); glBlitFramebuffer(0,0,w,h, 0,0,w,h, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); // has to be GL_NEAREST to work with DEPTH // Draw a grid for orientation purposes if (m_drawGrid) drawGrid(); // Draw overlay stuff, including cursor position. if (m_drawCursor) drawCursor(transState, m_cursorPos, 10); //drawCursor(transState, m_camera.center(), 10); // Draw overlay axes if (m_drawAxes) drawAxes(); // Set up timer to draw a high quality frame if necessary if (!drawCount.moreToDraw) m_incrementalFrameTimer->stop(); else m_incrementalFrameTimer->start(10); m_incrementalDraw = true; glFrameBufferStatus(m_incrementalFramebuffer); glCheckError(); }
// ----------- draw void Plant::draw(){ // rig.draw(); // drawPolylines(); drawMeshes(); }