mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-03 17:30:04 -05:00
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:
+1
-1
Submodule ext/ghoul updated: 221555e074...8daa78d248
+1
-1
Submodule openspace-data updated: 833450690c...707eb16fa6
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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})
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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_;
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -44,7 +44,6 @@ public:
|
||||
* assertion will be triggered.
|
||||
*/
|
||||
static void initialize();
|
||||
|
||||
static void deinitialize();
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user