Beispiel #1
0
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
    }
}
Beispiel #2
0
void execTransBackStatement(void)
{
	SymTableNodePtr prevState = CurModule->getPrevState();
	if(!prevState)
		runtimeError(ABL_ERR_RUNTIME_NULL_PREVSTATE);
	transState(prevState);
	getCodeToken();
}
Beispiel #3
0
void execTransStatement(void)
{
	getCodeToken();
	getCodeToken();
	SymTableNodePtr idPtr = getCodeSymTableNodePtr();
	transState(idPtr);
	getCodeToken();
}
Beispiel #4
0
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
    }
}
Beispiel #5
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();
}