2352 lines · 101.2 KB · C++
RawDownload
    glTranslatef(translation.x, translation.y, translation.z);    glm::quat rotation = sphere->getRotation();    glm::vec3 axis = glm::axis(rotation);    glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);        Application::getInstance()->getDeferredLightingEffect()->renderSolidSphere(sphere->getScale(), 32, 32);        glPopMatrix();} CuboidRenderer::CuboidRenderer() {} void CuboidRenderer::render(const MetavoxelLOD& lod, bool contained, bool cursor) {    Cuboid* cuboid = static_cast<Cuboid*>(_spanner);    const QColor& color = cuboid->getColor();    glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF());        glPushMatrix();    const glm::vec3& translation = cuboid->getTranslation();    glTranslatef(translation.x, translation.y, translation.z);    glm::quat rotation = cuboid->getRotation();    glm::vec3 axis = glm::axis(rotation);    glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);    glScalef(1.0f, cuboid->getAspectY(), cuboid->getAspectZ());        Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(cuboid->getScale() * 2.0f);        glPopMatrix();} StaticModelRenderer::StaticModelRenderer() :    _model(new Model(this)) {} void StaticModelRenderer::init(Spanner* spanner) {    SpannerRenderer::init(spanner);     _model->init();        StaticModel* staticModel = static_cast<StaticModel*>(spanner);    applyTranslation(staticModel->getTranslation());    applyRotation(staticModel->getRotation());    applyScale(staticModel->getScale());    applyURL(staticModel->getURL());        connect(spanner, SIGNAL(translationChanged(const glm::vec3&)), SLOT(applyTranslation(const glm::vec3&)));    connect(spanner, SIGNAL(rotationChanged(const glm::quat&)), SLOT(applyRotation(const glm::quat&)));    connect(spanner, SIGNAL(scaleChanged(float)), SLOT(applyScale(float)));    connect(spanner, SIGNAL(urlChanged(const QUrl&)), SLOT(applyURL(const QUrl&)));} void StaticModelRenderer::simulate(float deltaTime) {    // update the bounds    Box bounds;    if (_model->isActive()) {        const Extents& extents = _model->getGeometry()->getFBXGeometry().meshExtents;        bounds = Box(extents.minimum, extents.maximum);    }    static_cast<StaticModel*>(_spanner)->setBounds(glm::translate(_model->getTranslation()) *        glm::mat4_cast(_model->getRotation()) * glm::scale(_model->getScale()) * bounds);    _model->simulate(deltaTime);} void StaticModelRenderer::render(const MetavoxelLOD& lod, bool contained, bool cursor) {    _model->render();} bool StaticModelRenderer::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const {    RayIntersectionInfo info;    info._rayStart = origin;    info._rayDirection = direction;    if (!_model->findRayIntersection(info)) {        return false;    }    distance = info._hitDistance;    return true;} void StaticModelRenderer::applyTranslation(const glm::vec3& translation) {    _model->setTranslation(translation);} void StaticModelRenderer::applyRotation(const glm::quat& rotation) {    _model->setRotation(rotation);} void StaticModelRenderer::applyScale(float scale) {    _model->setScale(glm::vec3(scale, scale, scale));} void StaticModelRenderer::applyURL(const QUrl& url) {    _model->setURL(url);} HeightfieldRenderer::HeightfieldRenderer() {} const int X_MAXIMUM_FLAG = 1;const int Y_MAXIMUM_FLAG = 2; static void renderNode(const HeightfieldNodePointer& node, Heightfield* heightfield, const MetavoxelLOD& lod,        const glm::vec2& minimum, float size, bool contained, bool cursor) {    const glm::quat& rotation = heightfield->getRotation();    glm::vec3 scale(heightfield->getScale() * size, heightfield->getScale() * heightfield->getAspectY(),        heightfield->getScale() * heightfield->getAspectZ() * size);    glm::vec3 translation = heightfield->getTranslation() + rotation * glm::vec3(minimum.x * heightfield->getScale(),        0.0f, minimum.y * heightfield->getScale() * heightfield->getAspectZ());    if (!contained) {        Frustum::IntersectionType type = Application::getInstance()->getMetavoxels()->getFrustum().getIntersectionType(            glm::translate(translation) * glm::mat4_cast(rotation) * Box(glm::vec3(), scale));        if (type == Frustum::NO_INTERSECTION) {            return;        }        if (type == Frustum::CONTAINS_INTERSECTION) {            contained = true;        }    }    if (!node->isLeaf() && lod.shouldSubdivide(minimum, size)) {        float nextSize = size * 0.5f;        for (int i = 0; i < HeightfieldNode::CHILD_COUNT; i++) {            renderNode(node->getChild(i), heightfield, lod, minimum + glm::vec2(i & X_MAXIMUM_FLAG ? nextSize : 0.0f,                i & Y_MAXIMUM_FLAG ? nextSize : 0.0f), nextSize, contained, cursor);        }        return;    }    HeightfieldNodeRenderer* renderer = static_cast<HeightfieldNodeRenderer*>(node->getRenderer());    if (!renderer) {        node->setRenderer(renderer = new HeightfieldNodeRenderer());    }    renderer->render(node, translation, rotation, scale, cursor);} void HeightfieldRenderer::render(const MetavoxelLOD& lod, bool contained, bool cursor) {    Heightfield* heightfield = static_cast<Heightfield*>(_spanner);    renderNode(heightfield->getRoot(), heightfield, heightfield->transformLOD(lod), glm::vec2(), 1.0f, contained, cursor);} HeightfieldNodeRenderer::HeightfieldNodeRenderer() :    _heightTextureID(0),    _colorTextureID(0),    _materialTextureID(0) {} HeightfieldNodeRenderer::~HeightfieldNodeRenderer() {    QMetaObject::invokeMethod(Application::getInstance()->getMetavoxels(), "deleteTextures", Q_ARG(int, _heightTextureID),        Q_ARG(int, _colorTextureID), Q_ARG(int, _materialTextureID));} void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const glm::vec3& translation,        const glm::quat& rotation, const glm::vec3& scale, bool cursor) {    if (!node->getHeight()) {        return;    }    int width = node->getHeight()->getWidth();    int height = node->getHeight()->getContents().size() / width;    int innerWidth = width - 2 * HeightfieldHeight::HEIGHT_BORDER;    int innerHeight = height - 2 * HeightfieldHeight::HEIGHT_BORDER;    int vertexCount = width * height;    int rows = height - 1;    int columns = width - 1;    int indexCount = rows * columns * 3 * 2;    BufferPair& bufferPair = _bufferPairs[IntPair(width, height)];    if (!bufferPair.first.isCreated()) {        QVector<HeightfieldPoint> vertices(vertexCount);        HeightfieldPoint* point = vertices.data();                float xStep = 1.0f / (innerWidth - 1);        float zStep = 1.0f / (innerHeight - 1);        float z = -zStep;        float sStep = 1.0f / width;        float tStep = 1.0f / height;        float t = tStep / 2.0f;        for (int i = 0; i < height; i++, z += zStep, t += tStep) {            float x = -xStep;            float s = sStep / 2.0f;            const float SKIRT_LENGTH = 0.25f;            float baseY = (i == 0 || i == height - 1) ? -SKIRT_LENGTH : 0.0f;            for (int j = 0; j < width; j++, point++, x += xStep, s += sStep) {                point->vertex = glm::vec3(x, (j == 0 || j == width - 1) ? -SKIRT_LENGTH : baseY, z);                point->textureCoord = glm::vec2(s, t);            }        }                bufferPair.first.setUsagePattern(QOpenGLBuffer::StaticDraw);        bufferPair.first.create();        bufferPair.first.bind();        bufferPair.first.allocate(vertices.constData(), vertexCount * sizeof(HeightfieldPoint));        bufferPair.first.release();                QVector<int> indices(indexCount);        int* index = indices.data();        for (int i = 0; i < rows; i++) {            int lineIndex = i * width;            int nextLineIndex = (i + 1) * width;            for (int j = 0; j < columns; j++) {                *index++ = lineIndex + j;                *index++ = nextLineIndex + j;                *index++ = nextLineIndex + j + 1;                                *index++ = nextLineIndex + j + 1;                *index++ = lineIndex + j + 1;                *index++ = lineIndex + j;            }        }                bufferPair.second = QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);        bufferPair.second.create();        bufferPair.second.bind();        bufferPair.second.allocate(indices.constData(), indexCount * sizeof(int));        bufferPair.second.release();    }    if (_heightTextureID == 0) {        glGenTextures(1, &_heightTextureID);        glBindTexture(GL_TEXTURE_2D, _heightTextureID);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);        const QVector<quint16>& heightContents = node->getHeight()->getContents();        glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, width, height, 0,            GL_RED, GL_UNSIGNED_SHORT, heightContents.constData());            glGenTextures(1, &_colorTextureID);        glBindTexture(GL_TEXTURE_2D, _colorTextureID);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);        if (node->getColor()) {            const QByteArray& contents = node->getColor()->getContents();            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, node->getColor()->getWidth(),                contents.size() / (node->getColor()->getWidth() * DataBlock::COLOR_BYTES),                0, GL_RGB, GL_UNSIGNED_BYTE, contents.constData());                    } else {            const quint8 WHITE_COLOR[] = { 255, 255, 255 };            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, WHITE_COLOR);        }                glGenTextures(1, &_materialTextureID);        glBindTexture(GL_TEXTURE_2D, _materialTextureID);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);        if (node->getMaterial()) {            const QByteArray& contents = node->getMaterial()->getContents();            glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, node->getMaterial()->getWidth(),                contents.size() / node->getMaterial()->getWidth(),                0, GL_RED, GL_UNSIGNED_BYTE, contents.constData());                            const QVector<SharedObjectPointer>& materials = node->getMaterial()->getMaterials();            _networkTextures.resize(materials.size());            for (int i = 0; i < materials.size(); i++) {                const SharedObjectPointer& material = materials.at(i);                if (material) {                    _networkTextures[i] = Application::getInstance()->getTextureCache()->getTexture(                        static_cast<MaterialObject*>(material.data())->getDiffuse(), SPLAT_TEXTURE);                }            }        } else {            const quint8 ZERO_VALUE = 0;            glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 1, 1, 0, GL_RED, GL_UNSIGNED_BYTE, &ZERO_VALUE);        }        glBindTexture(GL_TEXTURE_2D, 0);    }        if (cursor) {        bufferPair.first.bind();        bufferPair.second.bind();            glPushMatrix();        glTranslatef(translation.x, translation.y, translation.z);        glm::vec3 axis = glm::axis(rotation);        glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);        glScalef(scale.x, scale.y, scale.z);                HeightfieldPoint* point = 0;        glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex);        glTexCoordPointer(2, GL_FLOAT, sizeof(HeightfieldPoint), &point->textureCoord);                glBindTexture(GL_TEXTURE_2D, _heightTextureID);                glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0);                glBindTexture(GL_TEXTURE_2D, 0);                glPopMatrix();                bufferPair.first.release();        bufferPair.second.release();        return;    }    HeightfieldBaseLayerBatch baseBatch;    baseBatch.vertexBuffer = &bufferPair.first;    baseBatch.indexBuffer = &bufferPair.second;    baseBatch.translation = translation;    baseBatch.rotation = rotation;    baseBatch.scale = scale;    baseBatch.vertexCount = vertexCount;    baseBatch.indexCount = indexCount;    baseBatch.heightTextureID = _heightTextureID;    baseBatch.heightScale = glm::vec4(1.0f / width, 1.0f / height, (innerWidth - 1) / -2.0f, (innerHeight - 1) / -2.0f);    baseBatch.colorTextureID = _colorTextureID;    baseBatch.colorScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight);    Application::getInstance()->getMetavoxels()->addHeightfieldBaseBatch(baseBatch);            if (!_networkTextures.isEmpty()) {        HeightfieldSplatBatch splatBatch;        splatBatch.vertexBuffer = &bufferPair.first;        splatBatch.indexBuffer = &bufferPair.second;        splatBatch.translation = translation;        splatBatch.rotation = rotation;        splatBatch.scale = scale;        splatBatch.vertexCount = vertexCount;        splatBatch.indexCount = indexCount;        splatBatch.heightTextureID = _heightTextureID;        splatBatch.heightScale = glm::vec4(1.0f / width, 1.0f / height, 0.0f, 0.0f);        splatBatch.materialTextureID = _materialTextureID;        splatBatch.textureScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight);        splatBatch.splatTextureOffset = glm::vec2(            glm::dot(translation, rotation * glm::vec3(1.0f, 0.0f, 0.0f)) / scale.x,            glm::dot(translation, rotation * glm::vec3(0.0f, 0.0f, 1.0f)) / scale.z);                const QVector<SharedObjectPointer>& materials = node->getMaterial()->getMaterials();        for (int i = 0; i < materials.size(); i += SPLAT_COUNT) {            for (int j = 0; j < SPLAT_COUNT; j++) {                int index = i + j;                if (index < _networkTextures.size()) {                    const NetworkTexturePointer& texture = _networkTextures.at(index);                    if (texture) {                        MaterialObject* material = static_cast<MaterialObject*>(materials.at(index).data());                        splatBatch.splatTextureScalesS[j] = scale.x / material->getScaleS();                        splatBatch.splatTextureScalesT[j] = scale.z / material->getScaleT();                        splatBatch.splatTextureIDs[j] = texture->getID();                                            } else {                        splatBatch.splatTextureIDs[j] = 0;                    }                } else {                    splatBatch.splatTextureIDs[j] = 0;                }            }            splatBatch.materialIndex = i;            Application::getInstance()->getMetavoxels()->addHeightfieldSplatBatch(splatBatch);        }    }} QHash<HeightfieldNodeRenderer::IntPair, HeightfieldNodeRenderer::BufferPair> HeightfieldNodeRenderer::_bufferPairs; 

Lines 2001–2352 of 2352. Previous lines