From 0a3d6ae5e05d8ea768e7f1acdb5d44e6f089cbb7 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 21 Jan 2014 19:31:56 -0800 Subject: [PATCH] More work on metavoxel editing (grid, etc.) --- interface/resources/shaders/grid.frag | 13 ++++++ interface/src/renderer/GeometryCache.cpp | 48 ++++++++++++++++++++++ interface/src/renderer/GeometryCache.h | 3 ++ interface/src/ui/MetavoxelEditorDialog.cpp | 46 +++++++++++++++++++++ interface/src/ui/MetavoxelEditorDialog.h | 4 ++ 5 files changed, 114 insertions(+) create mode 100644 interface/resources/shaders/grid.frag diff --git a/interface/resources/shaders/grid.frag b/interface/resources/shaders/grid.frag new file mode 100644 index 0000000000..c62241cc3e --- /dev/null +++ b/interface/resources/shaders/grid.frag @@ -0,0 +1,13 @@ +#version 120 + +// +// grid.frag +// fragment shader +// +// Created by Andrzej Kapolka on 1/21/14. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// + +void main(void) { + gl_FragColor = vec4(gl_Color.rgb, exp(-0.25 / gl_FragCoord.w)); +} diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index 9fff306aca..bdb3916694 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -7,7 +7,11 @@ #include +// include this before QOpenGLBuffer, which includes an earlier version of OpenGL +#include "InterfaceConfig.h" + #include +#include #include "Application.h" #include "GeometryCache.h" @@ -241,6 +245,50 @@ void GeometryCache::renderHalfCylinder(int slices, int stacks) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } +void GeometryCache::renderGrid(int xDivisions, int yDivisions) { + QOpenGLBuffer& buffer = _gridBuffers[IntPair(xDivisions, yDivisions)]; + int vertices = (xDivisions + 1 + yDivisions + 1) * 2; + if (!buffer.isCreated()) { + GLfloat* vertexData = new GLfloat[vertices * 2]; + GLfloat* vertex = vertexData; + for (int i = 0; i <= xDivisions; i++) { + float x = (float)i / xDivisions; + + *(vertex++) = x; + *(vertex++) = 0.0f; + + *(vertex++) = x; + *(vertex++) = 1.0f; + } + for (int i = 0; i <= yDivisions; i++) { + float y = (float)i / yDivisions; + + *(vertex++) = 0.0f; + *(vertex++) = y; + + *(vertex++) = 1.0f; + *(vertex++) = y; + } + buffer.create(); + buffer.setUsagePattern(QOpenGLBuffer::StaticDraw); + buffer.bind(); + buffer.allocate(vertexData, vertices * 2 * sizeof(GLfloat)); + delete[] vertexData; + + } else { + buffer.bind(); + } + glEnableClientState(GL_VERTEX_ARRAY); + + glVertexPointer(2, GL_FLOAT, 0, 0); + + glDrawArrays(GL_LINES, 0, vertices); + + glDisableClientState(GL_VERTEX_ARRAY); + + buffer.release(); +} + QSharedPointer GeometryCache::getGeometry(const QUrl& url) { QSharedPointer geometry = _networkGeometry.value(url); if (geometry.isNull()) { diff --git a/interface/src/renderer/GeometryCache.h b/interface/src/renderer/GeometryCache.h index 8a68917ba5..312d8bcd91 100644 --- a/interface/src/renderer/GeometryCache.h +++ b/interface/src/renderer/GeometryCache.h @@ -19,6 +19,7 @@ #include "InterfaceConfig.h" class QNetworkReply; +class QOpenGLBuffer; class NetworkGeometry; class NetworkMesh; @@ -33,6 +34,7 @@ public: void renderHemisphere(int slices, int stacks); void renderSquare(int xDivisions, int yDivisions); void renderHalfCylinder(int slices, int stacks); + void renderGrid(int xDivisions, int yDivisions); /// Loads geometry from the specified URL. QSharedPointer getGeometry(const QUrl& url); @@ -45,6 +47,7 @@ private: QHash _hemisphereVBOs; QHash _squareVBOs; QHash _halfCylinderVBOs; + QHash _gridBuffers; QHash > _networkGeometry; }; diff --git a/interface/src/ui/MetavoxelEditorDialog.cpp b/interface/src/ui/MetavoxelEditorDialog.cpp index b21cfb0840..73319cdc08 100644 --- a/interface/src/ui/MetavoxelEditorDialog.cpp +++ b/interface/src/ui/MetavoxelEditorDialog.cpp @@ -79,6 +79,13 @@ MetavoxelEditorDialog::MetavoxelEditorDialog() : connect(Application::getInstance(), SIGNAL(renderingInWorldInterface()), SLOT(render())); show(); + + if (_gridProgram.isLinked()) { + return; + } + switchToResourcesParentIfRequired(); + _gridProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/grid.frag"); + _gridProgram.link(); } void MetavoxelEditorDialog::updateValueEditor() { @@ -138,7 +145,44 @@ void MetavoxelEditorDialog::updateGridPosition() { } void MetavoxelEditorDialog::render() { + const float GRID_BRIGHTNESS = 0.5f; + glColor3f(GRID_BRIGHTNESS, GRID_BRIGHTNESS, GRID_BRIGHTNESS); + glDisable(GL_LIGHTING); + glPushMatrix(); + + glm::quat rotation; + switch (_gridPlane->currentIndex()) { + case GRID_PLANE_XZ: + rotation = glm::angleAxis(90.0f, 1.0f, 0.0f, 0.0f); + glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); + break; + + case GRID_PLANE_YZ: + rotation = glm::angleAxis(-90.0f, 0.0f, 1.0f, 0.0f); + glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + break; + } + + // center the grid around the camera position on the plane + glm::vec3 rotated = rotation * Application::getInstance()->getCamera()->getPosition(); + float spacing = _gridSpacing->value(); + const int GRID_DIVISIONS = 300; + glTranslatef(spacing * (floor(rotated.x / spacing) - GRID_DIVISIONS / 2), + spacing * (floor(rotated.y / spacing) - GRID_DIVISIONS / 2), _gridPosition->value()); + + float scale = GRID_DIVISIONS * spacing; + glScalef(scale, scale, scale); + + _gridProgram.bind(); + + Application::getInstance()->getGeometryCache()->renderGrid(GRID_DIVISIONS, GRID_DIVISIONS); + + _gridProgram.release(); + + glPopMatrix(); + + glEnable(GL_LIGHTING); } void MetavoxelEditorDialog::updateAttributes(const QString& select) { @@ -164,3 +208,5 @@ QString MetavoxelEditorDialog::getSelectedAttribute() const { QList selectedItems = _attributes->selectedItems(); return selectedItems.isEmpty() ? QString() : selectedItems.first()->text(); } + +ProgramObject MetavoxelEditorDialog::_gridProgram; diff --git a/interface/src/ui/MetavoxelEditorDialog.h b/interface/src/ui/MetavoxelEditorDialog.h index 530a858a94..872cc50810 100644 --- a/interface/src/ui/MetavoxelEditorDialog.h +++ b/interface/src/ui/MetavoxelEditorDialog.h @@ -11,6 +11,8 @@ #include +#include "renderer/ProgramObject.h" + class QComboBox; class QDoubleSpinBox; class QGroupBox; @@ -42,6 +44,8 @@ private: QDoubleSpinBox* _gridSpacing; QDoubleSpinBox* _gridPosition; QGroupBox* _value; + + static ProgramObject _gridProgram; }; #endif /* defined(__interface__MetavoxelEditorDialog__) */