void View3D::drawGrid() const { glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); TransformState transState(Imath::V2i(width(), height()), m_camera.projectionMatrix(), m_camera.viewMatrix()); // Draw grid if (m_gridShader->isValid()) { QGLShaderProgram &gridShader = m_gridShader->shaderProgram(); // shader gridShader.bind(); // vertex buffer glBindVertexArray(m_gridVertexArray); // matrix stack transState.setUniforms(gridShader.programId()); // draw glLineWidth(1); // this won't work anymore for values larger than 1 (2.0f); glDrawArrays(GL_LINES, 0, (22 * 2)); // do NOT release shader, this is no longer supported in OpenGL 3.2 } }
void execTransBackStatement(void) { SymTableNodePtr prevState = CurModule->getPrevState(); if(!prevState) runtimeError(ABL_ERR_RUNTIME_NULL_PREVSTATE); transState(prevState); getCodeToken(); }
void execTransStatement(void) { getCodeToken(); getCodeToken(); SymTableNodePtr idPtr = getCodeSymTableNodePtr(); transState(idPtr); getCodeToken(); }
void View3D::drawAxes() const { glDisable(GL_DEPTH_TEST); TransformState projState(Imath::V2i(width(), height()), Imath::M44d(), Imath::M44d()); projState.projMatrix.makeIdentity(); projState.setOrthoProjection(0, width(), 0, height(), 0, 1); projState.modelViewMatrix.makeIdentity(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); const GLint w = 64; // Width of axes widget const GLint o = 8; // Axes widget offset in x and y // Center of axis overlay const V3d center(o+w/2,o+w/2,0.0); TransformState transState(Imath::V2i(width(), height()), m_camera.projectionMatrix(), m_camera.viewMatrix()); // Draw Background texture if (m_axesBackgroundShader->isValid()) { QGLShaderProgram& axesBackgroundShader = m_axesBackgroundShader->shaderProgram(); GLint textureSampler = glGetUniformLocation(axesBackgroundShader.programId(), "texture0"); // texture m_drawAxesBackground.bind(textureSampler); // shader axesBackgroundShader.bind(); // vertex buffer glBindVertexArray(m_quadVertexArray); // matrix stack projState.setUniforms(axesBackgroundShader.programId()); // draw glDrawArrays( GL_TRIANGLES, 0, 6 ); // do NOT release shader, this is no longer supported in OpenGL 3.2 glBindVertexArray(0); } // Draw axes if (m_axesShader->isValid()) { //tfm::printfln("drawing with m_axesShader"); QGLShaderProgram& axesShader = m_axesShader->shaderProgram(); // shader axesShader.bind(); // vertex buffer glBindVertexArray(m_axesVertexArray); // matrix stack axesShader.setUniformValue("center", center.x, center.y, center.z); projState.modelViewMatrix = m_camera.rotationMatrix(); projState.setUniforms(axesShader.programId()); // draw glLineWidth(1); // this won't work anymore for values larger than 1 (4.0f); glDrawArrays( GL_LINES, 0, 6 ); // do NOT release shader, this is no longer supported in OpenGL 3.2 } // Draw Labels const double r = 0.8; // 80% towards edge of circle // TODO: check if we should do this again: // Note that V3d -> V3i (double to integer precision) // conversion is intentionally snapping the label to // integer co-ordinates to eliminate subpixel aliasing // artifacts. This is also the reason that matrix // transformations are not being used for this. const V3d px = V3d(1.0,0.0,0.0)*r*w/2; const V3d py = V3d(0.0,1.0,0.0)*r*w/2; const V3d pz = V3d(0.0,0.0,1.0)*r*w/2; if (m_axesLabelShader->isValid()) { QGLShaderProgram& axesLabelShader = m_axesLabelShader->shaderProgram(); GLint textureSampler = glGetUniformLocation(axesLabelShader.programId(), "texture0"); // shader axesLabelShader.bind(); // vertex buffer glBindVertexArray(m_quadLabelVertexArray); // matrix stack projState.setUniforms(axesLabelShader.programId()); // adjust positions axesLabelShader.setUniformValue("center", center.x, center.y, center.z); // offset axesLabelShader.setUniformValue("offset", px.x, px.y, px.z); // texture m_drawAxesLabelX.bind(textureSampler); // draw glDrawArrays( GL_TRIANGLES, 0, 6 ); axesLabelShader.setUniformValue("offset", py.x, py.y, py.z); // texture m_drawAxesLabelY.bind(textureSampler); // draw glDrawArrays( GL_TRIANGLES, 0, 6 ); axesLabelShader.setUniformValue("offset", pz.x, pz.y, pz.z); // texture m_drawAxesLabelZ.bind(textureSampler); // draw glDrawArrays( GL_TRIANGLES, 0, 6 ); // do NOT release shader, this is no longer supported in OpenGL 3.2 } }
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(); }