mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-03-07 12:58:33 -06:00
begin cleanup, making code more transparent
This commit is contained in:
@@ -61,13 +61,11 @@ public:
|
||||
|
||||
protected:
|
||||
void loadTexture();
|
||||
|
||||
GLuint genComputeProg();
|
||||
GLuint _computeShader;
|
||||
void updateTex();
|
||||
bool auxiliaryRendertarget();
|
||||
glm::mat4 computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up);
|
||||
|
||||
private:
|
||||
void imageProject();
|
||||
void imageProjectGPU();
|
||||
|
||||
properties::StringProperty _colorTexturePath;
|
||||
properties::StringProperty _projectionTexturePath;
|
||||
@@ -76,20 +74,31 @@ private:
|
||||
ghoul::opengl::ProgramObject* _programObject;
|
||||
ghoul::opengl::ProgramObject* _fboProgramObject;
|
||||
|
||||
|
||||
ghoul::opengl::Texture* _texture;
|
||||
ghoul::opengl::Texture* _textureProj;
|
||||
planetgeometryprojection::PlanetGeometryProjection* _geometry;
|
||||
|
||||
glm::vec2 _camScaling;
|
||||
glm::vec3 _lookUp;
|
||||
glm::mat4 _transform;
|
||||
glm::mat4 _projectorMatrix;
|
||||
|
||||
// spice
|
||||
std::string _instrumentID;
|
||||
std::string _projectorID;
|
||||
std::string _projecteeID;
|
||||
std::string _aberration;
|
||||
float _fovy;
|
||||
float _aspectRatio;
|
||||
float _nearPlane;
|
||||
float _farPlane;
|
||||
|
||||
glm::dmat3 _stateMatrix;
|
||||
glm::dmat3 _instrumentMatrix;
|
||||
glm::mat4 _projectorMatrix;
|
||||
glm::vec3 _boresight;
|
||||
glm::vec2 _camScaling;
|
||||
glm::mat4 _transform;
|
||||
|
||||
double _time;
|
||||
openspace::SceneGraphNode* _targetNode;
|
||||
double lightTime;
|
||||
|
||||
std::string _target;
|
||||
|
||||
@@ -98,7 +107,6 @@ private:
|
||||
GLuint _quad;
|
||||
GLuint _vertexPositionBuffer;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __RENDERABLEPLANETPROJECTION_H__
|
||||
Submodule openspace-data updated: 72a6a0857a...14fcea5a8d
@@ -28,6 +28,8 @@ uniform sampler2D texture1;
|
||||
uniform mat4 ProjectorMatrix;
|
||||
uniform mat4 ModelTransform;
|
||||
uniform vec2 _scaling;
|
||||
uniform vec2 radius;
|
||||
flat in uint vs_segments;
|
||||
|
||||
in vec4 vs_position;
|
||||
in vec3 vs_boresight;
|
||||
@@ -59,23 +61,23 @@ bool inRange(float x, float a, float b){
|
||||
void main() {
|
||||
vec2 uv = vec2(0.5,0.5)*vs_position.xy+vec2(0.5,0.5);
|
||||
|
||||
vec2 radius = vec2(0.71492f, 8.f);
|
||||
vec4 in_pos = uvToModel(uv.x, uv.y, radius, 200);
|
||||
// vec2 radius_expl = vec2(0.71492f, 8.f);
|
||||
vec4 vertex = uvToModel(uv.x, uv.y, radius, vs_segments);
|
||||
|
||||
vec4 raw_pos = psc_to_meter(in_pos, _scaling);
|
||||
vec4 raw_pos = psc_to_meter(vertex, _scaling);
|
||||
vec4 projected = ProjectorMatrix * ModelTransform * raw_pos;
|
||||
|
||||
projected.x /= projected.w;
|
||||
projected.y /= projected.w;
|
||||
|
||||
vec4 normal = normalize(ModelTransform * vec4(in_pos.xyz,0));
|
||||
vec4 normal = normalize(ModelTransform * vec4(vertex.xyz,0));
|
||||
|
||||
//"in range"
|
||||
if(inRange(projected.x, 0, 1) &&
|
||||
inRange(projected.y, 0, 1) &&
|
||||
dot(normal.xyz,vs_boresight) < 0 ){
|
||||
inRange(projected.y, 0, 1) &&
|
||||
dot(normal.xyz,vs_boresight) < -0.09 ){
|
||||
color = texture(texture1, projected.xy);
|
||||
color.a = 1.0f;
|
||||
// color.a = 1.0f;
|
||||
}else{
|
||||
color = vec4(1,0,0,0);
|
||||
}
|
||||
|
||||
@@ -28,14 +28,17 @@ uniform mat4 ModelTransform;
|
||||
uniform vec2 _scaling;
|
||||
|
||||
layout(location = 0) in vec4 in_position;
|
||||
layout(location = 2) in vec3 boresight;
|
||||
layout(location = 1) in vec3 boresight;
|
||||
layout(location = 2) in int segments;
|
||||
uniform vec2 radius;
|
||||
|
||||
out vec4 vs_position;
|
||||
out vec3 vs_boresight;
|
||||
|
||||
flat out uint vs_segments;
|
||||
|
||||
void main() {
|
||||
vs_position = in_position;
|
||||
vs_position = in_position;
|
||||
vs_boresight = boresight;
|
||||
gl_Position = vec4(in_position.xy, 0.0, 1.0);
|
||||
vs_segments = segments;
|
||||
gl_Position = vec4(in_position.xy, 0.0, 1.0);
|
||||
}
|
||||
|
||||
@@ -42,30 +42,21 @@
|
||||
#include <math.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "RenderablePlanetProjection";
|
||||
const std::string _loggerCat = "RenderablePlanetProjection";
|
||||
const std::string keyProjObserver = "Projection.Observer";
|
||||
const std::string keyProjTarget = "Projection.Target";
|
||||
const std::string keyProjAberration = "Projection.Aberration";
|
||||
const std::string keyInstrument = "Instrument.Name";
|
||||
const std::string keyInstrumentFovy = "Instrument.Fovy";
|
||||
const std::string keyInstrumentAspect = "Instrument.Aspect";
|
||||
const std::string keyInstrumentNear = "Instrument.Near";
|
||||
const std::string keyInstrumentFar = "Instrument.Far";
|
||||
|
||||
const std::string _mainFrame = "GALACTIC";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
#define printOpenGLError() printOglError(__FILE__, __LINE__)
|
||||
|
||||
int printOglError(char *file, int line)
|
||||
{
|
||||
|
||||
GLenum glErr;
|
||||
int retCode = 0;
|
||||
|
||||
glErr = glGetError();
|
||||
if (glErr != GL_NO_ERROR)
|
||||
{
|
||||
printf("glError in file %s @ line %d: %s\n",
|
||||
file, line, gluErrorString(glErr));
|
||||
retCode = 1;
|
||||
}
|
||||
return retCode;
|
||||
}
|
||||
|
||||
|
||||
RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _colorTexturePath("colorTexture", "Color Texture")
|
||||
@@ -77,6 +68,24 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
|
||||
, _textureProj(nullptr)
|
||||
, _geometry(nullptr)
|
||||
{
|
||||
bool b1 = dictionary.getValue(keyInstrument , _instrumentID);
|
||||
bool b2 = dictionary.getValue( keyProjObserver , _projectorID );
|
||||
bool b3 = dictionary.getValue( keyProjTarget , _projecteeID );
|
||||
bool b4 = dictionary.getValue( keyProjAberration , _aberration );
|
||||
bool b5 = dictionary.getValue(keyInstrumentFovy , _fovy);
|
||||
bool b6 = dictionary.getValue(keyInstrumentAspect, _aspectRatio);
|
||||
bool b7 = dictionary.getValue(keyInstrumentNear , _nearPlane);
|
||||
bool b8 = dictionary.getValue(keyInstrumentFar , _farPlane);
|
||||
|
||||
assert(b1 == true);
|
||||
assert(b2 == true);
|
||||
assert(b3 == true);
|
||||
assert(b4 == true);
|
||||
assert(b5 == true);
|
||||
assert(b6 == true);
|
||||
assert(b7 == true);
|
||||
assert(b8 == true);
|
||||
|
||||
std::string name;
|
||||
bool success = dictionary.getValue(constants::scenegraphnode::keyName, name);
|
||||
assert(success);
|
||||
@@ -110,7 +119,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
|
||||
addPropertySubOwner(_geometry);
|
||||
|
||||
addProperty(_imageTrigger);
|
||||
_imageTrigger.onChange(std::bind(&RenderablePlanetProjection::imageProject, this));
|
||||
_imageTrigger.onChange(std::bind(&RenderablePlanetProjection::imageProjectGPU, this));
|
||||
|
||||
addProperty(_colorTexturePath);
|
||||
_colorTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadTexture, this));
|
||||
@@ -122,11 +131,7 @@ RenderablePlanetProjection::~RenderablePlanetProjection(){
|
||||
deinitialize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool RenderablePlanetProjection::initialize(){
|
||||
_computeShader = genComputeProg();
|
||||
|
||||
bool completeSuccess = true;
|
||||
if (_programObject == nullptr)
|
||||
completeSuccess
|
||||
@@ -142,6 +147,13 @@ bool RenderablePlanetProjection::initialize(){
|
||||
|
||||
completeSuccess &= _geometry->initialize(this);
|
||||
|
||||
completeSuccess &= auxiliaryRendertarget();
|
||||
|
||||
return completeSuccess;
|
||||
}
|
||||
|
||||
bool RenderablePlanetProjection::auxiliaryRendertarget(){
|
||||
bool completeSuccess = false;
|
||||
// setup FBO
|
||||
glGenFramebuffers(1, &_fboID);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
|
||||
@@ -150,21 +162,19 @@ bool RenderablePlanetProjection::initialize(){
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE)
|
||||
completeSuccess &= false;
|
||||
|
||||
// switch back to window-system-provided framebuffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
|
||||
// SCREEN-QUAD
|
||||
const GLfloat size = 1.0f;
|
||||
const GLfloat w = 1.0f;
|
||||
const GLfloat vertex_data[] = {
|
||||
// x y z w s t
|
||||
-size, -size, 0.0f, w, 0, 1,
|
||||
size, size, 0.0f, w, 1, 0,
|
||||
-size, size, 0.0f, w, 0, 0,
|
||||
-size, -size, 0.0f, w, 0, 1,
|
||||
size, -size, 0.0f, w, 1, 1,
|
||||
size, size, 0.0f, w, 1, 0,
|
||||
const GLfloat vertex_data[] = {
|
||||
-size, -size, 0.0f, w, 0, 1,
|
||||
size, size, 0.0f, w, 1, 0,
|
||||
-size, size, 0.0f, w, 0, 0,
|
||||
-size, -size, 0.0f, w, 0, 1,
|
||||
size, -size, 0.0f, w, 1, 1,
|
||||
size, size, 0.0f, w, 1, 0,
|
||||
};
|
||||
|
||||
glGenVertexArrays(1, &_quad); // generate array
|
||||
@@ -177,7 +187,7 @@ bool RenderablePlanetProjection::initialize(){
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(sizeof(GLfloat) * 4));
|
||||
|
||||
return completeSuccess;
|
||||
return completeSuccess;
|
||||
}
|
||||
|
||||
bool RenderablePlanetProjection::deinitialize(){
|
||||
@@ -190,102 +200,102 @@ bool RenderablePlanetProjection::deinitialize(){
|
||||
_textureProj = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderablePlanetProjection::isReady() const {
|
||||
return (_geometry != nullptr);
|
||||
}
|
||||
GLuint RenderablePlanetProjection::genComputeProg() {
|
||||
// Creating the compute shader, and the program object containing the shader
|
||||
GLuint progHandle = glCreateProgram();
|
||||
GLuint cs = glCreateShader(GL_COMPUTE_SHADER);
|
||||
|
||||
// In order to write to a texture, we have to introduce it as image2D.
|
||||
// local_size_x/y/z layout variables define the work group size.
|
||||
// gl_GlobalInvocationID is a uvec3 variable giving the global ID of the thread,
|
||||
// gl_LocalInvocationID is the local index within the work group, and
|
||||
// gl_WorkGroupID is the work group's index
|
||||
const char *csSrc[] = {
|
||||
"#version 440\n",
|
||||
"layout (binding = 0, rgba32f) uniform image2D destTex;\
|
||||
layout (local_size_x = 16, local_size_y = 16) in;\
|
||||
void main() {\
|
||||
ivec2 storePos = ivec2(gl_GlobalInvocationID.xy);\
|
||||
imageStore(destTex, storePos, vec4(1.0,0,0,1.0));\
|
||||
}"
|
||||
};
|
||||
void RenderablePlanetProjection::imageProjectGPU(){
|
||||
// keep handle to the current bound FBO
|
||||
GLint defaultFBO;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
|
||||
|
||||
glShaderSource(cs, 2, csSrc, NULL);
|
||||
glCompileShader(cs);
|
||||
int rvalue;
|
||||
glGetShaderiv(cs, GL_COMPILE_STATUS, &rvalue);
|
||||
if (!rvalue) {
|
||||
fprintf(stderr, "Error in compiling the compute shader\n");
|
||||
GLchar log[10240];
|
||||
GLsizei length;
|
||||
glGetShaderInfoLog(cs, 10239, &length, log);
|
||||
fprintf(stderr, "Compiler log:\n%s\n", log);
|
||||
exit(40);
|
||||
GLint m_viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, m_viewport);
|
||||
|
||||
static int counter = 0;
|
||||
if (counter > 1){ // every something frame for now..
|
||||
counter = 0;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
|
||||
// set blend eq
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ZERO);
|
||||
glViewport(0, 0, _texture->width(), _texture->height());
|
||||
_fboProgramObject->activate();
|
||||
|
||||
ghoul::opengl::TextureUnit unitFbo;
|
||||
unitFbo.activate();
|
||||
_textureProj->bind();
|
||||
_fboProgramObject->setUniform("texture1", unitFbo);
|
||||
_fboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix);
|
||||
_fboProgramObject->setUniform("ModelTransform", _transform);
|
||||
_fboProgramObject->setUniform("_scaling", _camScaling);
|
||||
_fboProgramObject->setAttribute("boresight", _boresight);
|
||||
|
||||
//TODO - needs target switching.
|
||||
if (_geometry->hasProperty("radius")){
|
||||
boost::any r = _geometry->property("radius")->get();
|
||||
if (glm::vec2* radius = boost::any_cast<glm::vec2>(&r)){
|
||||
_fboProgramObject->setUniform("radius", radius[0]);
|
||||
}
|
||||
}else{
|
||||
LERROR("Geometry object needs to provide radius");
|
||||
}
|
||||
// pass nr of segments
|
||||
if (_geometry->hasProperty("segments")){
|
||||
boost::any s = _geometry->property("segments")->get();
|
||||
if (int* segments = boost::any_cast<int>(&s)){
|
||||
_fboProgramObject->setAttribute("segments", segments[0]);
|
||||
}
|
||||
}else{
|
||||
LERROR("Geometry object needs to provide segment count");
|
||||
}
|
||||
|
||||
glBindVertexArray(_quad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
_fboProgramObject->deactivate();
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
//bind back to default
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
|
||||
glViewport(m_viewport[0], m_viewport[1],
|
||||
m_viewport[2], m_viewport[3]);
|
||||
}
|
||||
else{
|
||||
printf(" CS COMPILE SUCCESS");
|
||||
}
|
||||
glAttachShader(progHandle, cs);
|
||||
|
||||
glLinkProgram(progHandle);
|
||||
glGetProgramiv(progHandle, GL_LINK_STATUS, &rvalue);
|
||||
if (!rvalue) {
|
||||
fprintf(stderr, "Error in linking compute shader program\n");
|
||||
GLchar log[10240];
|
||||
GLsizei length;
|
||||
glGetProgramInfoLog(progHandle, 10239, &length, log);
|
||||
fprintf(stderr, "Linker log:\n%s\n", log);
|
||||
exit(41);
|
||||
}
|
||||
else{
|
||||
printf(" CS LINK SUCCESS");
|
||||
}
|
||||
|
||||
return progHandle;
|
||||
}
|
||||
void RenderablePlanetProjection::updateTex(){
|
||||
|
||||
glUseProgram(_computeShader);
|
||||
|
||||
const GLint location = glGetUniformLocation(_computeShader, "destTex"); //
|
||||
if (location == -1){
|
||||
printf("Could not locate uniform location for texture in CS");
|
||||
}
|
||||
|
||||
//ghoul::opengl::TextureUnit unit;
|
||||
//unit.activate();
|
||||
_texture->bind();
|
||||
//GLint format = _texture->internalFormat();
|
||||
//GLint format = _texture->format();
|
||||
//glUniform1i(location, 0);
|
||||
glBindImageTexture(0, *_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
|
||||
|
||||
glDispatchCompute(_texture->width() / 16, _texture->height() / 16, 1);
|
||||
|
||||
glUseProgram(0);
|
||||
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
|
||||
printOpenGLError();
|
||||
counter++;
|
||||
}
|
||||
|
||||
#define RENDER_TO_TEXTURE
|
||||
void RenderablePlanetProjection::render(const RenderData& data)
|
||||
{
|
||||
glm::mat4 RenderablePlanetProjection::computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up){
|
||||
//rotate boresight into correct alignment
|
||||
_boresight = _instrumentMatrix*aim;
|
||||
glm::vec3 uptmp(_instrumentMatrix*glm::dvec3(up));
|
||||
|
||||
//create view matrix
|
||||
glm::vec3 e3 = glm::normalize(_boresight);
|
||||
glm::vec3 e1 = glm::normalize(glm::cross(uptmp, e3));
|
||||
glm::vec3 e2 = glm::normalize(glm::cross(e3, e1));
|
||||
glm::mat4 projViewMatrix = glm::mat4(e1.x, e2.x, e3.x, 0.f,
|
||||
e1.y, e2.y, e3.y, 0.f,
|
||||
e1.z, e2.z, e3.z, 0.f,
|
||||
-glm::dot(e1, loc), -glm::dot(e2, loc), -glm::dot(e3, loc), 1.f);
|
||||
//create perspective projection matrix
|
||||
glm::mat4 projProjectionMatrix = glm::perspective(_fovy, _aspectRatio, _nearPlane, _farPlane);
|
||||
//bias matrix
|
||||
glm::mat4 projNormalizationMatrix = glm::mat4(0.5f, 0, 0, 0,
|
||||
0, 0.5f, 0, 0,
|
||||
0, 0, 0.5f, 0,
|
||||
0.5f, 0.5f, 0.5f, 1);
|
||||
return projNormalizationMatrix*projProjectionMatrix*projViewMatrix;
|
||||
}
|
||||
|
||||
#define SEQUENCING
|
||||
void RenderablePlanetProjection::render(const RenderData& data){
|
||||
if (!_programObject) return;
|
||||
if (!_textureProj) return;
|
||||
|
||||
//updateTex();
|
||||
// activate shader
|
||||
|
||||
// scale the planet to appropriate size since the planet is a unit sphere
|
||||
// precomputations for shader
|
||||
_transform = glm::mat4(1);
|
||||
|
||||
//earth needs to be rotated for that to work.
|
||||
//90 deg rotation w.r.t spice req.
|
||||
glm::mat4 rot = glm::rotate(_transform, 90.f, glm::vec3(1, 0, 0));
|
||||
|
||||
for (int i = 0; i < 3; i++){
|
||||
for (int j = 0; j < 3; j++){
|
||||
_transform[i][j] = _stateMatrix[i][j];
|
||||
@@ -295,249 +305,55 @@ void RenderablePlanetProjection::render(const RenderData& data)
|
||||
if (_target == "IAU_JUPITER"){ // tmp scale of jupiterx = 0.935126
|
||||
_transform *= glm::scale(glm::mat4(1), glm::vec3(1, 0.935126, 1));
|
||||
}
|
||||
|
||||
// PROJECTIVE TEXTURING----------------------------------------------------------
|
||||
// get fov
|
||||
std::string shape, instrument;
|
||||
std::vector<glm::dvec3> bounds;
|
||||
glm::dvec3 bs;
|
||||
bool found = openspace::SpiceManager::ref().getFieldOfView("NH_LORRI", shape, instrument, bs, bounds);
|
||||
bool found = openspace::SpiceManager::ref().getFieldOfView(_instrumentID, shape, instrument, bs, bounds);
|
||||
if (!found) LERROR("Could not locate instrument");
|
||||
|
||||
psc position;
|
||||
double lightTime = 0.0;
|
||||
SpiceManager::ref().getTargetPosition("NEW HORIZONS", "JUPITER BARYCENTER","GALACTIC", "NONE", _time, position, lightTime);
|
||||
SpiceManager::ref().getTargetPosition(_projectorID, _projecteeID, _mainFrame, _aberration, _time, position, lightTime);
|
||||
position[3] += 3;
|
||||
glm::vec3 nh_pos = position.vec3();
|
||||
glm::vec3 cpos = position.vec3();
|
||||
|
||||
//get up-vecto
|
||||
//rotate boresight into correct alignment
|
||||
_boresight = _instrumentMatrix*bs;
|
||||
glm::vec3 uptmp(_instrumentMatrix*glm::dvec3(data.camera.lookUpVector()));
|
||||
|
||||
//create view matrix
|
||||
glm::vec3 e3 = glm::normalize(_boresight);
|
||||
glm::vec3 e1 = glm::normalize(glm::cross(uptmp, e3));
|
||||
glm::vec3 e2 = glm::normalize(glm::cross(e3, e1));
|
||||
|
||||
glm::mat4 projViewMatrix = glm::mat4( e1.x, e2.x, e3.x, 0.f,
|
||||
e1.y, e2.y, e3.y, 0.f,
|
||||
e1.z, e2.z, e3.z, 0.f,
|
||||
-glm::dot(e1, nh_pos), -glm::dot(e2, nh_pos), -glm::dot(e3, nh_pos), 1.f);
|
||||
//create perspective projection matrix
|
||||
glm::mat4 projProjectionMatrix = glm::perspective(0.2907f, 1.f, 0.2f, 1000000.0f);
|
||||
//bias matrix
|
||||
glm::mat4 projNormalizationMatrix = glm::mat4(0.5f, 0 , 0 , 0,
|
||||
0 , 0.5f, 0 , 0,
|
||||
0 , 0 , 0.5f, 0,
|
||||
0.5f, 0.5f, 0.5f, 1 );
|
||||
_projectorMatrix = computeProjectorMatrix(cpos, bs, data.camera.lookUpVector());
|
||||
|
||||
_camScaling = data.camera.scaling();
|
||||
|
||||
_projectorMatrix = projNormalizationMatrix*projProjectionMatrix*projViewMatrix;
|
||||
|
||||
// keep handle to the current bound FBO
|
||||
GLint defaultFBO;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
|
||||
|
||||
#ifdef RENDER_TO_TEXTURE
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ZERO);
|
||||
glViewport(0, 0, _texture->width(), _texture->height());
|
||||
_fboProgramObject->activate();
|
||||
|
||||
ghoul::opengl::TextureUnit unitFbo;
|
||||
unitFbo.activate();
|
||||
_textureProj->bind();
|
||||
_fboProgramObject->setUniform("texture1", unitFbo);
|
||||
_fboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix);
|
||||
_fboProgramObject->setUniform("ModelTransform", _transform);
|
||||
_fboProgramObject->setUniform("_scaling", data.camera.scaling());
|
||||
_fboProgramObject->setAttribute("boresight", _boresight);
|
||||
|
||||
|
||||
glBindVertexArray(_quad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
|
||||
_fboProgramObject->deactivate();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
//bind back to default
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
|
||||
glViewport(0, 0, 1920, 1080);
|
||||
#ifdef SEQUENCING
|
||||
imageProjectGPU();
|
||||
#endif
|
||||
|
||||
// Main renderpass
|
||||
_programObject->activate();
|
||||
// setup the data to the shader
|
||||
_programObject->setUniform("ProjectorMatrix", _projectorMatrix);
|
||||
_programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_programObject->setUniform("ModelTransform", _transform);
|
||||
_programObject->setAttribute("boresight", _boresight);
|
||||
_programObject->setUniform("ViewProjection" , data.camera.viewProjectionMatrix());
|
||||
_programObject->setUniform("ModelTransform" , _transform);
|
||||
_programObject->setAttribute("boresight" , _boresight);
|
||||
setPscUniforms(_programObject, &data.camera, data.position);
|
||||
|
||||
// Bind texture
|
||||
ghoul::opengl::TextureUnit unit;
|
||||
unit.activate();
|
||||
ghoul::opengl::TextureUnit unit[2];
|
||||
unit[0].activate();
|
||||
_texture->bind();
|
||||
_programObject->setUniform("texture1", unit); // jupiter
|
||||
|
||||
ghoul::opengl::TextureUnit unit2;
|
||||
unit2.activate();
|
||||
_programObject->setUniform("texture1", unit[0]);
|
||||
unit[1].activate();
|
||||
_textureProj->bind();
|
||||
_programObject->setUniform("texture2", unit2); // proj
|
||||
|
||||
// render
|
||||
_programObject->setUniform("texture2", unit[1]);
|
||||
// render geometry
|
||||
_geometry->render();
|
||||
|
||||
// disable shader
|
||||
_programObject->deactivate();
|
||||
|
||||
}
|
||||
|
||||
void RenderablePlanetProjection::imageProject(){
|
||||
//_textureProj->downloadTexture();
|
||||
//_texture->downloadTexture();
|
||||
|
||||
auto uvToModel = [](float u, float v, float radius[2], float fsegments)->glm::vec4{
|
||||
|
||||
const float fj = u * fsegments;
|
||||
const float fi = v * fsegments;
|
||||
|
||||
const float theta = fi * float(M_PI) / fsegments; // 0 -> PI
|
||||
const float phi = fj * float(M_PI) * 2.0f / fsegments;
|
||||
|
||||
const float x = radius[0] * sin(phi) * sin(theta); //
|
||||
const float y = radius[0] * cos(theta); // up
|
||||
const float z = radius[0] * cos(phi) * sin(theta); //
|
||||
|
||||
return glm::vec4(x, y, z, radius[1]);
|
||||
};
|
||||
|
||||
auto uvToIndex = [](const glm::vec2 &uv, int w, int h, int &i, int &j){
|
||||
i = static_cast<int>(uv.x * float(w));
|
||||
j = static_cast<int>(uv.y * float(h));
|
||||
};
|
||||
|
||||
auto inRange = [](int x, int a, int b)->bool{
|
||||
return (x >= a && x <= b);
|
||||
};
|
||||
|
||||
auto pscToMeter = [](glm::vec4 v1, glm::vec2 v2)->glm::vec4{
|
||||
float factor = v2.x * pow(10, v2.y + v1.w);
|
||||
return glm::vec4(v1.xyz * factor, 1.0);
|
||||
};
|
||||
|
||||
typedef glm::detail::tvec3<glm::detail::uint8> rgb;
|
||||
|
||||
auto bilinear = [inRange](const ghoul::opengl::Texture* dest, const ghoul::opengl::Texture* source,
|
||||
float x, float y, float i, float j)->rgb{
|
||||
x = (x * float(source->width()));
|
||||
y = (y * float(source->height()));
|
||||
|
||||
int px = static_cast<int>(std::floor(x)); // floor of x
|
||||
int py = static_cast<int>(std::floor(y)); // floor of y
|
||||
|
||||
rgb p0, p1, p2, p3;
|
||||
//original
|
||||
int of = 0;
|
||||
|
||||
bool x0 = inRange(px, 1, source->width() - 1);
|
||||
bool y0 = inRange(py, 1, source->height() - 1);
|
||||
bool x1 = inRange(px + 1, 1, source->width() - 1);
|
||||
bool y1 = inRange(py + 1, 1, source->height() - 1);
|
||||
|
||||
p0 = x0 && y0 ? source->texel<rgb>(px + 0, py + 0) : dest->texel<rgb>(i + 0, j + 0);
|
||||
p1 = x1 && y0 ? source->texel<rgb>(px + 1, py + 0) : dest->texel<rgb>(i + 1, j + 0);
|
||||
p2 = x0 && y1 ? source->texel<rgb>(px + 0, py + 1) : dest->texel<rgb>(i + 0, j + 1);
|
||||
p3 = x1 && y1 ? source->texel<rgb>(px + 1, py + 1) : dest->texel<rgb>(i + 1, j + 1);
|
||||
|
||||
|
||||
glm::vec3 p0f = (glm::vec3)p0;
|
||||
glm::vec3 p1f = (glm::vec3)p1;
|
||||
glm::vec3 p2f = (glm::vec3)p2;
|
||||
glm::vec3 p3f = (glm::vec3)p3;
|
||||
|
||||
float a = x - float(px);
|
||||
float b = y - float(py);
|
||||
if (a < 0) a = -a;
|
||||
if (b < 0) b = -b;
|
||||
|
||||
glm::vec3 v1 = p0f*(1-a) + a*p1f;
|
||||
glm::vec3 v2 = p2f*(1-a) + a*p3f;
|
||||
|
||||
glm::vec3 v = v1*(1-b) + b*v2;
|
||||
|
||||
return rgb(v[0], v[1], v[2]);
|
||||
};
|
||||
|
||||
const float w = _texture->width();
|
||||
const float h = _texture->height();
|
||||
const float wp = _textureProj->width();
|
||||
const float hp = _textureProj->height();
|
||||
|
||||
for (int i = 0; i < w; ++i) {
|
||||
for (int j = 0; j < h; ++j) {
|
||||
// "Shader code"
|
||||
// Texture coordinates
|
||||
float u = float(i) / w;
|
||||
float v = float(j) / h;
|
||||
|
||||
// Psc scaling
|
||||
// Convert texture coordinates to model coordinates
|
||||
float radius[2] = { 0.71492f, 8.f };
|
||||
glm::vec4 in_position = uvToModel(u, v, radius, 200);
|
||||
bool frontfacing = glm::dot(_boresight, glm::vec3((_transform*in_position).xyz)) < 0;
|
||||
|
||||
// Convert psc to meters
|
||||
glm::vec4 raw_pos = pscToMeter(in_position, _camScaling);
|
||||
|
||||
// Transform model coordinates to world coordinates
|
||||
glm::vec4 projected = _projectorMatrix * _transform * raw_pos;
|
||||
|
||||
projected.x /= projected.w;
|
||||
projected.y /= projected.w;
|
||||
|
||||
// To do : use bilinear interpolation
|
||||
int x, y;
|
||||
glm::vec2 uv;
|
||||
uv.x = projected.x;
|
||||
uv.y = projected.y;
|
||||
uvToIndex(uv, wp, hp, x, y);
|
||||
|
||||
if (frontfacing && inRange(x, 0, wp - 1) && inRange(y, 0, hp - 1)){
|
||||
rgb final(0);
|
||||
|
||||
if (x <= (wp*0.5f)){ // bilinear vs nonbilinear comparison
|
||||
final = bilinear(_texture, _textureProj, uv.x, uv.y, i, j);// _textureProj->texel<rgb>(x, y);
|
||||
}else{
|
||||
final = _textureProj->texel<rgb>(x, y);
|
||||
}
|
||||
_texture->texel<rgb>(i, j) = final;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Upload textures
|
||||
_textureProj->uploadTexture();
|
||||
//_texture->uploadTexture();
|
||||
|
||||
}
|
||||
|
||||
void RenderablePlanetProjection::update(const UpdateData& data){
|
||||
// set spice-orientation in accordance to timestamp
|
||||
_time = data.time;
|
||||
openspace::SpiceManager::ref().getPositionTransformMatrix(_target, "GALACTIC", data.time, _stateMatrix);
|
||||
openspace::SpiceManager::ref().getPositionTransformMatrix("NH_LORRI", "GALACTIC", data.time, _instrumentMatrix);
|
||||
|
||||
openspace::SpiceManager::ref().getPositionTransformMatrix(_target, _mainFrame, data.time, _stateMatrix);
|
||||
openspace::SpiceManager::ref().getPositionTransformMatrix(_instrumentID, _mainFrame, data.time, _instrumentMatrix);
|
||||
}
|
||||
|
||||
void RenderablePlanetProjection::loadTexture()
|
||||
{
|
||||
void RenderablePlanetProjection::loadTexture(){
|
||||
delete _texture;
|
||||
_texture = nullptr;
|
||||
if (_colorTexturePath.value() != "") {
|
||||
@@ -550,7 +366,6 @@ void RenderablePlanetProjection::loadTexture()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
delete _textureProj;
|
||||
_textureProj = nullptr;
|
||||
if (_colorTexturePath.value() != "") {
|
||||
|
||||
@@ -37,17 +37,15 @@
|
||||
#include <chrono>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "RenderableFov";
|
||||
//constants
|
||||
const std::string keyBody = "Body";
|
||||
const std::string keyFrame = "Frame";
|
||||
const std::string keyPathModule = "ModulePath";
|
||||
const std::string keyColor = "RGB";
|
||||
const std::string keyInstrument = "Instrument.Name";
|
||||
const std::string keyInstrumentMethod = "Instrument.Method";
|
||||
const std::string keyInstrumentAberration = "Instrument.Aberration";
|
||||
|
||||
|
||||
const std::string _loggerCat = "RenderableFov";
|
||||
//constants
|
||||
const std::string keyBody = "Body";
|
||||
const std::string keyFrame = "Frame";
|
||||
const std::string keyPathModule = "ModulePath";
|
||||
const std::string keyColor = "RGB";
|
||||
const std::string keyInstrument = "Instrument.Name";
|
||||
const std::string keyInstrumentMethod = "Instrument.Method";
|
||||
const std::string keyInstrumentAberration = "Instrument.Aberration";
|
||||
}
|
||||
//#define DEBUG
|
||||
namespace openspace{
|
||||
@@ -67,11 +65,17 @@ namespace openspace{
|
||||
, _texture(nullptr)
|
||||
, _mode(GL_LINES){
|
||||
|
||||
assert(dictionary.getValue(keyBody , _spacecraft));
|
||||
assert(dictionary.getValue(keyFrame , _frame));
|
||||
assert(dictionary.getValue(keyInstrument , _instrumentID));
|
||||
assert(dictionary.getValue(keyInstrumentMethod , _method));
|
||||
assert(dictionary.getValue(keyInstrumentAberration , _aberrationCorrection));
|
||||
bool b1 = dictionary.getValue(keyBody , _spacecraft);
|
||||
bool b2 = dictionary.getValue(keyFrame , _frame);
|
||||
bool b3 = dictionary.getValue(keyInstrument , _instrumentID);
|
||||
bool b4 = dictionary.getValue(keyInstrumentMethod , _method);
|
||||
bool b5 = dictionary.getValue(keyInstrumentAberration , _aberrationCorrection);
|
||||
|
||||
assert(b1 == true);
|
||||
assert(b2 == true);
|
||||
assert(b3 == true);
|
||||
assert(b4 == true);
|
||||
assert(b5 == true);
|
||||
}
|
||||
void RenderableFov::allocateData(){
|
||||
int points = 8;
|
||||
|
||||
Reference in New Issue
Block a user