Exemple #1
0
void PageBoundary::drawClipped (
    Canvas* c, Coord l, Coord b, Coord r, Coord t, Graphic* gs
) {
    Coord x0, y0, x1, y1, x2, y2;
    BoxObj clipBox(l, b, r, t);
    
    transform(0, 0, x0, y0, gs);
    transform(border, pageheight, x1, y1, gs);
    transform(pagewidth, border, x2, y2, gs);

    BoxObj lbox(x0, y0, x1, y1);
    BoxObj bbox(x0, y0, x2, y2);
    
    transform(pagewidth - border, 0, x0, y0, gs);
    transform(0, pageheight - border, x1, y1, gs);
    transform(pagewidth, pageheight, x2, y2, gs);

    BoxObj rbox(x0, y0, x2, y2);
    BoxObj tbox(x1, y1, x2, y2);

    update(gs);
    if (lbox.Intersects(clipBox)) {
	pFillRect(c, 0, 0, border, pageheight);
    }
    if (bbox.Intersects(clipBox)) {
	pFillRect(c, 0, 0, pagewidth, border);
    }
    if (rbox.Intersects(clipBox)) {
	pFillRect(c, pagewidth - border, 0, pagewidth, pageheight);
    }
    if (tbox.Intersects(clipBox)) {
	pFillRect(c, 0, pageheight - border, pagewidth, pageheight);
    }
}
Exemple #2
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);
        }
    }
}
Exemple #3
0
    void Level::render(Graphics & gfx)
    {
        m_renderManager.clear();

        if(r_map != NULL)
            r_map->registerRender(m_renderManager);

        const sf::FloatRect & viewRect = gfx.getCurrentView().GetRect();
        AxisAlignedBB clipBox(viewRect.Left, viewRect.Top, viewRect.Right, viewRect.Bottom);

        std::list<SpaceDivision*> divs;
        m_spaceDivider.getDivisionsFromBox(divs, clipBox);

        std::list<SpaceDivision*>::iterator it1;
        std::map<int,Entity*>::iterator it2;
        Entity * e;
        SpaceDivision * div;

        // Only render entities of space divisions within the view clippig rectangle
        for(it1 = divs.begin(); it1 != divs.end(); it1++)
        {
            div = *it1;
            for(it2 = div->entities.begin(); it2 != div->entities.end(); it2++)
            {
                e = it2->second;
                if(e->isDrawable() && e->getType() != ENT_MAP)
                    e->registerRender(m_renderManager);
            }
        }
        m_renderManager.render(gfx);
    }
Exemple #4
0
void BSplineSelection::drawClipped (Canvas* c, Coord l, Coord b, Coord r,
Coord t, Graphic* gs) {
    BoxObj box;
    getBox(box, gs);

    BoxObj clipBox(l, b, r, t);
    if (clipBox.Intersects(box)) {
	draw(c, gs);
    }
}
Exemple #5
0
void Graphic::eraseClipped (
    Canvas* c, Coord left, Coord bottom, Coord right, Coord top, Graphic* gs
) {
    BoxObj thisBox;
    BoxObj clipBox(left, bottom, right, top);

    getBox(thisBox, gs);
    if (clipBox.Intersects(thisBox)) {
        erase(c, gs);
    }
}
Exemple #6
0
void Graphic31::drawclipped_gs (
    Canvas* c, Coord l, Coord b, Coord r, Coord t, Graphic31* gs
) {
    Coord ll, bb, rr, tt;
    getbounds_gs(ll, bb, rr, tt, gs);

    BoxObj thisBox(ll, bb, rr, tt);
    BoxObj clipBox(l, b, r, t);
    if (clipBox.Intersects(thisBox)) {
	draw_gs(c, gs);
    }
}
Exemple #7
0
void Picture::drawClipped (
    Canvas* c, Coord l, Coord b, Coord r, Coord t, Graphic* gs
) {
    BoxObj box, clipBox(l, b, r, t);
    
    getBox(box, gs);

    if (clipBox.Intersects(box)) {
        Iterator i;
        FullGraphic gstemp;
        Transformer ttemp;
	gstemp.SetTransformer(&ttemp);

        for (First(i); !Done(i); Next(i)) {
	    Graphic* gr = GetGraphic(i);
	    concatGraphic(gr, gr, gs, &gstemp);
	    drawClippedGraphic(gr, c, l, b, r, t, &gstemp);
	}
	gstemp.SetTransformer(nil); /* to avoid deleting ttemp explicitly */
    }
}
Exemple #8
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;
}
Exemple #9
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;
}