mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 22:15:15 +02:00
128 lines
4.1 KiB
C++
128 lines
4.1 KiB
C++
//
|
|
// MetavoxelSystem.cpp
|
|
// interface
|
|
//
|
|
// Created by Andrzej Kapolka on 12/10/13.
|
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
|
//
|
|
|
|
#include <QtDebug>
|
|
|
|
#include <SharedUtil.h>
|
|
|
|
#include "Application.h"
|
|
#include "MetavoxelSystem.h"
|
|
|
|
ProgramObject MetavoxelSystem::_program;
|
|
int MetavoxelSystem::_pointScaleLocation;
|
|
|
|
MetavoxelSystem::MetavoxelSystem() :
|
|
_buffer(QOpenGLBuffer::VertexBuffer),
|
|
_pointVisitor(_points) {
|
|
}
|
|
|
|
void MetavoxelSystem::init() {
|
|
if (!_program.isLinked()) {
|
|
switchToResourcesParentIfRequired();
|
|
_program.addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/metavoxel_point.vert");
|
|
_program.link();
|
|
|
|
_pointScaleLocation = _program.uniformLocation("pointScale");
|
|
}
|
|
|
|
MetavoxelPath p1;
|
|
p1 += 7;
|
|
p1 += 7;
|
|
p1 += 7;
|
|
|
|
AttributePointer color = AttributeRegistry::getInstance()->getAttribute("color");
|
|
|
|
_data.setAttributeValue(p1, AttributeValue(color, encodeInline(qRgba(0xFF, 0xFF, 0xFF, 0xFF))));
|
|
|
|
QScriptValue guideFunction = _scriptEngine.evaluate(
|
|
"(function(visitation) { "
|
|
" visitation.visitor.visit(visitation.info);"
|
|
"})");
|
|
_data.setAttributeValue(MetavoxelPath(), AttributeValue(AttributeRegistry::getInstance()->getGuideAttribute(),
|
|
encodeInline(PolymorphicDataPointer(new ScriptedMetavoxelGuide(guideFunction)))));
|
|
|
|
_buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw);
|
|
_buffer.create();
|
|
}
|
|
|
|
void MetavoxelSystem::simulate(float deltaTime) {
|
|
_points.clear();
|
|
_data.guide(_pointVisitor);
|
|
|
|
_buffer.bind();
|
|
int bytes = _points.size() * sizeof(Point);
|
|
if (_buffer.size() < bytes) {
|
|
_buffer.allocate(_points.constData(), bytes);
|
|
} else {
|
|
_buffer.write(0, _points.constData(), bytes);
|
|
}
|
|
_buffer.release();
|
|
}
|
|
|
|
void MetavoxelSystem::render() {
|
|
int viewport[4];
|
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
|
const int VIEWPORT_WIDTH_INDEX = 2;
|
|
const int VIEWPORT_HEIGHT_INDEX = 3;
|
|
float viewportWidth = viewport[VIEWPORT_WIDTH_INDEX];
|
|
float viewportHeight = viewport[VIEWPORT_HEIGHT_INDEX];
|
|
float viewportDiagonal = sqrtf(viewportWidth*viewportWidth + viewportHeight*viewportHeight);
|
|
float worldDiagonal = glm::distance(Application::getInstance()->getViewFrustum()->getNearBottomLeft(),
|
|
Application::getInstance()->getViewFrustum()->getNearTopRight());
|
|
|
|
_program.bind();
|
|
_program.setUniformValue(_pointScaleLocation, viewportDiagonal *
|
|
Application::getInstance()->getViewFrustum()->getNearClip() / worldDiagonal);
|
|
|
|
_buffer.bind();
|
|
|
|
Point* pt = 0;
|
|
glVertexPointer(4, GL_FLOAT, sizeof(Point), &pt->vertex);
|
|
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Point), &pt->color);
|
|
glNormalPointer(GL_BYTE, sizeof(Point), &pt->normal);
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
glEnableClientState(GL_NORMAL_ARRAY);
|
|
|
|
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
|
|
|
|
glDrawArrays(GL_POINTS, 0, _points.size());
|
|
|
|
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
|
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
glDisableClientState(GL_COLOR_ARRAY);
|
|
glDisableClientState(GL_NORMAL_ARRAY);
|
|
|
|
_buffer.release();
|
|
|
|
_program.release();
|
|
}
|
|
|
|
MetavoxelSystem::PointVisitor::PointVisitor(QVector<Point>& points) :
|
|
MetavoxelVisitor(QVector<AttributePointer>() <<
|
|
AttributeRegistry::getInstance()->getColorAttribute() <<
|
|
AttributeRegistry::getInstance()->getNormalAttribute()),
|
|
_points(points) {
|
|
}
|
|
|
|
bool MetavoxelSystem::PointVisitor::visit(const MetavoxelInfo& info) {
|
|
if (!info.isLeaf) {
|
|
return true;
|
|
}
|
|
QRgb color = info.attributeValues.at(0).getInlineValue<QRgb>();
|
|
QRgb normal = info.attributeValues.at(1).getInlineValue<QRgb>();
|
|
int alpha = qAlpha(color);
|
|
if (alpha > 0) {
|
|
Point point = { glm::vec4(info.minimum + glm::vec3(info.size, info.size, info.size) * 0.5f, info.size),
|
|
{ qRed(color), qGreen(color), qBlue(color), alpha }, { qRed(normal), qGreen(normal), qBlue(normal) } };
|
|
_points.append(point);
|
|
}
|
|
return false;
|
|
}
|