示例#1
0
void PointArray::estimateCost(const TransformState& transState,
                              bool incrementalDraw, const double* qualities,
                              DrawCount* drawCounts, int numEstimates) const
{
    TransformState relativeTrans = transState.translate(offset());
    V3f relCamera = relativeTrans.cameraPos();
    ClipBox clipBox(relativeTrans);

    std::vector<const OctreeNode*> nodeStack;
    nodeStack.push_back(m_rootNode.get());
    while (!nodeStack.empty())
    {
        const OctreeNode* node = nodeStack.back();
        nodeStack.pop_back();
        if (clipBox.canCull(node->bbox))
            continue;
        if (!node->isLeaf())
        {
            for (int i = 0; i < 8; ++i)
            {
                OctreeNode* n = node->children[i];
                if (n)
                    nodeStack.push_back(n);
            }
            continue;
        }
        for (int i = 0; i < numEstimates; ++i)
        {
            drawCounts[i] += node->drawCount(relCamera, qualities[i],
                                             incrementalDraw);
        }
    }
}
示例#2
0
void TriMesh::drawEdges(QGLShaderProgram& prog,
                        const TransformState& transState) const
{
    unsigned int vertexShaderId = shaderId("meshedge");
    unsigned int vertexArray = getVAO("meshedge");

    transState.translate(offset()).setUniforms(vertexShaderId);

    glBindVertexArray(vertexArray);
    glDrawElements(GL_LINES, (GLsizei)m_edges.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}
示例#3
0
void Annotation::draw(QGLShaderProgram& annotationShaderProg,
                      const TransformState& transState) const
{
    glBindVertexArray(m_vao);
    GLint texture0 = glGetUniformLocation(annotationShaderProg.programId(),
                                          "texture0");
    m_texture->bind(texture0);
    annotationShaderProg.setUniformValue("annotationSize",
                                        m_texture->width(),
                                        m_texture->height());
    transState.translate(m_position)
              .setUniforms(annotationShaderProg.programId());
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glBindTexture(GL_TEXTURE_2D, 0);
    glBindVertexArray(0);
}
示例#4
0
文件: mesh.cpp 项目: gphysics/displaz
void TriMesh::drawEdges(QGLShaderProgram& prog,
                        const TransformState& transState) const
{
    transState.translate(offset()).setUniforms(prog.programId());
    prog.enableAttributeArray("position");
    prog.setAttributeArray("position", GL_FLOAT, &m_verts[0], 3);
    if (m_colors.size() == m_verts.size())
    {
        prog.enableAttributeArray("color");
        prog.setAttributeArray("color", GL_FLOAT, &m_colors[0], 3);
    }
    else
        prog.setAttributeValue("color", GLfloat(1), GLfloat(1), GLfloat(1));
    glDrawElements(GL_LINES, (GLsizei)m_edges.size(),
                   GL_UNSIGNED_INT, &m_edges[0]);
    prog.disableAttributeArray("color");
    prog.disableAttributeArray("position");
}
示例#5
0
void TriMesh::drawFaces(QGLShaderProgram& prog,
                        const TransformState& transState) const
{
    // TODO: The hasTexture uniform shader variable would be unnecessary if we
    // supported more than one mesh face shader...
    GLint hasTextureLoc = glGetUniformLocation(prog.programId(), "hasTexture");
    if (m_texture)
    {
        GLint textureSamplerLoc = glGetUniformLocation(prog.programId(), "texture0");
        if (textureSamplerLoc != -1)
            m_texture->bind(textureSamplerLoc);
    }
    if (hasTextureLoc != -1)
        glUniform1i(hasTextureLoc, m_texture ? 1 : 0);
    unsigned int vertexShaderId = shaderId("meshface");
    unsigned int vertexArray = getVAO("meshface");

    transState.translate(offset()).setUniforms(vertexShaderId);

    glBindVertexArray(vertexArray);
    glDrawElements(GL_TRIANGLES, (GLsizei)m_triangles.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}
示例#6
0
DrawCount PointArray::drawPoints(QGLShaderProgram& prog, const TransformState& transState,
                                 double quality, bool incrementalDraw) const
{
    TransformState relativeTrans = transState.translate(offset());
    relativeTrans.setUniforms(prog.programId());
    //printActiveShaderAttributes(prog.programId());
    std::vector<ShaderAttribute> activeAttrs = activeShaderAttributes(prog.programId());
    // Figure out shader locations for each point field
    // TODO: attributeLocation() forces the OpenGL usage here to be
    // synchronous.  Does this matter?  (Alternative: bind them ourselves.)
    std::vector<const ShaderAttribute*> attributes;
    for (size_t i = 0; i < m_fields.size(); ++i)
    {
        const GeomField& field = m_fields[i];
        if (field.spec.isArray())
        {
            for (int j = 0; j < field.spec.count; ++j)
            {
                std::string name = tfm::format("%s[%d]", field.name, j);
                attributes.push_back(findAttr(name, activeAttrs));
            }
        }
        else
        {
            attributes.push_back(findAttr(field.name, activeAttrs));
        }
    }
    // Zero out active attributes in case they don't have associated fields
    GLfloat zeros[16] = {0};
    for (size_t i = 0; i < activeAttrs.size(); ++i)
    {
        prog.setAttributeValue((int)i, zeros, activeAttrs[i].rows,
                               activeAttrs[i].cols);
    }
    // Enable attributes which have associated fields
    for (size_t i = 0; i < attributes.size(); ++i)
    {
        if (attributes[i])
            prog.enableAttributeArray(attributes[i]->location);
    }

    DrawCount drawCount;
    ClipBox clipBox(relativeTrans);

    // Draw points in each bucket, with total number drawn depending on how far
    // away the bucket is.  Since the points are shuffled, this corresponds to
    // a stochastic simplification of the full point cloud.
    V3f relCamera = relativeTrans.cameraPos();
    std::vector<const OctreeNode*> nodeStack;
    nodeStack.push_back(m_rootNode.get());
    while (!nodeStack.empty())
    {
        const OctreeNode* node = nodeStack.back();
        nodeStack.pop_back();
        if (clipBox.canCull(node->bbox))
            continue;
        if (!node->isLeaf())
        {
            for (int i = 0; i < 8; ++i)
            {
                OctreeNode* n = node->children[i];
                if (n)
                    nodeStack.push_back(n);
            }
            continue;
        }
        size_t idx = node->beginIndex;
        if (!incrementalDraw)
            node->nextBeginIndex = node->beginIndex;

        DrawCount nodeDrawCount = node->drawCount(relCamera, quality, incrementalDraw);
        drawCount += nodeDrawCount;

        idx = node->nextBeginIndex;
        if (nodeDrawCount.numVertices == 0)
            continue;
        for (size_t i = 0, k = 0; i < m_fields.size(); k+=m_fields[i].spec.arraySize(), ++i)
        {
            const GeomField& field = m_fields[i];
            int arraySize = field.spec.arraySize();
            int vecSize = field.spec.vectorSize();
            for (int j = 0; j < arraySize; ++j)
            {
                const ShaderAttribute* attr = attributes[k+j];
                if (!attr)
                    continue;
                char* data = field.data.get() + idx*field.spec.size() +
                             j*field.spec.elsize;
                if (attr->baseType == TypeSpec::Int || attr->baseType == TypeSpec::Uint)
                {
                    glVertexAttribIPointer(attr->location, vecSize,
                                           glBaseType(field.spec), 0, data);
                }
                else
                {
                    glVertexAttribPointer(attr->location, vecSize,
                                          glBaseType(field.spec),
                                          field.spec.fixedPoint, 0, data);
                }
            }
        }
        glDrawArrays(GL_POINTS, 0, (GLsizei)nodeDrawCount.numVertices);
        node->nextBeginIndex += nodeDrawCount.numVertices;
    }
    //tfm::printf("Drew %d of total points %d, quality %f\n", totDraw, m_npoints, quality);

    // Disable all attribute arrays - leaving these enabled seems to screw with
    // the OpenGL fixed function pipeline in unusual ways.
    for (size_t i = 0; i < attributes.size(); ++i)
    {
        if (attributes[i])
            prog.disableAttributeArray(attributes[i]->location);
    }
    return drawCount;
}
示例#7
0
/// Draw the 3D cursor
void View3D::drawCursor(const TransformState& transStateIn, const V3d& cursorPos, float centerPointRadius) const
{
    V3d offset = transStateIn.cameraPos();
    TransformState transState = transStateIn.translate(offset);
    V3d relCursor = cursorPos - offset;

    // Cull if behind camera
    if((relCursor * transState.modelViewMatrix).z > 0)
        return;

    // Find position of cursor in screen space
    V3d screenP3 = relCursor * transState.modelViewMatrix * transState.projMatrix;
    // Position in ortho coord system
    V2f p2 = 0.5f * V2f(width(), height()) * (V2f(screenP3.x, screenP3.y) + V2f(1.0f));

    // Draw cursor
    if (m_cursorShader->isValid())
    {
        QGLShaderProgram& cursorShader = m_cursorShader->shaderProgram();
        // shader
        cursorShader.bind();
        // vertex array
        glBindVertexArray(m_cursorVertexArray);

        transState.projMatrix.makeIdentity();
        transState.setOrthoProjection(0, width(), 0, height(), 0, 1);
        transState.modelViewMatrix.makeIdentity();

        if (centerPointRadius > 0)
        {
            // fake drawing of white point through scaling ...
            //
            TransformState pointState = transState.translate( V3d(p2.x, p2.y, 0) );
            pointState = pointState.scale( V3d(0.0,0.0,0.0) );
            glLineWidth(centerPointRadius);
            cursorShader.setUniformValue("color", 1.0f, 1.0f, 1.0f, 1.0f);
            pointState.setUniforms(cursorShader.programId());
            glDrawArrays( GL_POINTS, 0, 1 );
        }

        // Now draw a 2D overlay over the 3D scene to allow user to pinpoint the
        // cursor, even when when it's behind something.
        glDisable(GL_DEPTH_TEST);

        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glEnable(GL_LINE_SMOOTH);

        glLineWidth(1); // this won't work anymore for values larger than 1 (2.0f);

        // draw white lines
        transState = transState.translate( V3d(p2.x, p2.y, 0) );
        cursorShader.setUniformValue("color", 1.0f, 1.0f, 1.0f, 1.0f);
        transState.setUniforms(cursorShader.programId());
        glDrawArrays( GL_LINES, 0, 8 );

        // draw black lines
        transState = transState.rotate( V4d(0,0,1,0.785398) ); //45 deg
        cursorShader.setUniformValue("color", 0.0f, 0.0f, 0.0f, 1.0f);
        transState.setUniforms(cursorShader.programId());
        glDrawArrays( GL_LINES, 0, 8 );
    }
}
示例#8
0
DrawCount PointArray::drawPoints(QGLShaderProgram& prog, const TransformState& transState,
                                 double quality, bool incrementalDraw) const
{
    GLuint vao = getVAO("points");
    glBindVertexArray(vao);

    GLuint vbo = getVBO("point_buffer");
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    TransformState relativeTrans = transState.translate(offset());
    relativeTrans.setUniforms(prog.programId());
    //printActiveShaderAttributes(prog.programId());
    std::vector<ShaderAttribute> activeAttrs = activeShaderAttributes(prog.programId());
    // Figure out shader locations for each point field
    // TODO: attributeLocation() forces the OpenGL usage here to be
    // synchronous.  Does this matter?  (Alternative: bind them ourselves.)
    std::vector<const ShaderAttribute*> attributes;
    for (size_t i = 0; i < m_fields.size(); ++i)
    {
        const GeomField& field = m_fields[i];
        if (field.spec.isArray())
        {
            for (int j = 0; j < field.spec.count; ++j)
            {
                std::string name = tfm::format("%s[%d]", field.name, j);
                attributes.push_back(findAttr(name, activeAttrs));
            }
        }
        else
        {
            attributes.push_back(findAttr(field.name, activeAttrs));
        }
    }
    // Zero out active attributes in case they don't have associated fields
    GLfloat zeros[16] = {0};
    for (size_t i = 0; i < activeAttrs.size(); ++i)
    {
        prog.setAttributeValue((int)i, zeros, activeAttrs[i].rows,
                               activeAttrs[i].cols);
    }
    // Enable attributes which have associated fields
    for (size_t i = 0; i < attributes.size(); ++i)
    {
        if (attributes[i])
            prog.enableAttributeArray(attributes[i]->location);
    }

    DrawCount drawCount;
    ClipBox clipBox(relativeTrans);

    // Draw points in each bucket, with total number drawn depending on how far
    // away the bucket is.  Since the points are shuffled, this corresponds to
    // a stochastic simplification of the full point cloud.
    V3f relCamera = relativeTrans.cameraPos();
    std::vector<const OctreeNode*> nodeStack;
    nodeStack.push_back(m_rootNode.get());
    while (!nodeStack.empty())
    {
        const OctreeNode* node = nodeStack.back();
        nodeStack.pop_back();
        if (clipBox.canCull(node->bbox))
            continue;
        if (!node->isLeaf())
        {
            for (int i = 0; i < 8; ++i)
            {
                OctreeNode* n = node->children[i];
                if (n)
                    nodeStack.push_back(n);
            }
            continue;
        }
        size_t idx = node->beginIndex;
        if (!incrementalDraw)
            node->nextBeginIndex = node->beginIndex;

        DrawCount nodeDrawCount = node->drawCount(relCamera, quality, incrementalDraw);
        drawCount += nodeDrawCount;

        idx = node->nextBeginIndex;
        if (nodeDrawCount.numVertices == 0)
            continue;

        if (m_fields.size() < 1)
            continue;

        long bufferSize = 0;
        for (size_t i = 0; i < m_fields.size(); ++i)
        {
            const GeomField &field = m_fields[i];
            unsigned int arraySize = field.spec.arraySize();
            unsigned int vecSize = field.spec.vectorSize();

            // tfm::printfln("FIELD-NAME: %s", field.name);
            // tfm::printfln("AS: %i, VS: %i, FSS: %i, FSES: %i, GLBTFSS: %i", arraySize, vecSize, field.spec.size(), field.spec.elsize, sizeof(glBaseType(field.spec)));

            bufferSize += arraySize * vecSize * field.spec.elsize; //sizeof(glBaseType(field.spec));
        }

        bufferSize = bufferSize * (GLsizei)nodeDrawCount.numVertices;

        // TODO: might be able to do something more efficient here, for example use glBufferSubData to avoid re-allocation of memory by glBufferData
        // INITIALIZE THE BUFFER TO FULL SIZE
        // tfm::printfln("INIT BUFFER: %i, BS: %i", vbo, bufferSize);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)bufferSize, NULL, GL_STREAM_DRAW);
        /// ========================================================================
        /// ========================================================================
        GLintptr bufferOffset = 0;

        for (size_t i = 0, k = 0; i < m_fields.size(); k+=m_fields[i].spec.arraySize(), ++i)
        {
            const GeomField& field = m_fields[i];
            int arraySize = field.spec.arraySize();
            int vecSize = field.spec.vectorSize();

            // TODO: should use a single data-array that isn't split into vertex / normal / color / etc. sections, but has interleaved data ?
            // OpenGL has a stride value in glVertexAttribPointer for exactly this purpose, which should be used for better efficiency
            // here we write only the current attribute data into this the buffer (e.g. all positions, then all colors)
            bufferSize = arraySize * vecSize * field.spec.elsize * (GLsizei)nodeDrawCount.numVertices; //sizeof(glBaseType(field.spec))

            char* bufferData = field.data.get() + idx*field.spec.size();
            glBufferSubData(GL_ARRAY_BUFFER, bufferOffset, bufferSize, bufferData);

            // tfm::printfln("UPDATE BUFFER: %i, BS: %i", vbo, bufferSize);

            for (int j = 0; j < arraySize; ++j)
            {
                const ShaderAttribute* attr = attributes[k+j];
                if (!attr)
                    continue;

                // we have to create an intermediate buffer offsets for glVertexAttribPointer, but we can still upload the whole data array earlier !?
                GLintptr intermediate_bufferOffset = bufferOffset + j*field.spec.elsize;

                if (attr->baseType == TypeSpec::Int || attr->baseType == TypeSpec::Uint)
                {
                    glVertexAttribIPointer(attr->location, vecSize,
                                           glBaseType(field.spec), 0, (const GLvoid *)intermediate_bufferOffset);
                }
                else
                {
                    glVertexAttribPointer(attr->location, vecSize,
                                          glBaseType(field.spec),
                                          field.spec.fixedPoint, 0, (const GLvoid *)intermediate_bufferOffset);
                }

                glEnableVertexAttribArray(attr->location);
            }

            bufferOffset += bufferSize;
        }

        glDrawArrays(GL_POINTS, 0, (GLsizei)nodeDrawCount.numVertices);
        node->nextBeginIndex += nodeDrawCount.numVertices;
    }
    //tfm::printf("Drew %d of total points %d, quality %f\n", totDraw, m_npoints, quality);

    // Disable all attribute arrays - leaving these enabled seems to screw with
    // the OpenGL fixed function pipeline in unusual ways.
    for (size_t i = 0; i < attributes.size(); ++i)
    {
        if (attributes[i])
            prog.disableAttributeArray(attributes[i]->location);
    }

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    return drawCount;
}