Finalized first draft for the SceneGraph

- Refactored several files
- Implemented PositionInformation subclasses
- Added standard shaders in the shader directory
- Removed SceneGraphLoader, now integrated in the SceneGraph

- TODO: Further testing and improvements to the PowerScale coordinate
system
This commit is contained in:
Jonas Strandstedt
2014-03-13 11:21:30 -04:00
parent 9833c3c8d4
commit b1eab2cf03
29 changed files with 897 additions and 833 deletions
+115
View File
@@ -0,0 +1,115 @@
/**
Copyright (C) 2012-2014 Jonas Strandstedt
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 400 core
uniform mat4 ViewProjection;
uniform mat4 ModelTransform;
uniform vec4 campos;
uniform vec4 objpos;
uniform float time;
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform sampler2D texture3;
uniform float TessLevel;
uniform bool Wireframe;
uniform bool Lightsource;
uniform bool UseTexture;
in vec2 vs_st;
//in vec3 vs_stp;
in vec4 vs_normal;
in vec4 vs_position;
out vec4 diffuse;
const float k = 10.0;
vec4 psc_normlization(vec4 invec) {
float xymax = max(invec.x,invec.y);
if(invec.z > 0.0f || invec.z < 0.0f) {
return invec / abs(invec.z);
} else if (xymax != 0.0f) {
return invec / xymax;
} else {
return invec / -.0;
}
}
void main()
{
// Observable universe is 10^27m, setting the far value to extremely high, aka 30!! ERMAHGERD!
float s_far = 27.0; //= gl_DepthRange.far; // 40
float s_farcutoff = 12.0;
float s_nearcutoff = 7.0;
float s_near = 0.0f;// gl_DepthRange.near; // 0.1
float depth;
// the value can be normalized to 1
vec4 p = vs_position;
if(vs_position.w <= 0.5) {
//depth = abs(vs_position.z * pow(10, vs_position.w)) / pow(k,s_far);
depth = (vs_position.w+log(abs(vs_position.z)))/pow(k, vs_position.w);
} else if(vs_position.w < 3.0) {
depth = vs_position.w+log(abs(vs_position.z))/pow(k, vs_position.w);
} else {
depth = vs_position.w+log(abs(vs_position.z));
}
// DEBUG
float depth_orig = depth;
float x = 0.0f;
float cutoffs = 0.0;
float orig_z = vs_position.z;
// calculate a normalized depth [0.0 1.0]
if((depth > s_near && depth <= s_nearcutoff) || (depth > s_farcutoff && depth < s_far)) {
// completely linear interpolation [s_near .. depth .. s_far]
depth = (depth - s_near) / (s_far - s_near);
} else if(depth > s_nearcutoff && depth < s_farcutoff) {
// DEBUG
cutoffs = 1.0;
// interpolate [10^s_nearcutoff .. 10^depth .. 10^s_farcutoff]
// calculate between 0..1 where the depth is
x = (pow(10,depth) - pow(10, s_nearcutoff)) / (pow(10,s_farcutoff) - pow(10, s_nearcutoff));
// remap the depth to the 0..1 depth buffer
depth = s_nearcutoff + x * (s_farcutoff - s_nearcutoff);
depth = (depth - s_near) / (s_far - s_near);
} else {
// where am I?
// do I need to be discarded?
// discard;
}
// set the depth
gl_FragDepth = depth;
//gl_FragDepth = 0.5;
// color
diffuse = texture(texture1, vs_st);
//diffuse = vec4(vs_position.z,0.0, 0.0, 1.0);
// diffuse = vec4(vs_position.xyz * pow(10, vs_position.w), 1.0);
//diffuse = vec4(vs_st, 0.0, 1.0);
//diffuse = vec4(1.0,1.0, 0.0, 1.0);
//diffuse = vec4(depth*5,0.0, 0.0, 1.0);
//diffuse = vec4(vs_position.w,0.0, 0.0, 1.0);
//diffuse = vec4(1.0,0.0,0.0,1.0);
}
+115
View File
@@ -0,0 +1,115 @@
/**
Copyright (C) 2012-2014 Jonas Strandstedt
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 400 core
uniform mat4 ViewProjection;
uniform mat4 ModelTransform;
uniform vec4 campos;
uniform mat4 camrot;
uniform vec2 scaling;
uniform vec4 objpos;
uniform float time;
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform sampler2D texture3;
uniform float TessLevel;
uniform bool Wireframe;
uniform bool Lightsource;
uniform bool UseTexture;
layout(location = 0) in vec4 in_position;
//in vec3 in_position;
layout(location = 1) in vec2 in_st;
layout(location = 2) in vec3 in_normal;
out vec2 vs_st;
out vec3 vs_stp;
out vec4 vs_normal;
out vec4 vs_position;
const float k = 10.0;
const float dgr_to_rad = 0.0174532925;
vec4 psc_addition(vec4 v1, vec4 v2) {
float ds = v2.w - v1.w;
if(ds >= 0) {
float p = pow(k,-ds);
return vec4(v1.x*p + v2.x, v1.y*p + v2.y, v1.z*p + v2.z, v2.w);
} else {
float p = pow(k,ds);
return vec4(v1.x + v2.x*p, v1.y + v2.y*p, v1.z + v2.z*p, v1.w);
}
}
vec4 psc_to_meter(vec4 v1, vec2 v2) {
float factor = v2.x * pow(k,v2.y + v1.w);
return vec4(v1.xyz * factor, 1.0);
}
vec4 psc_scaling(vec4 v1, vec2 v2) {
float ds = v2.y - v1.w;
if(ds >= 0) {
return vec4(v1.xyz * v2.x * pow(k,v1.w), v2.y);
} else {
return vec4(v1.xyz * v2.x * pow(k,v2.y), v1.w);
}
}
void main()
{
// set variables
vs_st = in_st;
//vs_stp = in_position.xyz;
vs_normal = normalize(ModelTransform * vec4(in_normal,0));
// fetch model and view translation
//vec4 vertex_translate = ModelTransform[3];
// rotate and scale vertex with model transform and add the translation
vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz;
//vec4 lvp = ModelTransform * in_position;
// PSC addition; local vertex position and the object power scaled world position
vs_position = psc_addition(vec4(local_vertex_pos,in_position.w),objpos);
//vs_position = psc_addition(lvp,objpos);
// PSC addition; rotated and viewscaled vertex and the cmaeras negative position
vs_position = psc_addition(vs_position,vec4(-campos.xyz,campos.w));
// rotate the camera
local_vertex_pos = mat3(camrot) * vs_position.xyz;
vs_position = vec4(local_vertex_pos, vs_position.w);
//vs_position = camrot* vs_position;
// rescales the scene to fit inside the view frustum
// is set from the main program, but these are decent values
// scaling = vec2(1.0, -8.0);
// project using the rescaled coordinates,
//vec4 vs_position_rescaled = psc_scaling(vs_position, scaling);
vec4 vs_position_rescaled = psc_to_meter(vs_position, scaling);
//vs_position = vs_position_rescaled;
// project the position to view space
gl_Position = ViewProjection * vs_position_rescaled;
}
+1 -1
View File
@@ -73,7 +73,7 @@ source_group(Rendering FILES ${RENDERING_SOURCE} ${RENDERING_HEADER})
file(GLOB SCENEGRAPH_SOURCE ${SOURCE_ROOT_DIR}/scenegraph/*.cpp)
set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${SCENEGRAPH_SOURCE})
file(GLOB SCENEGRAPH_HEADER ${HEADER_ROOT_DIR}/scenegraph/*.h)
file(GLOB SCENEGRAPH_HEADER ${HEADER_ROOT_DIR}/scenegraph/*.h ${HEADER_ROOT_DIR}/scenegraph/*.inl)
set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${SCENEGRAPH_HEADER})
source_group(SceneGraph FILES ${SCENEGRAPH_SOURCE} ${SCENEGRAPH_HEADER})
+3 -2
View File
@@ -227,7 +227,7 @@ double InteractionHandler::getDt() {
void InteractionHandler::keyboardCallback(int key, int action) {
// TODO package in script
const double speed = 0.75;
const double speed = 2.75;
const double dt = getDt();
if (key == 'S') {
glm::vec3 euler(speed * dt, 0.0, 0.0);
@@ -277,6 +277,7 @@ void InteractionHandler::keyboardCallback(int key, int action) {
pss dist(speed * dt, 8.0);
distance(dist);
}
/*
if (key == '1') {
SceneGraphNode* node = getSceneGraphNode("sun");
@@ -301,7 +302,7 @@ void InteractionHandler::keyboardCallback(int key, int action) {
getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 0.5, 8.0));
getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0));
}
*/
}
void InteractionHandler::mouseButtonCallback(int key, int action) {
-11
View File
@@ -12,17 +12,6 @@
#include <mutex>
#include <memory>
// hack until we have a file/path manager
//#ifdef __WIN32__
//#ifdef NDEBUG
//#define RELATIVE_PATH ""
//#else
//#define RELATIVE_PATH "../../../"
//#endif
//#else
//#define RELATIVE_PATH "../"
//#endif
namespace openspace {
class InteractionHandler {
+2 -2
View File
@@ -130,6 +130,7 @@ bool OpenSpaceEngine::initialize() {
FileSys.registerPathToken("${SCRIPTS}", "${BASE_PATH}/scripts");
FileSys.registerPathToken("${OPENSPACE-DATA}", "${BASE_PATH}/openspace-data");
FileSys.registerPathToken("${SCENEPATH}", "${OPENSPACE-DATA}/scene");
FileSys.registerPathToken("${SHADERS}", "${BASE_PATH}/shaders");
// Load the configurationmanager with the default configuration
_engine->_configurationManager->initialize();
@@ -146,9 +147,8 @@ bool OpenSpaceEngine::initialize() {
DeviceIdentifier::init();
DeviceIdentifier::ref().scanDevices();
_engine->_interactionHandler->connectDevices();
return true;
}
-34
View File
@@ -70,40 +70,6 @@ private:
#define OsEng (openspace::OpenSpaceEngine::ref())
/*
class RenderEngine: public Object {
public:
// constructors & destructor
RenderEngine(int argc, char **argv);
~RenderEngine();
// sgct wrapped functions
bool init();
void preSync();
void postSyncPreDraw();
void render();
void postDraw();
void keyboardCallback(int key, int action);
void mouseButtonCallback(int key, int action);
void mousePosCallback(int x, int y);
void mouseScrollCallback(int pos);
// object extensions
virtual void encode();
virtual void decode();
private:
double masterTime_;
Camera *mainCamera_;
//MouseExternalControl *mouseControl_;
//KeyboardExternalControl *keyboardControl_;
SceneGraph *sceneGraph_;
glm::vec3 eyePosition_;
};
*/
} // namespace openspace
#endif // __OPENSPACEENGINE_H__
+64 -6
View File
@@ -2,25 +2,81 @@
// open space includes
#include "renderableplanet.h"
#include <ghoul/opengl/texturereader.h>
#include <ghoul/filesystem/filesystem.h>
#include <openspaceengine.h>
#include <sgct.h>
namespace {
std::string _loggerCat = "RenderablePlanet";
}
namespace openspace {
RenderablePlanet::RenderablePlanet(): programObject_(nullptr), texture_(nullptr) {}
RenderablePlanet::RenderablePlanet(): programObject_(nullptr), texture_(nullptr),
planet_(nullptr) {}
RenderablePlanet::~RenderablePlanet() {
delete planet_;
}
bool RenderablePlanet::initialize() {
if (programObject_ == nullptr) {
OsEng.ref().configurationManager().getValue("pscShader", programObject_);
}
if (programObject_ == nullptr) {
return false;
}
return true;
}
bool RenderablePlanet::initializeWithDictionary(ghoul::Dictionary* dictionary) {
if ( ! initialize()) {
return false;
}
double value = 1.0f, exponent= 0.0f;
double segments = 20.0;
if(dictionary->hasKey("Geometry.Radius.1"))
dictionary->getValue("Geometry.Radius.1", value);
if(dictionary->hasKey("Geometry.Radius.2"))
dictionary->getValue("Geometry.Radius.2", exponent);
if(dictionary->hasKey("Geometry.Segments"))
dictionary->getValue("Geometry.Segments", segments);
// create the power scaled scalar
pss planetSize(value, exponent);
setBoundingSphere(planetSize);
// get path if available
std::string path;
dictionary->getValue("Path", path);
if(dictionary->hasKey("Textures.Color")) {
std::string texturePath;
dictionary->getValue("Textures.Color", texturePath);
std::string fullpath = path + "/" + texturePath;
texture_ = ghoul::opengl::loadTexture(fullpath);
if (texture_) {
LDEBUG("Loaded texture from '" << fullpath <<"'");
texture_->uploadTexture();
}
}
planet_ = new PowerScaledSphere(pss(value, exponent), static_cast<int>(segments));
return true;
}
void RenderablePlanet::setProgramObject(ghoul::opengl::ProgramObject *programObject = nullptr) {
assert(programObject) ;
assert(programObject);
programObject_ = programObject;
}
@@ -34,7 +90,7 @@ void RenderablePlanet::render(const Camera *camera, const psc &thisPosition) {
// check so that the shader is set
assert(programObject_);
assert(texture_);
// activate shader
programObject_->activate();
@@ -42,9 +98,11 @@ void RenderablePlanet::render(const Camera *camera, const psc &thisPosition) {
psc currentPosition = thisPosition;
psc campos = camera->getPosition();
glm::mat4 camrot = camera->getViewRotationMatrix();
pss scaling = camera->getScaling();
// scale the planet to appropriate size since the planet is a unit sphere
glm::mat4 transform = glm::mat4(1);
transform = glm::rotate(transform, 4.1f*static_cast<float>(sgct::Engine::instance()->getTime()), glm::vec3(0.0f, 1.0f, 0.0f));
// setup the data to the shader
programObject_->setUniform("ViewProjection", camera->getViewProjectionMatrix());
@@ -52,9 +110,9 @@ void RenderablePlanet::render(const Camera *camera, const psc &thisPosition) {
programObject_->setUniform("campos", campos.getVec4f());
programObject_->setUniform("objpos", currentPosition.getVec4f());
programObject_->setUniform("camrot", camrot);
programObject_->setUniform("scaling", camera->getScaling());
programObject_->setUniform("scaling", scaling.getVec2f());
//// if texture is availible, use it
// Bind texture
glActiveTexture(GL_TEXTURE0);
texture_->bind();
programObject_->setUniform("texture1", 0);
+4 -6
View File
@@ -3,11 +3,11 @@
// open space includes
#include "renderable.h"
#include "util/planet.h"
#include <util/powerscaledsphere.h>
// ghoul includes
#include "ghoul/opengl/programobject.h"
#include "ghoul/opengl/texture.h"
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
namespace openspace {
@@ -30,9 +30,7 @@ public:
private:
ghoul::opengl::ProgramObject *programObject_;
ghoul::opengl::Texture *texture_;
// double rad_;
Planet *planet_;
PowerScaledSphere *planet_;
};
} // namespace openspace
+79 -153
View File
@@ -26,7 +26,6 @@
#include "openspaceengine.h"
#include "scenegraph/scenegraph.h"
#include "scenegraph/scenegraphloader.h"
#include "util/camera.h"
#include "sgct.h"
@@ -44,64 +43,58 @@ RenderEngine::~RenderEngine() {
}
bool RenderEngine::initialize() {
// init camera and set position
// init camera and set temporary position and scaling
_mainCamera = new Camera();
_mainCamera->setScaling(glm::vec2(1.0, -8.0));
_mainCamera->setPosition(psc(0.0,0.0,1.499823,11.0)); // about the distance from the sun to our moon, will be overritten by the scenegraphloader
_mainCamera->setPosition(psc(0.0,0.0,1.499823,11.0));
// if master, setup interaction
if (sgct::Engine::instance()->isMaster()) {
OsEng.interactionHandler().setCamera(_mainCamera);
// init interactionhandler and mouse interaction
//keyboardControl_ = new KeyboardExternalControl(RELATIVE_PATH"pyinput/keyboard.py");
//mouseControl_ = new MouseExternalControl(RELATIVE_PATH"pyinput/mouse.py");
//InteractionHandler::ref().addExternalControl(mouseControl_); // the interactionhandler is deallocating the object when it terminates
//InteractionHandler::ref().addExternalControl(keyboardControl_); // the interactionhandler is deallocating the object when it terminates
}
// init scenegraph
// initialize scenegraph
_sceneGraph = new SceneGraph;
_sceneGraph->initialize();
//_sceneGraph = loadSceneGraph(sceneGraph);
return true;
}
bool RenderEngine::initializeGL() {
// GL settings
glEnable (GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
// set the close clip plane and the far clip plane to extreme values while in development
sgct::Engine::instance()->setNearAndFarClippingPlanes(0.1f,100.0f);
//sgct::Engine::setNearAndFarClippingPlanes(0.1f,10000.0f);
//sgct::Engine::getPtr()->setNearAndFarClippingPlanes(0.1f,10000.0f);
// calculating the maximum field of view for the camera, used to determine visibility of objects in the scene graph
if(sgct::Engine::instance()->getWindowPtr(0)->isUsingFisheyeRendering()) {
#define SGCT_WPTR sgct::Engine::instance()->getWindowPtr(0)
using sgct_core::Viewport;
// TODO: Fix the power scaled coordinates in such a way that these values can be set
// to more realistic values
// set the close clip plane and the far clip plane to extreme values while in development
//sgct::Engine::instance()->setNearAndFarClippingPlanes(0.1f,100.0f);
sgct::Engine::instance()->setNearAndFarClippingPlanes(0.00001f,100.0f);
// calculating the maximum field of view for the camera, used to
// determine visibility of objects in the scene graph
if(SGCT_WPTR->isUsingFisheyeRendering()) {
// fisheye mode, looking upwards to the "dome"
glm::vec4 viewdir(0,1,0,0);
// get the tilt and rotate the view
float tilt = sgct::Engine::instance()->getWindowPtr(0)->getFisheyeTilt();
float tilt = SGCT_WPTR->getFisheyeTilt();
//tilt = tilt * 0.0174532925; // degrees to radians
glm::mat4 tiltMatrix = glm::rotate(glm::mat4(1.0f), tilt, glm::vec3(1.0f,0.0f,0.0f));
viewdir = tiltMatrix * viewdir;
// set the tilted view and the FOV
_mainCamera->setCameraDirection(glm::vec3(viewdir[0],viewdir[1],viewdir[2]));
//mainCamera_->setMaxFov(sgct_core::SGCTSettings::Instance()->getFisheyeFOV());
_mainCamera->setMaxFov(sgct::Engine::instance()->getWindowPtr(0)->getFisheyeFOV());
_mainCamera->setMaxFov(SGCT_WPTR->getFisheyeFOV());
} else {
// get corner positions, calculating the forth to easily calculate center
// get corner positions, calculating the forth to easily calculate center
glm::vec3 corners[4];
corners[0] = sgct::Engine::instance()->getWindowPtr(0)->getCurrentViewport()->getViewPlaneCoords(sgct_core::Viewport::LowerLeft);
corners[1] = sgct::Engine::instance()->getWindowPtr(0)->getCurrentViewport()->getViewPlaneCoords(sgct_core::Viewport::UpperLeft);
corners[2] = sgct::Engine::instance()->getWindowPtr(0)->getCurrentViewport()->getViewPlaneCoords(sgct_core::Viewport::UpperRight);
corners[0] = SGCT_WPTR->getCurrentViewport()->getViewPlaneCoords(Viewport::LowerLeft);
corners[1] = SGCT_WPTR->getCurrentViewport()->getViewPlaneCoords(Viewport::UpperLeft);
corners[2] = SGCT_WPTR->getCurrentViewport()->getViewPlaneCoords(Viewport::UpperRight);
corners[3] = glm::vec3(corners[2][0],corners[0][1],corners[2][2]);
glm::vec3 center = (corners[0] + corners[1] + corners[2] + corners[3]) / 4.0f;
@@ -129,7 +122,7 @@ bool RenderEngine::initializeGL() {
}
_mainCamera->setMaxFov(maxFov);
}
// successful init
return true;
}
@@ -140,52 +133,73 @@ void RenderEngine::postSynchronizationPreDraw() {
_mainCamera->compileViewRotationMatrix();
// update and evaluate the scene starting from the root node
//_sceneGraph->update();
//_sceneGraph->evaluate(_mainCamera);
_sceneGraph->update();
_mainCamera->setCameraDirection(glm::vec3(0,0,-1));
_sceneGraph->evaluate(_mainCamera);
}
void RenderEngine::render() {
// preparing the camera can only be done in the render function
// since the SGCT get matrix functions is only valid in the render function
glm::mat4 projection = sgct::Engine::instance()->getActiveProjectionMatrix();
glm::mat4 view = sgct::Engine::instance()->getActiveViewMatrix();
const glm::vec3 eyePosition = sgct_core::ClusterManager::instance()->getUserPtr()->getPos();
view = glm::translate(view, eyePosition); // make sure the eye is in the center
// SGCT resets certian settings
glEnable (GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
// setup the camera for the current frame
//_mainCamera->setViewProjectionMatrix(projection*view);
const glm::vec3 eyePosition = sgct_core::ClusterManager::instance()->getUserPtr()->getPos();
glm::mat4 view = glm::translate(glm::mat4(1.0), eyePosition); // make sure the eye is in the center
_mainCamera->setViewProjectionMatrix(sgct::Engine::instance()->getActiveModelViewProjectionMatrix()*view);
// render the scene starting from the root node
//_sceneGraph->render(_mainCamera);
/*
_sceneGraph->render(_mainCamera);
// Print some useful information on the master viewport
if (sgct::Engine::instance()->isMaster()) {
// Apple usually has retina screens
#ifdef __APPLE__
#define FONT_SIZE 18
#else
#define FONT_SIZE 10
#endif
const glm::vec2 scaling = _mainCamera->getScaling();
const glm::vec3 viewdirection = _mainCamera->getViewDirection();
const psc position = _mainCamera->getPosition();
Freetype::print(sgct_text::FontManager::instance()->getFont( "SGCTFont", 10 ), 10, 50,
"Position: (%.5f, %.5f, %.5f, %.5f)", position[0], position[1], position[2], position[3]
);
Freetype::print(sgct_text::FontManager::instance()->getFont( "SGCTFont", 10 ), 10, 35,
"View direction: (%.3f, %.3f, %.3f)", viewdirection[0], viewdirection[1], viewdirection[2]
);
Freetype::print(sgct_text::FontManager::instance()->getFont( "SGCTFont", 10 ), 10, 20,
"Scaling: (%.10f, %.2f)", scaling[0], scaling[1]
);
const psc origin = OsEng.interactionHandler().getOrigin();
const pss pssl = (position - origin).length();
Freetype::print(sgct_text::FontManager::instance()->getFont( "SGCTFont", FONT_SIZE ),
FONT_SIZE,
FONT_SIZE*10,
"Origin: (%.5f, %.5f, %.5f, %.5f)",
origin[0], origin[1], origin[2], origin[3]
);
Freetype::print(sgct_text::FontManager::instance()->getFont( "SGCTFont", FONT_SIZE ),
FONT_SIZE,
FONT_SIZE*8,
"Camera position: (%.5f, %.5f, %.5f, %.5f)",
position[0], position[1], position[2], position[3]
);
Freetype::print(sgct_text::FontManager::instance()->getFont( "SGCTFont", FONT_SIZE ),
FONT_SIZE,
FONT_SIZE*6,
"Distance to origin: (%.15f, %.2f)",
pssl[0], pssl[1]
);
Freetype::print(sgct_text::FontManager::instance()->getFont( "SGCTFont", FONT_SIZE ),
FONT_SIZE,
FONT_SIZE*4,
"View direction: (%.3f, %.3f, %.3f)",
viewdirection[0], viewdirection[1], viewdirection[2]
);
Freetype::print(sgct_text::FontManager::instance()->getFont( "SGCTFont", FONT_SIZE ),
FONT_SIZE,
FONT_SIZE*2,
"Scaling: (%.10f, %.2f)",
scaling[0], scaling[1]
);
psc campos = _mainCamera->getPosition();
psc origin = OsEng.interactionHandler().getOrigin();
//psc campos = InteractionHandler::ref().getCamera()->getPosition();
//psc origin = InteractionHandler::ref().getOrigin();
psc relative = campos - origin;
pss pssl = relative.length();
//mainCamera_->setScaling(glm::vec2(pssl[0], -pssl[1]+6));
//mainCamera_->setScaling(glm::vec2(3000.0, -11.0f));
Freetype::print(sgct_text::FontManager::instance()->getFont( "SGCTFont", 10 ), 10, 65,
"Distance to origin: (%.15f, %.2f)", pssl[0], pssl[1]
);
}
*/
}
SceneGraph* RenderEngine::sceneGraph() {
@@ -195,92 +209,4 @@ SceneGraph* RenderEngine::sceneGraph() {
}
/*
void RenderEngine::keyboardCallback(int key, int action) {
const double speed = 0.75;
if (key == 'S') {
double dt = InteractionHandler::ref().getDt();
glm::vec3 euler(speed * dt, 0.0, 0.0);
glm::quat rot = glm::quat(euler);
InteractionHandler::ref().orbit(rot);
}
if (key == 'W') {
double dt = InteractionHandler::ref().getDt();
glm::vec3 euler(-speed * dt, 0.0, 0.0);
glm::quat rot = glm::quat(euler);
InteractionHandler::ref().orbit(rot);
}
if (key == 'A') {
double dt = InteractionHandler::ref().getDt();
glm::vec3 euler(0.0, -speed * dt, 0.0);
glm::quat rot = glm::quat(euler);
InteractionHandler::ref().orbit(rot);
}
if (key == 'D') {
double dt = InteractionHandler::ref().getDt();
glm::vec3 euler(0.0, speed * dt, 0.0);
glm::quat rot = glm::quat(euler);
InteractionHandler::ref().orbit(rot);
}
if (key == 262) {
double dt = InteractionHandler::ref().getDt();
glm::vec3 euler(0.0, speed * dt, 0.0);
glm::quat rot = glm::quat(euler);
InteractionHandler::ref().rotate(rot);
}
if (key == 263) {
double dt = InteractionHandler::ref().getDt();
glm::vec3 euler(0.0, -speed * dt, 0.0);
glm::quat rot = glm::quat(euler);
InteractionHandler::ref().rotate(rot);
}
if (key == 264) {
double dt = InteractionHandler::ref().getDt();
glm::vec3 euler(speed * dt, 0.0, 0.0);
glm::quat rot = glm::quat(euler);
InteractionHandler::ref().rotate(rot);
}
if (key == 265) {
double dt = InteractionHandler::ref().getDt();
glm::vec3 euler(-speed * dt, 0.0, 0.0);
glm::quat rot = glm::quat(euler);
InteractionHandler::ref().rotate(rot);
}
if (key == 'R') {
double dt = InteractionHandler::ref().getDt();
pss dist(3 * -speed * dt, 8.0);
InteractionHandler::ref().distance(dist);
}
if (key == 'F') {
double dt = InteractionHandler::ref().getDt();
pss dist(3 * speed * dt, 8.0);
InteractionHandler::ref().distance(dist);
}
if (key == '1') {
SceneGraphNode* earth = sceneGraph_->root()->get("sun");
InteractionHandler::ref().setFocusNode(earth);
InteractionHandler::ref().getCamera()->setPosition(earth->getWorldPosition() + psc(0.0, 0.0, 0.5, 10.0));
InteractionHandler::ref().getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0));
}
if (key == '2') {
SceneGraphNode* earth = sceneGraph_->root()->get("earth");
InteractionHandler::ref().setFocusNode(earth);
InteractionHandler::ref().getCamera()->setPosition(earth->getWorldPosition() + psc(0.0, 0.0, 1.0, 8.0));
InteractionHandler::ref().getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0));
}
if (key == '3') {
SceneGraphNode* earth = sceneGraph_->root()->get("moon");
InteractionHandler::ref().setFocusNode(earth);
InteractionHandler::ref().getCamera()->setPosition(earth->getWorldPosition() + psc(0.0, 0.0, 0.5, 8.0));
InteractionHandler::ref().getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0));
}
}
*/
} // namespace openspace
+20 -7
View File
@@ -31,16 +31,29 @@ ConstantPositionInformation::ConstantPositionInformation() {}
ConstantPositionInformation::~ConstantPositionInformation() {}
bool ConstantPositionInformation::initializeWithDictionary(ghoul::Dictionary* dictionary) {
return true;
if ( dictionary == nullptr) {
_position = psc(0.0,0.0,0.0,0.0);
return true;
}
if (dictionary->hasKey("Position.1")) {
double x, y, z, e;
if (dictionary->getValue("Position.1", x) && dictionary->getValue("Position.2", y) &&
dictionary->getValue("Position.3", z) && dictionary->getValue("Position.4", e)) {
_position = psc(x, y, z, e);
return true;
}
}
return false;
}
const psc& ConstantPositionInformation::position() const {
return psc();
const psc& ConstantPositionInformation::position() const {
return _position;
}
void ConstantPositionInformation::update() {
}
}
} // namespace openspace
@@ -38,6 +38,7 @@ public:
virtual void update();
protected:
private:
psc _position;
};
+70 -25
View File
@@ -24,10 +24,10 @@
// open space includes
#include "scenegraph/scenegraph.h"
#include "scenegraph/scenegraphloader.h"
#include "rendering/renderableplanet.h"
#include "interaction/interactionhandler.h"
#include "util/spice.h"
#include <openspaceengine.h>
// ghoul includes
#include "ghoul/opengl/programobject.h"
@@ -40,6 +40,7 @@
#include <ghoul/misc/dictionary.h>
#include <ghoul/lua/ghoul_lua.h>
#include <ghoul/lua/lua_helper.h>
#include <ghoul/opengl/shadermanager.h>
#include <iostream>
#include <string>
@@ -60,31 +61,26 @@ SceneGraph::~SceneGraph() {
// no need to remove from _nodes and _allNodes.
if(_root)
delete _root;
// deallocate shaders, iterate c++11 style
for (auto& shaderTuple: _shaders) {
// the shader is in the maps second position
delete shaderTuple.second;
}
}
void SceneGraph::initialize() {
// logger string
std::string _loggerCat = "SceneGraph::init";
// The ${SCENEPATH} variable needs to be set and the scene definition needs to exist
assert(FileSys.fileExists("${SCENEPATH}/default.scene"));
// load the scene
loadFromModulePath();
// SceneGraphLoader *loader = new SceneGraphLoader(&nodes_, &shaders_);
// root_ = loader->loadSceneGraph(absPath("${BASE_PATH}/modules"));
update();
//pss bs = root_->calculateBoundingSphere();
// Calculate the bounding sphere for the scenegraph
_root->calculateBoundingSphere();
}
void SceneGraph::update() {
for(auto node: _nodes) {
//node->update();
node->update();
}
}
@@ -107,26 +103,67 @@ void SceneGraph::loadFromModulePath() {
}
luaL_openlibs(state);
// initialize the root node
_root = new SceneGraphNode;
_root->initialize();
_root->setName("Root");
_nodes.push_back(_root);
_allNodes.insert ( std::make_pair("Root", _root));
ghoul::lua::lua_loadIntoDictionary(state, &dictionary, absPath("${SCENEPATH}/default.scene"));
ghoul::Dictionary* tmpDictionary;
if(dictionary.getValue("modules", tmpDictionary)) {
auto keys = tmpDictionary->keys();
ghoul::Dictionary moduleDictionary;
if(dictionary.getValue("Modules", moduleDictionary)) {
auto keys = moduleDictionary.keys();
std::sort(keys.begin(), keys.end());
for (auto key: keys) {
std::string moduleFolder;
if(tmpDictionary->getValue(key, moduleFolder)) {
if(moduleDictionary.getValue(key, moduleFolder)) {
loadModulesFromModulePath(absPath("${SCENEPATH}/"+moduleFolder));
}
}
}
// update relative positions for all loaded objects. Necessary for Spice position modules
update();
// TODO: Make it less hard-coded and more flexible when nodes are not found
ghoul::Dictionary cameraDictionary;
if(dictionary.getValue("Camera", cameraDictionary)) {
LDEBUG("Cameradictionary found");
std::string focus;
std::string position;
if (cameraDictionary.getValue("Focus", focus) &&
cameraDictionary.getValue("Position", position)) {
LDEBUG("focus & position found " << focus << " " << position);
auto focusIterator = _allNodes.find(focus);
auto positionIterator = _allNodes.find(position);
if(focusIterator != _allNodes.end() && positionIterator != _allNodes.end()) {
LDEBUG("Setting position and focus from config");
SceneGraphNode* focusNode = focusIterator->second;
SceneGraphNode* positionNode = positionIterator->second;
Camera* c = OsEng.interactionHandler().getCamera();
// TODO: Make distance depend on radius
// TODO: Set distance and camera direction in some more smart way
// TODO: Set scaling dependent on the position and distance
// set position for camera
psc cameraPosition = positionNode->getPosition();
cameraPosition += psc(0.0,0.0,1.0,2.0);
c->setPosition(cameraPosition);
c->setCameraDirection(glm::vec3(0,0,-1));
c->setScaling(glm::vec2(1.0,0.0));
// Set the focus node for the interactionhandler
OsEng.interactionHandler().setFocusNode(focusNode);
}
}
}
// Close the Lua state
lua_close(state);
}
@@ -152,13 +189,13 @@ void SceneGraph::loadModulesFromModulePath(const std::string& modulePath) {
ghoul::lua::lua_loadIntoDictionary(state, &moduleDictionary, fullModule);
auto keys = moduleDictionary.keys();
for (auto key: keys) {
ghoul::Dictionary* singleModuleDictionary;
ghoul::Dictionary singleModuleDictionary;
if(moduleDictionary.getValue(key, singleModuleDictionary)) {
std::string moduleName;
if (singleModuleDictionary->getValue("Name", moduleName)) {
if (singleModuleDictionary.getValue("Name", moduleName)) {
std::string parentName;
if ( ! singleModuleDictionary->getValue("Parent", parentName)) {
LDEBUG("Could not find 'Parent' key, using 'Root'.");
if ( ! singleModuleDictionary.getValue("Parent", parentName)) {
LWARNING("Could not find 'Parent' key, using 'Root'.");
parentName = "Root";
}
@@ -172,8 +209,8 @@ void SceneGraph::loadModulesFromModulePath(const std::string& modulePath) {
// allocate SceneGraphNode and initialize with Dictionary
SceneGraphNode* node = new SceneGraphNode;
singleModuleDictionary->setValue("Path", modulePath);
if(node->initializeWithDictionary(singleModuleDictionary)) {
singleModuleDictionary.setValue("Path", modulePath);
if(node->initializeWithDictionary(&singleModuleDictionary)) {
// add to internal data structures
_allNodes.insert(std::make_pair(moduleName, node));
_nodes.push_back(node);
@@ -192,5 +229,13 @@ void SceneGraph::loadModulesFromModulePath(const std::string& modulePath) {
// Close the Lua state
lua_close(state);
}
void SceneGraph::printChildren() const {
_root->print();
}
SceneGraphNode* SceneGraph::root() const {
return _root;
}
} // namespace openspace
+22 -6
View File
@@ -45,18 +45,35 @@ public:
SceneGraph();
~SceneGraph();
/*
* Initalizes the SceneGraph by loading modules from the ${SCENEPATH} directory
*/
void initialize();
/*
* Updates all SceneGraphNodes relative positions
*/
void update();
/*
* Evaluates if the SceneGraphNodes are visible to the provided camera
*/
void evaluate(Camera *camera);
/*
* Render visible SceneGraphNodes using the provided camera
*/
void render(Camera *camera);
void printChildren() const {
_root->print();
}
/*
* Prints the SceneGraph tree. For debugging purposes
*/
void printChildren() const;
SceneGraphNode* root() const { return _root; }
void setRoot(SceneGraphNode* root) { _root = root; }
/*
* Returns the root SceneGraphNode
*/
SceneGraphNode* root() const;
private:
@@ -67,7 +84,6 @@ private:
SceneGraphNode *_root;
std::vector<SceneGraphNode*> _nodes;
std::map<std::string, SceneGraphNode*> _allNodes;
std::map<std::string, ghoul::opengl::ProgramObject*> _shaders;
};
-439
View File
@@ -1,439 +0,0 @@
#include "openspaceengine.h"
// open space includes
#include "scenegraph/scenegraphloader.h"
#include "rendering/renderablebody.h"
#include "rendering/renderableplanet.h"
#include "interaction/interactionhandler.h"
#include "util/spice.h"
// ghoul includes
#include "ghoul/logging/logmanager.h"
#include "ghoul/logging/consolelog.h"
#include "ghoul/opengl/texturereader.h"
#include "ghoul/opengl/texture.h"
// std includes
#include <utility>
namespace openspace {
/*
SceneGraph* loadSceneGraph(const std::string& sceneGraphPath) {
SceneGraph* result = new SceneGraph;
//result->setRo
return result;
}
SceneGraphLoader::SceneGraphLoader(std::vector<SceneGraphNode*> *nodes, std::map<std::string, ghoul::opengl::ProgramObject*> *commonShaders) {
root_ = nullptr;
nodes_ = nodes;
commonShaders_ = commonShaders;
}
SceneGraphLoader::~SceneGraphLoader() {
}
SceneGraphNode* SceneGraphLoader::loadSceneGraph(const std::string &path) {
assert(commonShaders_);
std::string _loggerCat = "SceneGraphLoader::loadSceneGraph";
// initializes the scene graph
root_ = new SceneGraphNode();
// loading all common stuff
tinyxml2::XMLDocument commonXML;
std::string commonPath = path + "/common/common.xml";
commonXML.LoadFile(commonPath.c_str());
// loading the shaders
tinyxml2::XMLElement* shaders = commonXML.FirstChildElement( "shaders" );
if(shaders) {
tinyxml2::XMLElement* shader = shaders->FirstChildElement( "shader" );
for(;shader; shader = shader->NextSiblingElement( "shader" )) {
if(shader->Attribute("identifier")) {
std::string identifier = shader->Attribute("identifier");
ghoul::opengl::ProgramObject *programObject = nullptr;
if(getShader(&programObject,path + "/common/", shader ))
commonShaders_->insert( std::make_pair(identifier, programObject) );
}
}
}
tinyxml2::XMLDocument scenegraphXML;
std::string scenegraphPath = path + "/scenegraph.xml";
scenegraphXML.LoadFile(scenegraphPath.c_str());
// loading the scenegraph
tinyxml2::XMLElement* root = scenegraphXML.FirstChildElement( "root" );
if(root) {
tinyxml2::XMLElement* node = root->FirstChildElement( "node" );
loadSceneGraphTree(node, root_, path);
}
return root_;
}
// ugly
void SceneGraphLoader::loadSceneGraphTree(tinyxml2::XMLElement* node, SceneGraphNode *current, const std::string &path) {
// ghoul logger
std::string _loggerCat = "SceneGraphLoader::loadSceneGraphTree";
for(;node; node = node->NextSiblingElement( "node" )) {
SceneGraphNode *thisNode = nullptr;
std::string name = "";
if(node->Attribute("module")) {
name = node->Attribute("module");
thisNode = loadSceneGraphNodeFromFile(name, current, path);
} else {
thisNode = loadSceneGraphNode(node, "", current, path);
}
if(thisNode) {
tinyxml2::XMLElement* children = node->FirstChildElement( "node" );
if(children) {
loadSceneGraphTree(children, thisNode, path);
}
nodes_->push_back(thisNode);
// camera stuff
tinyxml2::XMLElement* camera = node->FirstChildElement( "camera" );
if(camera && camera->Attribute("setting")) {
std::string setting = camera->Attribute("setting");
if(setting == "focus") {
// HACK
OsEng.interactionHandler().setFocusNode(thisNode->parent());
LINFO("Setting camera focus: " << name);
} else if(setting == "position") {
OsEng.interactionHandler().getCamera()->setPosition(thisNode->getWorldPosition());
LINFO("Setting camera position: " << name);
}
}
} else {
LERROR("Could not load SceneGraphNode [ " << name << " ], ignoring all children!");
}
}
}
SceneGraphNode * SceneGraphLoader::loadSceneGraphNodeFromFile(std::string name, SceneGraphNode *parent, const std::string &path) {
std::string _loggerCat = "SceneGraphLoader::loadSceneGraphNode";
// path and name
std::string nodePath = path + "/" + name + "/" + name + ".xml";
tinyxml2::XMLDocument nodeXML;
nodeXML.LoadFile(nodePath.c_str());
return loadSceneGraphNode(nodeXML.FirstChildElement( "module" ), name, parent, path + "/" + name);
}
SceneGraphNode * SceneGraphLoader::loadSceneGraphNode(tinyxml2::XMLElement *xmlnode, std::string name, SceneGraphNode *parent, const std::string &path) {
assert(commonShaders_);
std::string _loggerCat = "SceneGraphLoader::loadSceneGraphNode";
// the node
SceneGraphNode *thisNode = nullptr;
// load the properties
tinyxml2::XMLElement* moduleElement = xmlnode;
if(moduleElement) {
thisNode = new SceneGraphNode();
// load spice
getSpice(thisNode, parent, moduleElement->FirstChildElement( "spice" ));
tinyxml2::XMLElement* renderableElement = moduleElement->FirstChildElement( "renderable" );
if(renderableElement && renderableElement->Attribute("type")) {
std::string type = renderableElement->Attribute("type");
if(type == "RenderableBody") {
RenderableBody *renderable = nullptr;
// load radius
pss radius;
// the radii element takes priority when setting the radius
if( getRadii(&radius, renderableElement->FirstChildElement( "radii" )) || thisNode->getSpiceID() > 0) {
double radii[3];
int n;
if(Spice::ref().getRadii(thisNode->getSpiceName(),radii,&n)) {
// multiply with factor 1000, spice uses km as standard and Open Space uses m
radius = pss::CreatePSS(radii[0]*1000.0);
} else {
LERROR("Tried to use spice raddi but failed for: " << name);
delete thisNode;
return nullptr;
}
} else {
LERROR("Could not find radiiElement or spice id for: " << name << " " << thisNode->getSpiceID() );
delete thisNode;
return nullptr;
}
LINFO("Adding renderable: "<< name);
// load texture and shader
ghoul::opengl::Texture *texture = nullptr;
ghoul::opengl::ProgramObject *program = nullptr;
tinyxml2::XMLElement* textureElement = renderableElement->FirstChildElement( "texture" );
if(textureElement) {
if( ! getTexture(&texture, path, textureElement->FirstChildElement( "file" ))) {
LERROR("Could not load texture " << name);
}
} else {
LERROR("Could not find texture for: " << name);
}
// load shader
if( ! getShader(&program, path, renderableElement->FirstChildElement( "shader" ))) {
LERROR("Could not find shader for: " << name);
}
if( ! texture || ! program) {
delete thisNode;
return nullptr;
}
// create the renderable
renderable = new RenderableBody(radius);
renderable->setTexture(texture);
renderable->setProgramObject(program);
thisNode->setRenderable(renderable);
} else if(type == "RenderablePlanet") {
RenderablePlanet *renderable = nullptr;
// load radius
pss radius;
// the radii element takes priority when setting the radius
if( getRadii(&radius, renderableElement->FirstChildElement( "radii" )) || thisNode->getSpiceID() > 0) {
double radii[3];
int n;
if(Spice::ref().getRadii(thisNode->getSpiceName(),radii,&n)) {
// multiply with factor 1000, spice uses km as standard and Open Space uses m
radius = pss::CreatePSS(radii[0]*1000.0);
} else {
LERROR("Tried to use spice raddi but failed for: " << name);
delete thisNode;
return nullptr;
}
} else {
LERROR("Could not find radiiElement or spice id for: " << name << " " << thisNode->getSpiceID() );
delete thisNode;
return nullptr;
}
LINFO("Adding renderable: "<< name);
// load texture and shader
ghoul::opengl::Texture *texture = nullptr;
ghoul::opengl::ProgramObject *program = nullptr;
tinyxml2::XMLElement* textureElement = renderableElement->FirstChildElement( "texture" );
if(textureElement) {
if( ! getTexture(&texture, path, textureElement->FirstChildElement( "file" ))) {
LERROR("Could not load texture " << name);
}
} else {
LERROR("Could not find texture for: " << name);
}
// load shader
if( ! getShader(&program, path, renderableElement->FirstChildElement( "shader" ))) {
LERROR("Could not find shader for: " << name);
}
if( ! texture || ! program) {
delete thisNode;
return nullptr;
}
// create the renderable
renderable = new RenderablePlanet(radius);
renderable->setTexture(texture);
renderable->setProgramObject(program);
thisNode->setRenderable(renderable);
LINFO("Adding renderablePlanet");
}
}
// set identifier and add to parent
thisNode->setName(name);
parent->addNode(thisNode);
return thisNode;
} else {
LERROR("Unable to open properties element");
return nullptr;
}
}
bool SceneGraphLoader::getSpice(SceneGraphNode *node, SceneGraphNode *parent, tinyxml2::XMLElement *xmlnode) {
std::string _loggerCat = "SceneGraphLoader::getSpice";
if(xmlnode && node) {
tinyxml2::XMLElement* identifierElement = xmlnode->FirstChildElement( "identifier" );
if(identifierElement && identifierElement->Attribute("string")) {
std::string identifier = identifierElement->Attribute("string");
int spiceID;
int spiceIDFound;
Spice::ref().bod_NameToInt(identifierElement->Attribute("string"), &spiceID, &spiceIDFound);
if(spiceIDFound) {
// The spice id exists, save the identifier
node->setSpiceName(identifier);
int parentSpice = 0; // sun barycenter
if(parent) {
if( parent->getSpiceID() != 0)
parentSpice = parent->getSpiceID();
}
node->setSpiceID(spiceID,parentSpice);
return true;
} else {
LERROR("Could not find spice ID ");
}
} else {
LERROR("Could not find spice identifier element in xml ");
}
}
return false;
}
bool SceneGraphLoader::getRadii(pss *radii, tinyxml2::XMLElement *xmlnode) {
std::string _loggerCat = "SceneGraphLoader::getRadii";
if(xmlnode ) {
double value = 0.0;
double power = 0.0;
if(xmlnode->Attribute("value")) {
value = xmlnode->DoubleAttribute("value");
if(xmlnode->Attribute("power"))
power = xmlnode->DoubleAttribute("power");
*radii = pss(value, power);
return true;
}
}
return false;
}
bool SceneGraphLoader::getTexture(ghoul::opengl::Texture **texture, const std::string &path, tinyxml2::XMLElement *xmlnode) {
std::string _loggerCat = "SceneGraphLoader::getTexture";
if(xmlnode && xmlnode->Attribute("path")) {
std::string texturePath = path + "/" + xmlnode->Attribute("path");
*texture = ghoul::opengl::loadTexture(texturePath);
// if textures where accessed, upload them to the graphics card. This check needs to be done to avoid crash.
if(texture) {
LINFO("Uploading tetxure: "<< texturePath);
(*texture)->uploadTexture();
//ghoul::opengl::Texture *tmp = new ghoul::opengl::Texture(*texture);
//texture = tmp;
return true;
} else {
LERROR("Could not load texture: "<< texturePath);
}
} else {
LERROR("Could not find file element");
}
return false;
}
bool SceneGraphLoader::getShader(ghoul::opengl::ProgramObject **program, const std::string &path, tinyxml2::XMLElement *xmlnode) {
std::string _loggerCat = "SceneGraphLoader::getShader";
if( ! xmlnode)
return false;
// use a common shader
if(xmlnode->IntAttribute("common") && xmlnode->Attribute( "identifier" )) {
std::string identifier = xmlnode->Attribute( "identifier" );
std::map<std::string, ghoul::opengl::ProgramObject*>::iterator it;
it = commonShaders_->find(identifier);
if(it != commonShaders_->end()) {
*program = it->second;
return true;
}
LERROR("Could not find common shader: " << identifier);
return false;
// load and return the shader
} else {
tinyxml2::XMLElement* glsl_vs = xmlnode->FirstChildElement( "vertex" );
tinyxml2::XMLElement* glsl_fs = xmlnode->FirstChildElement( "fragment" );
if(glsl_vs && glsl_fs) {
if(glsl_vs->Attribute("path") && glsl_fs->Attribute("path")) {
std::string vs_path = glsl_vs->Attribute("path");
std::string fs_path = glsl_fs->Attribute("path");
vs_path = path + vs_path;
fs_path = path + fs_path;
ghoul::opengl::ProgramObject *programObject = new ghoul::opengl::ProgramObject();
ghoul::opengl::ShaderObject *vs = new ghoul::opengl::ShaderObject(ghoul::opengl::ShaderObject::ShaderType::ShaderTypeVertex, vs_path);
ghoul::opengl::ShaderObject *fs = new ghoul::opengl::ShaderObject(ghoul::opengl::ShaderObject::ShaderType::ShaderTypeFragment, fs_path);
programObject->attachObject(vs);
programObject->attachObject(fs);
// check for bindings
tinyxml2::XMLElement* bindings = xmlnode->FirstChildElement( "bindings" );
if(bindings) {
tinyxml2::XMLElement* attributes = bindings->FirstChildElement( "attribute" );
for(;attributes; attributes = attributes->NextSiblingElement( "attribute" )) {
if(attributes->Attribute("name") && attributes->Attribute("position")) {
std::string name = attributes->Attribute("name");
int position = attributes->IntAttribute("position");
programObject->bindAttributeLocation(name,position);
}
}
tinyxml2::XMLElement* fragdata = bindings->FirstChildElement( "fragdata" );
for(;fragdata; fragdata = fragdata->NextSiblingElement( "fragdata" )) {
if(fragdata->Attribute("name") && fragdata->Attribute("position")) {
std::string name = fragdata->Attribute("name");
int position = fragdata->IntAttribute("position");
programObject->bindFragDataLocation(name,position);
}
}
}
if(programObject->compileShaderObjects()) {
if(programObject->linkProgramObject()) {
*program = programObject;
LINFO("Common shader successfully loaded!");
return true;
} else {
LERROR("Common shader could not be linked!");
}
} else {
LERROR("Common shader could not be compiled!");
}
if(programObject)
delete programObject;
return false;
}
}
}
LERROR("Could not load shader");
return false;
}
*/
} // namespace openspace
-56
View File
@@ -1,56 +0,0 @@
#ifndef SCENEGRAPHLOADER_H
#define SCENEGRAPHLOADER_H
// open space includes
#include "scenegraph/scenegraphnode.h"
// std includes
#include <vector>
#include <string>
#include <map>
// ghoul includes
#include "ghoul/opengl/programobject.h"
#include "ghoul/opengl/texture.h"
// sgct includes
//#include "ext/tinyxml2.h"
namespace openspace {
/*
class SceneGraph;
SceneGraph* loadSceneGraph(const std::string& sceneGraphPath);
class SceneGraphLoader {
public:
// constructors & destructor
SceneGraphLoader(std::vector<SceneGraphNode*> *nodes, std::map<std::string, ghoul::opengl::ProgramObject*> *commonShaders);
~SceneGraphLoader();
SceneGraphNode *loadSceneGraph(const std::string &path);
private:
SceneGraphNode *root_;
std::map<std::string, ghoul::opengl::ProgramObject*> *commonShaders_;
std::vector<SceneGraphNode*> *nodes_;
// private methods
void loadSceneGraphTree(tinyxml2::XMLElement* node, SceneGraphNode *current, const std::string &path);
SceneGraphNode * loadSceneGraphNodeFromFile(std::string name, SceneGraphNode *parent, const std::string &path);
SceneGraphNode * loadSceneGraphNode(tinyxml2::XMLElement *xmlnode, std::string name, SceneGraphNode *parent, const std::string &path);
bool getSpice(SceneGraphNode *node,SceneGraphNode *parent, tinyxml2::XMLElement *xmlnode);
bool getRadii(pss *radii, tinyxml2::XMLElement *xmlnode);
bool getTexture(ghoul::opengl::Texture **texture, const std::string &path, tinyxml2::XMLElement *xmlnode);
bool getShader(ghoul::opengl::ProgramObject **program, const std::string &path, tinyxml2::XMLElement *xmlnode);
};
*/
} // namespace openspace
#endif
+69 -70
View File
@@ -29,8 +29,13 @@
// ghoul includes
#include <ghoul/logging/logmanager.h>
#include <ghoul/logging/consolelog.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/opengl/shadermanager.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/shaderobject.h>
#include <util/factorymanager.h>
#include <scenegraph/constantpositioninformation.h>
#include <openspaceengine.h>
namespace {
std::string _loggerCat = "SceneGraphNode";
@@ -54,40 +59,49 @@ SceneGraphNode::~SceneGraphNode() {
delete child;
}
bool SceneGraphNode::initialize() {
bool SceneGraphNode::_initialize() {
using ghoul::opengl::ShaderObject;
using ghoul::opengl::ProgramObject;
using ghoul::opengl::ShaderManager;
ShaderObject* powerscale_vs = new ShaderObject(ShaderObject::ShaderType::ShaderTypeVertex,
absPath("${SHADERS}/pscstandard_vs.glsl"),
"PS Vertex"
);
ShaderObject* powerscale_fs = new ShaderObject(ShaderObject::ShaderType::ShaderTypeFragment,
absPath("${SHADERS}/pscstandard_fs.glsl"),
"PS Fragment"
);
ProgramObject* po = new ProgramObject;
po->attachObject(powerscale_vs);
po->attachObject(powerscale_fs);
if( ! po->compileShaderObjects())
return false;
if( ! po->linkProgramObject())
return false;
OsEng.ref().configurationManager().setValue("pscShader", po);
return true;
}
template<class T>
bool safeInitializeWithDictionary(T** object, const std::string& key, ghoul::Dictionary* dictionary, const std::string& path = "") {
if(dictionary->hasKey(key)) {
ghoul::Dictionary* tmpDictionary;
if(dictionary->getValue(key, tmpDictionary)) {
std::string renderableType;
if(tmpDictionary->getValue("Type", renderableType)) {
ghoul::TemplateFactory<T>* factory = FactoryManager::ref().factoryByType<T>();
T* tmp = factory->create(renderableType);
if(tmp != nullptr) {
if ( ! tmpDictionary->hasKey("Path")) {
tmpDictionary->setValue("Path", path);
}
if(tmp->initializeWithDictionary(tmpDictionary)) {
*object = tmp;
return true;
} else {
delete tmp;
}
}
}
}
bool SceneGraphNode::initialize() {
if( ! _initialize()) {
return false;
}
return false;
_position = new ConstantPositionInformation;
_position->initializeWithDictionary(nullptr);
return true;
}
bool SceneGraphNode::initializeWithDictionary(ghoul::Dictionary* dictionary) {
if( ! initialize()) {
if( ! _initialize()) {
return false;
}
@@ -100,6 +114,9 @@ bool SceneGraphNode::initializeWithDictionary(ghoul::Dictionary* dictionary) {
if(dictionary->hasKey("Renderable")) {
if(safeInitializeWithDictionary<Renderable>(&_renderable, "Renderable", dictionary, path)) {
LDEBUG("Successful initialization of renderable!");
if ( ! _renderable) {
LFATAL("But the renderable is not initialized for " << _nodeName);
}
} else {
LDEBUG("Failed to initialize renderable!");
}
@@ -107,52 +124,39 @@ bool SceneGraphNode::initializeWithDictionary(ghoul::Dictionary* dictionary) {
if(dictionary->hasKey("Position")) {
if(safeInitializeWithDictionary<PositionInformation>(&_position, "Position", dictionary, path)) {
LDEBUG("Successful initialization of position!");
if ( ! _position) {
LFATAL("But the position is not initialized for " << _nodeName);
}
} else {
LDEBUG("Failed to initialize position!");
}
}
if (_position == nullptr) {
_position = new ConstantPositionInformation;
_position->initializeWithDictionary(nullptr);
}
return true;
}
// essential
void SceneGraphNode::update() {
/*
if(_spiceID > 0) {
double state[3];
//double orientation[3][3];
Spice::ref().spk_getPosition(_spiceID, _parentSpiceID, state);
// multiply with factor 1000, spice uses km as standard and Open Space uses m
_position = psc::CreatePSC(state[0]*1000.0,state[1]*1000.0,state[2]*1000.0);
// update rotation
//if(Spice::ref().spk_getOrientation(spiceName_,orientation)) {
// printf("%s\n",spiceName_);
// printf("%.5f %.5f %.5f \n", orientation[0][0], orientation[0][1], orientation[0][2]);
// printf("%.5f %.5f %.5f \n", orientation[1][0], orientation[1][1], orientation[1][2]);
// printf("%.5f %.5f %.5f \n", orientation[2][0], orientation[2][1], orientation[2][2]);
//}
}
if(_renderable) {
_renderable->update();
}
*/
_position->update();
}
void SceneGraphNode::evaluate(const Camera *camera, const psc & parentPosition) {
void SceneGraphNode::evaluate(const Camera *camera, const psc& parentPosition) {
const psc thisPosition = parentPosition + _position->position();
const psc camPos = camera->getPosition();
const psc toCamera = thisPosition - camPos;
// init as not visible
_boundingSphereVisible = true;
_boundingSphereVisible = false;
_renderableVisible = false;
// check if camera is outside the node boundingsphere
if(toCamera.length() > _boundingSphereVisible) {
if(toCamera.length() > _boundingSphere) {
// check if the boudningsphere is visible before avaluating children
if( ! sphereInsideFrustum(thisPosition, _boundingSphere, camera)) {
@@ -160,9 +164,11 @@ void SceneGraphNode::evaluate(const Camera *camera, const psc & parentPosition)
return;
}
}
}
// inside boudningsphere or parts of the sphere is visible, individual
// children needs to be evaluated
_boundingSphereVisible = true;
// inside boudningsphere or parts of the sphere is visible, individual children needs to be evaluated
// this node has an renderable
if(_renderable) {
@@ -173,9 +179,9 @@ void SceneGraphNode::evaluate(const Camera *camera, const psc & parentPosition)
// evaluate all the children, tail-recursive function(?)
for(auto &child: _children) {
child->evaluate(camera,thisPosition);
child->evaluate(camera,psc());
}
}
void SceneGraphNode::render(const Camera *camera, const psc & parentPosition) {
@@ -185,15 +191,14 @@ void SceneGraphNode::render(const Camera *camera, const psc & parentPosition) {
// check if camera is outside the node boundingsphere
if( ! _boundingSphereVisible) {
return;
}
}
if(_renderableVisible) {
if (_nodeName == "earth")
_nodeName = _nodeName;
_renderable->render(camera,thisPosition);
}
// evaluate all the children, tail-recursive function(?)
for(auto &child: _children) {
for(auto &child: _children) {
child->render(camera,thisPosition);
}
@@ -242,7 +247,8 @@ pss SceneGraphNode::calculateBoundingSphere() {
for(size_t i = 0; i < _children.size(); ++i) {
// when positions is dynamix, change this part to fins the most distant position
pss child = _children.at(i)->getPosition().length() + _children.at(i)->calculateBoundingSphere();
pss child = _children.at(i)->getPosition().length() +
_children.at(i)->calculateBoundingSphere();
if(child > maxChild) {
maxChild = child;
}
@@ -280,13 +286,6 @@ bool SceneGraphNode::sphereInsideFrustum(const psc s_pos, const pss & s_rad, con
// the vector to the object from the new position
psc D = s_pos - U;
// check if outside the maximum angle
if (_nodeName == "earth") {
//psc tmp = s_pos - camera->getPosition();
//LINFOC("", "Angle: " << psc_camdir.angle(D));
//LINFOC("", "Pos: " << tmp.getVec4f()[0] << " " << tmp.getVec4f()[1] << " " << tmp.getVec4f()[2] << " " << tmp.getVec4f()[3]);
}
const double a = psc_camdir.angle(D);
if ( a < camera->getMaxFov())
{
+5
View File
@@ -92,6 +92,9 @@ public:
private:
// private initialize helper
bool _initialize();
// essential
std::vector<SceneGraphNode*> _children;
SceneGraphNode* _parent;
@@ -112,4 +115,6 @@ private:
} // namespace openspace
#include <scenegraph/scenegraphnode.inl>
#endif
+61
View File
@@ -0,0 +1,61 @@
/*****************************************************************************************
* *
* 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. *
****************************************************************************************/
#ifndef SCENEGRAPHNODE_INL
#define SCENEGRAPHNODE_INL
#include <util/factorymanager.h>
namespace openspace {
template<class T>
bool safeInitializeWithDictionary(T** object, const std::string& key,
ghoul::Dictionary* dictionary, const std::string& path = "") {
if(dictionary->hasKey(key)) {
ghoul::Dictionary tmpDictionary;
if(dictionary->getValue(key, tmpDictionary)) {
std::string renderableType;
if(tmpDictionary.getValue("Type", renderableType)) {
ghoul::TemplateFactory<T>* factory = FactoryManager::ref().factoryByType<T>();
T* tmp = factory->create(renderableType);
if(tmp != nullptr) {
if ( ! tmpDictionary.hasKey("Path") && path != "") {
tmpDictionary.setValue("Path", path);
}
if(tmp->initializeWithDictionary(&tmpDictionary)) {
*object = tmp;
return true;
} else {
delete tmp;
}
}
}
}
}
return false;
}
} // namespace openspace
#endif
+21 -4
View File
@@ -24,22 +24,39 @@
#include "spicepositioninformation.h"
#include <util/spice.h>
namespace openspace {
SpicePositionInformation::SpicePositionInformation() {}
SpicePositionInformation::SpicePositionInformation(): _target(0), _origin(0), _position() {}
SpicePositionInformation::~SpicePositionInformation() {}
bool SpicePositionInformation::initializeWithDictionary(ghoul::Dictionary* dictionary) {
std::string body, observer;
if (dictionary->getValue("Body", body) && dictionary->getValue("Observer", observer)) {
int bsuccess = 0;
int osuccess = 0;
Spice::ref().bod_NameToInt(body, &_target, &bsuccess);
Spice::ref().bod_NameToInt(observer, &_origin, &osuccess);
if (bsuccess && osuccess) {
return true;
}
}
return true;
}
const psc& SpicePositionInformation::position() const {
return psc();
return _position;
}
void SpicePositionInformation::update() {
double state[3];
Spice::ref().spk_getPosition(_target, _origin, state);
_position = psc::CreatePSC(state[0], state[1], state[2]);
}
}
} // namespace openspace
@@ -27,6 +27,8 @@
#include "positioninformation.h"
#include <util/psc.h>
namespace openspace {
class SpicePositionInformation: public PositionInformation {
@@ -38,6 +40,9 @@ public:
virtual void update();
protected:
private:
int _target, _origin;
psc _position;
};
+1 -4
View File
@@ -8,11 +8,9 @@
namespace openspace {
Camera::Camera() {
//glm::vec3 EulerAngles(90, 45, 0);
scaling_ = glm::vec2(1.0,0.0);
glm::vec3 EulerAngles(0, 0, 0);
viewRotation_ = glm::quat(EulerAngles);
//printf("Camera: [%f, %f, %f, %f]\n", viewRotation_[0], viewRotation_[1], viewRotation_[2], viewRotation_[3]);
}
Camera::~Camera() {
@@ -20,7 +18,7 @@ Camera::~Camera() {
}
void Camera::setPosition(psc pos) {
position_ = pos;
position_ = pos;
}
const psc& Camera::getPosition() const {
@@ -72,7 +70,6 @@ const glm::vec3 & Camera::getViewDirection() const {
return viewDirection_;
}
const float & Camera::getMaxFov() const {
return maxFov_;
}
+9 -3
View File
@@ -50,9 +50,15 @@ void FactoryManager::initialize() {
_manager = new FactoryManager;
assert(_manager != nullptr);
_manager->factoryByType<Renderable>()->registerClass<RenderablePlanet>("RenderablePlanet");
_manager->factoryByType<PositionInformation>()->registerClass<ConstantPositionInformation>("Constant");
_manager->factoryByType<PositionInformation>()->registerClass<SpicePositionInformation>("Spice");
// Add Renderables
_manager->factoryByType<Renderable>()->
registerClass<RenderablePlanet>("RenderablePlanet");
// Add PositionInformations
_manager->factoryByType<PositionInformation>()->
registerClass<ConstantPositionInformation>("Static");
_manager->factoryByType<PositionInformation>()->
registerClass<SpicePositionInformation>("Spice");
}
void FactoryManager::deinitialize() {
-1
View File
@@ -44,7 +44,6 @@ public:
* assertion will be triggered.
*/
static void initialize();
static void deinitialize();
/**
+171
View File
@@ -0,0 +1,171 @@
/**
Copyright (C) 2012-2014 Jonas Strandstedt
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.
*/
// open space includes
#include <util/powerscaledsphere.h>
#include <ghoul/logging/logmanager.h>
namespace {
std::string _loggerCat = "PowerScaledSphere";
}
namespace openspace
{
PowerScaledSphere::PowerScaledSphere(const pss radius, int segments)
{
static_assert(sizeof(Vertex) == 64 , "The size of the Vertex needs to be 64 for performance");
_vBufferID = 0;
_iBufferID = 0;
_vaoID = 0;
_isize = 0;
_vsize = 0;
_varray = nullptr;
_iarray = nullptr;
_mode = GL_TRIANGLES;
// calculate and allocate memory for number of vertices and incicies
_vsize = (segments +1) * (segments + 1);
_isize = 6*segments*segments;
_varray = new Vertex[_vsize];
_iarray = new int[_isize];
// define PI
const float PI = 3.14159265f;
int nr = 0;
for (int i = 0; i <= segments; i++)
{
// define an extra vertex around the y-axis due to texture mapping
for (int j = 0; j <= segments; j++)
{
float fi = static_cast<float>(i);
float fj = static_cast<float>(j);
float fsegments = static_cast<float>(segments);
float r = static_cast<float>(radius[0]);
// inclenation angle (north to south)
float theta = fi*PI/fsegments; // 0 -> PI
// azimuth angle (east to west)
float phi = fj*PI*2.0f/fsegments; // 0 -> 2*PI
float x = r*sin(phi)*sin(theta); //
float y = r*cos(theta); // up
float z = r*cos(phi)*sin(theta); //
glm::vec3 normal = glm::vec3(x,y,z);
if (!(x == 0.f && y == 0.f && z == 0.f))
normal = glm::normalize(normal);
float t1 = fj/fsegments;
float t2 = fi/fsegments;
_varray[nr].location[0] = x;
_varray[nr].location[1] = y;
_varray[nr].location[2] = z;
_varray[nr].location[3] = static_cast<GLfloat>(radius[1]);
_varray[nr].normal[0] = normal[0];
_varray[nr].normal[1] = normal[1];
_varray[nr].normal[2] = normal[2];
_varray[nr].tex[0] = t1;
_varray[nr].tex[1] = t2;
//LDEBUG("T: (" << t1 << ", " << t2 << ")");
nr++;
}
}
nr = 0;
// define indicies for all triangles
for (int i = 1; i <= segments; ++i)
{
for (int j = 0; j < segments; ++j)
{
int t = segments+1;
_iarray[nr] = (t) * (i-1) + j + 0; nr++;
_iarray[nr] = (t) * (i+0) + j + 0; nr++;
_iarray[nr] = (t) * (i+0) + j + 1; nr++;
_iarray[nr] = (t) * (i-1) + j + 0; nr++;
_iarray[nr] = (t) * (i+0) + j + 1; nr++;
_iarray[nr] = (t) * (i-1) + j + 1; nr++;
}
}
// Initialize and upload to graphics card
GLuint errorID = glGetError();
glGenVertexArrays(1, &_vaoID);
// First VAO setup
glBindVertexArray(_vaoID);
glGenBuffers(1, &_vBufferID);
glBindBuffer(GL_ARRAY_BUFFER, _vBufferID);
glBufferData(GL_ARRAY_BUFFER, _vsize*sizeof(Vertex), _varray, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET( 0));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(16));
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(24));
glGenBuffers(1, &_iBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _isize*sizeof(int), _iarray, GL_STATIC_DRAW);
if(_vBufferID == 0)
{
LERROR("Vertex buffer not initialized");
}
if(_iBufferID == 0)
{
LERROR("Index buffer not initialized");
}
glBindVertexArray(0);
errorID = glGetError();
if(errorID != GL_NO_ERROR)
{
LERROR("OpenGL error: " << glewGetErrorString(errorID));
LERROR("Attempting to proceed anyway. Expect rendering errors or a crash.");
}
}
PowerScaledSphere::~PowerScaledSphere() {
if(_varray)
delete[] _varray;
if(_iarray)
delete[] _iarray;
}
void PowerScaledSphere::render() {
//LDEBUGC("gogo","power renders");
glBindVertexArray(_vaoID); // select first VAO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferID);
glDrawElements(_mode, _isize, GL_UNSIGNED_INT, BUFFER_OFFSET(0));
glBindVertexArray(0);
}
}
+56
View File
@@ -0,0 +1,56 @@
/**
Copyright (C) 2012-2014 Jonas Strandstedt
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.
*/
#ifndef __POWERSCALEDSPHERE_H__
#define __POWERSCALEDSPHERE_H__
// open space includes
#include <ghoul/opengl/ghoul_gl.h>
#include <util/psc.h>
#include <util/pss.h>
namespace openspace {
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
typedef struct
{
GLfloat location[4];
GLfloat tex[2];
GLfloat normal[3];
GLubyte padding[28]; // Pads the struct out to 64 bytes for performance increase
} Vertex;
class PowerScaledSphere
{
public:
//initializers
PowerScaledSphere(const pss radius, int segments = 8);
~PowerScaledSphere();
void render();
private:
GLuint _vaoID;
GLuint _vBufferID;
GLuint _iBufferID;
GLenum _mode;
unsigned int _isize;
unsigned int _vsize;
Vertex *_varray;
int *_iarray;
};
}
#endif
+1 -1
View File
@@ -52,7 +52,7 @@ void gl4::VBO::init()
// if arrays not set from sub-class initialize with a colored quad
if(_vsize == 0 || _isize == 0 || _varray == NULL || _iarray == NULL) {
//LOG("VBO: Init color quad\n");
LDEBUG("VBO: Init color quad");
_mode = GL_TRIANGLES;
_vsize = 4;