Created clipmap geometry

This commit is contained in:
kbladin
2016-04-12 13:44:28 -04:00
parent 48109dd664
commit 05569611da
9 changed files with 243 additions and 115 deletions
@@ -27,16 +27,16 @@
#include <ghoul/opengl/ghoul_gl.h>
namespace {
const std::string _loggerCat = "ClipmapGeometry";
const std::string _loggerCat = "ClipMapGeometry";
}
namespace openspace {
ClipmapGeometry::ClipmapGeometry(
ClipMapGeometry::ClipMapGeometry(
unsigned int resolution,
Positions usePositions = Positions::No,
TextureCoordinates useTextures = TextureCoordinates::No,
Normals useNormals = Normals::No)
Positions usePositions,
TextureCoordinates useTextures,
Normals useNormals)
: Geometry(CreateElements(resolution), usePositions, useTextures, useNormals)
, _resolution(resolution)
{
@@ -51,33 +51,37 @@ ClipmapGeometry::ClipmapGeometry(
}
}
ClipmapGeometry::~ClipmapGeometry()
ClipMapGeometry::~ClipMapGeometry()
{
}
const unsigned int ClipmapGeometry::resolution() const {
const unsigned int ClipMapGeometry::resolution() const {
return _resolution;
}
size_t ClipmapGeometry::numElements(unsigned int resolution)
size_t ClipMapGeometry::numElements(unsigned int resolution)
{
return resolution * resolution / 2 * 9;
}
size_t ClipmapGeometry::numVertices(unsigned int resolution)
size_t ClipMapGeometry::numVertices(unsigned int resolution)
{
return (resolution + 1) * (resolution + 1) - ((resolution / 2 - 1) * (resolution / 2 - 1));
return
(resolution + 1) * (resolution / 4 + 1) + // Bottom
(resolution / 4 + 1) * (resolution / 2 + 1) + // Left
(resolution / 4 + 1) * (resolution / 2 + 1) + // Right
(resolution + 1) * (resolution / 4 + 1); // Top
}
void ClipmapGeometry::validate(unsigned int resolution) {
void ClipMapGeometry::validate(unsigned int resolution) {
ghoul_assert(resolution >= 8,
"Resolution must be at least 8x8. (" << resolution << ")");
"Resolution must be at least 8. (" << resolution << ")");
ghoul_assert(resolution == pow(2, int(log2(resolution))),
"Resolution must be a power of 2. (" << resolution << ")");
}
std::vector<GLuint> ClipmapGeometry::CreateElements(unsigned int resolution) {
std::vector<GLuint> ClipMapGeometry::CreateElements(unsigned int resolution) {
validate(resolution);
std::vector<GLuint> elements;
elements.reserve(numElements(resolution));
@@ -89,13 +93,18 @@ std::vector<GLuint> ClipmapGeometry::CreateElements(unsigned int resolution) {
// x x x x ..
// : : : :
unsigned int numVerticesBottom = (resolution + 1) * (resolution / 4 + 1);
unsigned int numVerticesLeft = (resolution / 4 + 1) * (resolution / 2 + 1);
unsigned int numVerticesRight = (resolution / 4 + 1) * (resolution / 2 + 1);
unsigned int numVerticesTop = (resolution + 1) * (resolution / 4 + 1);
// Build the bottom part of the clipmap geometry
for (unsigned int x = 0; x < resolution; x++) {
for (unsigned int y = 0; y < resolution / 4; y++) {
GLuint v00 = (y + 0)*resolution + x + 0;
GLuint v10 = (y + 0)*resolution + x + 1;
GLuint v01 = (y + 1)*resolution + x + 0;
GLuint v11 = (y + 1)*resolution + x + 1;
for (unsigned int y = 0; y < resolution / 4; y++) {
for (unsigned int x = 0; x < resolution; x++) {
GLuint v00 = (y + 0) * (resolution + 1) + x + 0;
GLuint v10 = (y + 0) * (resolution + 1) + x + 1;
GLuint v01 = (y + 1) * (resolution + 1) + x + 0;
GLuint v11 = (y + 1) * (resolution + 1) + x + 1;
elements.push_back(v00);
elements.push_back(v10);
@@ -103,17 +112,35 @@ std::vector<GLuint> ClipmapGeometry::CreateElements(unsigned int resolution) {
elements.push_back(v00);
elements.push_back(v11);
elements.push_back(v01);
}
}
// Build the left part of the clipmap geometry
for (unsigned int y = 0; y < resolution / 2; y++) {
for (unsigned int x = 0; x < resolution / 4; x++) {
GLuint v00 = numVerticesBottom + (y + 0) * (resolution / 4 + 1) + x + 0;
GLuint v10 = numVerticesBottom + (y + 0) * (resolution / 4 + 1) + x + 1;
GLuint v01 = numVerticesBottom + (y + 1) * (resolution / 4 + 1) + x + 0;
GLuint v11 = numVerticesBottom + (y + 1) * (resolution / 4 + 1) + x + 1;
elements.push_back(v00);
elements.push_back(v10);
elements.push_back(v11);
elements.push_back(v00);
elements.push_back(v11);
elements.push_back(v01);
}
}
// Build the left part of the clipmap geometry
for (unsigned int x = 0; x < resolution / 4; x++) {
for (unsigned int y = resolution / 4 + 2; y < 3 * resolution / 4; y++) {
GLuint v00 = (y + 0)*resolution + x + 0;
GLuint v10 = (y + 0)*resolution + x + 1;
GLuint v01 = (y + 1)*resolution + x + 0;
GLuint v11 = (y + 1)*resolution + x + 1;
for (unsigned int y = 0; y < resolution / 2; y++) {
for (unsigned int x = 0; x < resolution / 4; x++) {
GLuint v00 = numVerticesBottom + numVerticesLeft + (y + 0) * (resolution / 4 + 1) + x + 0;
GLuint v10 = numVerticesBottom + numVerticesLeft + (y + 0) * (resolution / 4 + 1) + x + 1;
GLuint v01 = numVerticesBottom + numVerticesLeft + (y + 1) * (resolution / 4 + 1) + x + 0;
GLuint v11 = numVerticesBottom + numVerticesLeft + (y + 1) * (resolution / 4 + 1) + x + 1;
elements.push_back(v00);
elements.push_back(v10);
@@ -121,17 +148,17 @@ std::vector<GLuint> ClipmapGeometry::CreateElements(unsigned int resolution) {
elements.push_back(v00);
elements.push_back(v11);
elements.push_back(v10);
elements.push_back(v01);
}
}
// Build the right part of the clipmap geometry
for (unsigned int x = 3 * resolution / 4; x < resolution; x++) {
for (unsigned int y = resolution / 4 + 2; y < 3 * resolution / 4; y++) {
GLuint v00 = (y + 0)*resolution + x + 0;
GLuint v10 = (y + 0)*resolution + x + 1;
GLuint v01 = (y + 1)*resolution + x + 0;
GLuint v11 = (y + 1)*resolution + x + 1;
// Build the left part of the clipmap geometry
for (unsigned int y = 0; y < resolution / 4; y++) {
for (unsigned int x = 0; x < resolution; x++) {
GLuint v00 = numVerticesBottom + numVerticesLeft + numVerticesRight + (y + 0) * (resolution + 1) + x + 0;
GLuint v10 = numVerticesBottom + numVerticesLeft + numVerticesRight + (y + 0) * (resolution + 1) + x + 1;
GLuint v01 = numVerticesBottom + numVerticesLeft + numVerticesRight + (y + 1) * (resolution + 1) + x + 0;
GLuint v11 = numVerticesBottom + numVerticesLeft + numVerticesRight + (y + 1) * (resolution + 1) + x + 1;
elements.push_back(v00);
elements.push_back(v10);
@@ -139,31 +166,13 @@ std::vector<GLuint> ClipmapGeometry::CreateElements(unsigned int resolution) {
elements.push_back(v00);
elements.push_back(v11);
elements.push_back(v10);
}
}
// Build the top part of the clipmap geometry
for (unsigned int x = 0; x < resolution; x++) {
for (unsigned int y = 3 * resolution / 4; y < resolution; y++) {
GLuint v00 = (y + 0)*resolution + x + 0;
GLuint v10 = (y + 0)*resolution + x + 1;
GLuint v01 = (y + 1)*resolution + x + 0;
GLuint v11 = (y + 1)*resolution + x + 1;
elements.push_back(v00);
elements.push_back(v10);
elements.push_back(v11);
elements.push_back(v00);
elements.push_back(v11);
elements.push_back(v10);
elements.push_back(v01);
}
}
return elements;
}
std::vector<glm::vec4> ClipmapGeometry::CreatePositions(unsigned int resolution)
std::vector<glm::vec4> ClipMapGeometry::CreatePositions(unsigned int resolution)
{
validate(resolution);
std::vector<glm::vec4> positions;
@@ -183,53 +192,53 @@ std::vector<glm::vec4> ClipmapGeometry::CreatePositions(unsigned int resolution)
}
std::vector<glm::vec2> ClipmapGeometry::CreateTextureCoordinates(unsigned int resolution){
std::vector<glm::vec2> ClipMapGeometry::CreateTextureCoordinates(unsigned int resolution){
validate(resolution);
std::vector<glm::vec2> textureCoordinates;
textureCoordinates.reserve(numVertices(resolution));
// Build the bottom part of the clipmap geometry
for (unsigned int x = 0; x < resolution + 1; x++) {
for (unsigned int y = 0; y < resolution / 4 + 1; y++) {
for (unsigned int y = 0; y < resolution / 4 + 1; y++) {
for (unsigned int x = 0; x < resolution + 1; x++) {
textureCoordinates.push_back(glm::vec2(
static_cast<float>(x) / resolution,
static_cast<float>(y) / resolution));
}
}
// Build the left part of the clipmap geometry
for (unsigned int x = 0; x < resolution / 4 + 1; x++) {
for (unsigned int y = resolution / 4 + 2; y < 3 * resolution / 4 + 1; y++) {
textureCoordinates.push_back(glm::vec2(
static_cast<float>(x) / resolution,
static_cast<float>(y) / resolution));
for (unsigned int y = resolution / 4; y < 3 * resolution / 4 + 1; y++) {
for (unsigned int x = 0; x < resolution / 4 + 1; x++) {
float u = static_cast<float>(x) / resolution;
float v = static_cast<float>(y) / resolution;
textureCoordinates.push_back(glm::vec2(u, v));
}
}
// Build the right part of the clipmap geometry
for (unsigned int x = 3 * resolution / 4 + 1; x < resolution + 1; x++) {
for (unsigned int y = resolution / 4 + 2; y < 3 * resolution / 4 + 1; y++) {
textureCoordinates.push_back(glm::vec2(
static_cast<float>(x) / resolution,
static_cast<float>(y) / resolution));
for (unsigned int y = resolution / 4; y < 3 * resolution / 4 + 1; y++) {
for (unsigned int x = 3 * resolution / 4; x < resolution + 1; x++) {
float u = static_cast<float>(x) / resolution;
float v = static_cast<float>(y) / resolution;
textureCoordinates.push_back(glm::vec2(u, v));
}
}
// Build the top part of the clipmap geometry
for (unsigned int x = 0; x < resolution + 1; x++) {
for (unsigned int y = 3 * resolution / 4 + 1; y < resolution + 1; y++) {
for (unsigned int y = 3 * resolution / 4; y < resolution + 1; y++) {
for (unsigned int x = 0; x < resolution + 1; x++) {
textureCoordinates.push_back(glm::vec2(
static_cast<float>(x) / resolution,
static_cast<float>(y) / resolution));
}
}
return textureCoordinates;
}
std::vector<glm::vec3> ClipmapGeometry::CreateNormals(unsigned int resolution) {
std::vector<glm::vec3> ClipMapGeometry::CreateNormals(unsigned int resolution) {
validate(resolution);
std::vector<glm::vec3> normals;
normals.reserve(numVertices(resolution));
@@ -32,17 +32,17 @@
namespace openspace {
class ClipmapGeometry : public Geometry
class ClipMapGeometry : public Geometry
{
public:
ClipmapGeometry(
ClipMapGeometry(
unsigned int resolution,
Positions usePositions = Positions::No,
TextureCoordinates useTextures = TextureCoordinates::No,
Normals useNormals = Normals::No
);
~ClipmapGeometry();
~ClipMapGeometry();
const unsigned int resolution() const;
@@ -28,6 +28,8 @@
#include <modules/globebrowsing/rendering/clipmapglobe.h>
#include <modules/globebrowsing/rendering/clipmapgeometry.h>
// open space includes
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
@@ -69,12 +71,7 @@ namespace openspace {
// ---------
// init Renderer
auto geometry = std::shared_ptr<Geometry>(new GridGeometry(10, 10,
Geometry::Positions::No,
Geometry::TextureCoordinates::Yes,
Geometry::Normals::No));
auto patchRenderer = new LatLonPatchRenderer(geometry);
auto patchRenderer = new ClipMapPatchRenderer();
_patchRenderer.reset(patchRenderer);
}
@@ -90,30 +87,15 @@ namespace openspace {
}
bool ClipMapGlobe::isReady() const {
bool ready = true;
bool ready = true;
return ready;
}
void ClipMapGlobe::render(const RenderData& data)
{
// Set patch to follow camera
/*
<<<<<<< HEAD
int segmentsPerPatch = 10;
glm::vec2 cameraPositionLatLon =
converter::cartesianToLatLon(data.camera.position().dvec3());
_patch.setPositionLatLon(
glm::vec2((M_PI / 2.0 / segmentsPerPatch) * int(cameraPositionLatLon.x / (M_PI * 2) * segmentsPerPatch * 4),
(M_PI / 2.0 / segmentsPerPatch) * int(cameraPositionLatLon.y / (M_PI)* segmentsPerPatch * 2)));
_patch1.setPositionLatLon(
glm::vec2((M_PI / 4.0 / segmentsPerPatch) * int(cameraPositionLatLon.x / (M_PI * 2) * segmentsPerPatch * 8),
(M_PI / 4.0 / segmentsPerPatch) * int(cameraPositionLatLon.y / (M_PI)* segmentsPerPatch * 4))); // render
=======*/
//_patch.getPatch().setCenter(LatLon::fromCartesian(data.camera.position().dvec3()));
//_patch1.getPatch().setCenter(LatLon::fromCartesian(data.camera.position().dvec3()));
_patch.center = LatLon::fromCartesian(data.camera.position().dvec3());
// render
Vec3 cameraPos = data.camera.position().dvec3();
_patch.center = LatLon::fromCartesian(cameraPos);
_patchRenderer->renderPatch(_patch, data, 6.3e6);
}
@@ -24,6 +24,8 @@
#include <modules/globebrowsing/rendering/patchrenderer.h>
#include <modules/globebrowsing/rendering/clipmapgeometry.h>
// open space includes
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
@@ -63,11 +65,6 @@ namespace openspace {
}
}
void PatchRenderer::renderPatch(const LatLonPatch& patch, const RenderData& data, double radius) {
// nothing to do
}
//////////////////////////////////////////////////////////////////////////////////////
// LATLON PATCH RENDERER //
//////////////////////////////////////////////////////////////////////////////////////
@@ -84,8 +81,6 @@ namespace openspace {
_programObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes);
}
void LatLonPatchRenderer::renderPatch(
const LatLonPatch& patch, const RenderData& data, double radius)
{
@@ -121,6 +116,73 @@ namespace openspace {
// disable shader
_programObject->deactivate();
}
//////////////////////////////////////////////////////////////////////////////////////
// CLIPMAP PATCH RENDERER //
//////////////////////////////////////////////////////////////////////////////////////
ClipMapPatchRenderer::ClipMapPatchRenderer()
: PatchRenderer(shared_ptr<ClipMapGeometry>(new ClipMapGeometry(
8,
Geometry::Positions::No,
Geometry::TextureCoordinates::Yes,
Geometry::Normals::No)))
{
_programObject = OsEng.renderEngine().buildRenderProgram(
"LatLonSphereMappingProgram",
"${MODULE_GLOBEBROWSING}/shaders/clipmappatch_spheremapping_vs.glsl",
"${MODULE_GLOBEBROWSING}/shaders/simple_fs.glsl");
ghoul_assert(_programObject != nullptr, "Failed to initialize programObject!");
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
_programObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes);
}
void ClipMapPatchRenderer::renderPatch(
const LatLonPatch& patch, const RenderData& data, double radius)
{
// activate shader
_programObject->activate();
using namespace glm;
Vec3 cameraPos = data.camera.position().dvec3();
// Get camera transform matrix
// TODO : Should only need to fetch the camera transform and use directly
// but this is not currently possible in the camera class.
vec3 cameraPosition = data.camera.position().vec3();
mat4 viewTransform = inverse(translate(mat4(1.0), cameraPosition));
viewTransform = mat4(data.camera.viewRotationMatrix()) * viewTransform;
// TODO : Model transform should be fetched as a matrix directly.
mat4 modelTransform = translate(mat4(1), data.position.vec3());
// Snap patch position
int segmentsPerPatch = 8;
float stepSize = (M_PI / 2.0 / segmentsPerPatch);
ivec2 intSnapCoord = ivec2(
patch.center.lat / (M_PI * 2) * segmentsPerPatch * 4,
patch.center.lon / (M_PI) * segmentsPerPatch * 2);
LatLon swCorner = LatLon(
stepSize * intSnapCoord.x - patch.halfSize.lat,
stepSize * intSnapCoord.y - patch.halfSize.lon);
ivec2 contraction = ivec2(0, 0);// ivec2(intSnapCoord.y % 2, intSnapCoord.x % 2);
_programObject->setUniform("modelViewProjectionTransform", data.camera.projectionMatrix() * viewTransform * modelTransform);
_programObject->setUniform("minLatLon", vec2(swCorner.lat, swCorner.lon));
_programObject->setUniform("latLonScalingFactor", 2.0f * vec2(patch.halfSize.lat, patch.halfSize.lon));
_programObject->setUniform("globeRadius", float(radius));
_programObject->setUniform("contraction", contraction);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
// render
_geometry->drawUsingActiveProgram();
// disable shader
_programObject->deactivate();
}
} // namespace openspace
@@ -29,14 +29,11 @@
#include <glm/glm.hpp>
// open space includes
#include <openspace/rendering/renderable.h>
#include <modules/globebrowsing/datastructures/latlon.h>
#include <modules/globebrowsing/rendering/gridgeometry.h>
namespace ghoul {
namespace opengl {
class ProgramObject;
@@ -59,7 +56,7 @@ namespace openspace {
PatchRenderer(shared_ptr<Geometry>);
~PatchRenderer();
virtual void renderPatch(const LatLonPatch& patch, const RenderData& data, double radius);
virtual void renderPatch(const LatLonPatch& patch, const RenderData& data, double radius) = 0;
protected:
@@ -83,6 +80,15 @@ namespace openspace {
double radius) override;
};
class ClipMapPatchRenderer : public PatchRenderer {
public:
ClipMapPatchRenderer();
virtual void renderPatch(
const LatLonPatch& patch,
const RenderData& data,
double radius) override;
};
} // namespace openspace
#endif // __LATLONPATCH_H__
@@ -70,8 +70,8 @@ namespace openspace {
// Mainly for debugging purposes @AA
addProperty(_rotation);
//addSwitchValue(std::shared_ptr<ClipMapGlobe>(new ClipMapGlobe(dictionary)), 1e9);
addSwitchValue(std::shared_ptr<ChunkLodGlobe>(new ChunkLodGlobe(dictionary)), 1e9);
addSwitchValue(std::shared_ptr<ClipMapGlobe>(new ClipMapGlobe(dictionary)), 1e9);
//addSwitchValue(std::shared_ptr<ChunkLodGlobe>(new ChunkLodGlobe(dictionary)), 1e9);
addSwitchValue(std::shared_ptr<GlobeMesh>(new GlobeMesh(dictionary)), 1e10);
}
@@ -0,0 +1,69 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
uniform mat4 modelViewProjectionTransform;
uniform float globeRadius;
uniform vec2 minLatLon;
uniform vec2 latLonScalingFactor;
uniform ivec2 contraction; // [-1, 1]
layout(location = 1) in vec2 in_uv;
out vec4 vs_position;
out vec2 vs_uv;
#include "PowerScaling/powerScaling_vs.hglsl"
vec3 latLonToCartesian(float latitude, float longitude, float radius) {
return radius * vec3(
cos(latitude) * cos(longitude),
cos(latitude) * sin(longitude),
sin(latitude));
}
vec3 globalInterpolation(vec2 uv) {
vec2 latLonInput;
latLonInput.x = minLatLon.x + latLonScalingFactor.x * uv.y; // Lat
latLonInput.y = minLatLon.y + latLonScalingFactor.y * uv.x; // Lon
vec3 positionModelSpace = latLonToCartesian(latLonInput.x, latLonInput.y, globeRadius);
return positionModelSpace;
}
void main()
{
vs_uv = in_uv;
vec2 scaledContraction = contraction / 8.0f;
vs_uv += scaledContraction;
vs_uv = clamp(vs_uv, 0, 1);
vs_uv -= scaledContraction;
vec3 p = globalInterpolation(vs_uv);
vec4 position = modelViewProjectionTransform * vec4(p, 1);
gl_Position = z_normalization(position);
}
@@ -46,8 +46,8 @@ vec3 latLonToCartesian(float latitude, float longitude, float radius) {
vec3 globalInterpolation() {
vec2 latLonInput;
latLonInput.x = minLatLon.x + latLonScalingFactor.x * in_UV.x; // Lat
latLonInput.y = minLatLon.y + latLonScalingFactor.y * in_UV.y; // Lon
latLonInput.x = minLatLon.x + latLonScalingFactor.x * in_UV.y; // Lat
latLonInput.y = minLatLon.y + latLonScalingFactor.y * in_UV.x; // Lon
vec3 positionModelSpace = latLonToCartesian(latLonInput.x, latLonInput.y, globeRadius);
return positionModelSpace;
}
+1 -1
View File
@@ -45,7 +45,7 @@ in vec2 vs_uv;
Fragment getFragment() {
Fragment frag;
frag.color = vec4(fract(vs_uv * 1), 0.4,1);
frag.color = vec4(fract(vs_uv * 8), 0.4,1);
frag.depth = pscDepth(vs_position);
return frag;