mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-27 22:40:41 -05:00
Added a class for volume ray-casting and FBO class to ghoul. Also added a (probably tempoary) shader map to root dir with some shaders. Updated .gitignore for some common files
This commit is contained in:
+17
-1
@@ -1,4 +1,20 @@
|
||||
bin/
|
||||
build/
|
||||
ext/SGCT
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
|
||||
# CMake stuff
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
|
||||
# Eclipse stuff
|
||||
.cproject
|
||||
.project
|
||||
|
||||
# Doxygen stuff
|
||||
html/
|
||||
latex/
|
||||
Doxyfile
|
||||
|
||||
+1
-1
Submodule ext/ghoul updated: 9a8e9f1112...c23d35729e
@@ -0,0 +1,19 @@
|
||||
#version 400 core
|
||||
|
||||
uniform sampler2D texJonas;
|
||||
|
||||
in vec3 vPosition;
|
||||
in vec2 texCoords;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = vec4(vPosition+0.5, 1.0);
|
||||
if (fragColor.x <= 0.55 && fragColor.x >= 0.45)
|
||||
fragColor = vec4(1.0);
|
||||
else if (fragColor.y <= 0.55 && fragColor.y >= 0.45)
|
||||
fragColor = vec4(1.0);
|
||||
|
||||
fragColor = vec4(texCoords.x, texCoords.y, 0.0, 1.0);
|
||||
|
||||
fragColor = texture(texJonas, -texCoords+1);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#version 400 core
|
||||
|
||||
layout(location = 0) in vec2 texCoordinate;
|
||||
layout(location = 2) in vec3 vertPosition;
|
||||
uniform mat4 modelViewProjection;
|
||||
|
||||
out vec3 vPosition;
|
||||
out vec2 texCoords;
|
||||
|
||||
void main() {
|
||||
gl_Position = modelViewProjection * vec4(vertPosition, 1.0);
|
||||
// vPosition = gl_Position.xyz;
|
||||
vPosition = vertPosition;
|
||||
texCoords = texCoordinate;
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
#version 400 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler3D Density;
|
||||
uniform vec3 LightPosition = vec3(0.25, 1.0, 3.0);
|
||||
uniform vec3 LightIntensity = vec3(15.0);
|
||||
uniform float Absorption = 1.0;
|
||||
uniform mat4 Modelview;
|
||||
uniform float FocalLength;
|
||||
uniform vec2 WindowSize;
|
||||
uniform vec3 RayOrigin;
|
||||
|
||||
const float maxDist = sqrt(2.0);
|
||||
const int numSamples = 128;
|
||||
const float stepSize = maxDist/float(numSamples);
|
||||
const int numLightSamples = 32;
|
||||
const float lscale = maxDist / float(numLightSamples);
|
||||
const float densityFactor = 5;
|
||||
|
||||
struct Ray {
|
||||
vec3 Origin;
|
||||
vec3 Dir;
|
||||
};
|
||||
|
||||
struct AABB {
|
||||
vec3 Min;
|
||||
vec3 Max;
|
||||
};
|
||||
|
||||
bool IntersectBox(Ray r, AABB aabb, out float t0, out float t1)
|
||||
{
|
||||
vec3 invR = 1.0 / r.Dir;
|
||||
vec3 tbot = invR * (aabb.Min-r.Origin);
|
||||
vec3 ttop = invR * (aabb.Max-r.Origin);
|
||||
vec3 tmin = min(ttop, tbot);
|
||||
vec3 tmax = max(ttop, tbot);
|
||||
vec2 t = max(tmin.xx, tmin.yz);
|
||||
t0 = max(t.x, t.y);
|
||||
t = min(tmax.xx, tmax.yz);
|
||||
t1 = min(t.x, t.y);
|
||||
return t0 <= t1;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 rayDirection;
|
||||
rayDirection.xy = 2.0 * gl_FragCoord.xy / WindowSize - 1.0;
|
||||
rayDirection.z = -FocalLength;
|
||||
rayDirection = (vec4(rayDirection, 0) * Modelview).xyz;
|
||||
|
||||
Ray eye = Ray( RayOrigin, normalize(rayDirection) );
|
||||
AABB aabb = AABB(vec3(-1.0), vec3(+1.0));
|
||||
|
||||
float tnear, tfar;
|
||||
IntersectBox(eye, aabb, tnear, tfar);
|
||||
if (tnear < 0.0) tnear = 0.0;
|
||||
|
||||
vec3 rayStart = eye.Origin + eye.Dir * tnear;
|
||||
vec3 rayStop = eye.Origin + eye.Dir * tfar;
|
||||
rayStart = 0.5 * (rayStart + 1.0);
|
||||
rayStop = 0.5 * (rayStop + 1.0);
|
||||
|
||||
vec3 pos = rayStart;
|
||||
vec3 step = normalize(rayStop-rayStart) * stepSize;
|
||||
float travel = distance(rayStop, rayStart);
|
||||
float T = 1.0;
|
||||
vec3 Lo = vec3(0.0);
|
||||
|
||||
for (int i=0; i < numSamples && travel > 0.0; ++i, pos += step, travel -= stepSize) {
|
||||
|
||||
float density = texture(Density, pos).x * densityFactor;
|
||||
if (density <= 0.0)
|
||||
continue;
|
||||
|
||||
T *= 1.0-density*stepSize*Absorption;
|
||||
if (T <= 0.01)
|
||||
break;
|
||||
|
||||
vec3 lightDir = normalize(LightPosition-pos)*lscale;
|
||||
float Tl = 1.0;
|
||||
vec3 lpos = pos + lightDir;
|
||||
|
||||
for (int s=0; s < numLightSamples; ++s) {
|
||||
float ld = texture(Density, lpos).x;
|
||||
Tl *= 1.0-Absorption*stepSize*ld;
|
||||
if (Tl <= 0.01)
|
||||
lpos += lightDir;
|
||||
}
|
||||
|
||||
vec3 Li = LightIntensity*Tl;
|
||||
Lo += Li*T*density*stepSize;
|
||||
}
|
||||
|
||||
FragColor.rgb = Lo;
|
||||
FragColor.a = 1-T;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#version 400 core
|
||||
|
||||
layout(points) in;
|
||||
layout(triangle_strip, max_vertices = 24) out;
|
||||
|
||||
in vec4 vPosition[1];
|
||||
|
||||
uniform mat4 modelViewProjection;
|
||||
// uniform mat4 ProjectionMatrix;
|
||||
// uniform mat4 ViewMatrix;
|
||||
// uniform mat4 Modelview;
|
||||
|
||||
vec4 objCube[8]; // Object space coordinate of cube corner
|
||||
vec4 ndcCube[8]; // Normalized device coordinate of cube corner
|
||||
ivec4 faces[6]; // Vertex indices of the cube faces
|
||||
|
||||
void emit_vert(int vert)
|
||||
{
|
||||
gl_Position = ndcCube[vert];
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
void emit_face(int face)
|
||||
{
|
||||
emit_vert(faces[face][1]); emit_vert(faces[face][0]);
|
||||
emit_vert(faces[face][3]); emit_vert(faces[face][2]);
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
faces[0] = ivec4(0,1,3,2); faces[1] = ivec4(5,4,6,7);
|
||||
faces[2] = ivec4(4,5,0,1); faces[3] = ivec4(3,2,7,6);
|
||||
faces[4] = ivec4(0,3,4,7); faces[5] = ivec4(2,1,6,5);
|
||||
|
||||
vec4 P = vPosition[0];
|
||||
vec4 I = vec4(1,0,0,0);
|
||||
vec4 J = vec4(0,1,0,0);
|
||||
vec4 K = vec4(0,0,1,0);
|
||||
|
||||
objCube[0] = P+K+I+J; objCube[1] = P+K+I-J;
|
||||
objCube[2] = P+K-I-J; objCube[3] = P+K-I+J;
|
||||
objCube[4] = P-K+I+J; objCube[5] = P-K+I-J;
|
||||
objCube[6] = P-K-I-J; objCube[7] = P-K-I+J;
|
||||
|
||||
// Transform the corners of the box:
|
||||
for (int vert = 0; vert < 8; vert++)
|
||||
ndcCube[vert] = modelViewProjection * objCube[vert];
|
||||
|
||||
// Emit the six faces:
|
||||
for (int face = 0; face < 6; face++)
|
||||
emit_face(face);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#version 400 core
|
||||
|
||||
in vec4 Position;
|
||||
out vec4 vPosition;
|
||||
uniform mat4 modelViewProjection;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = modelViewProjection * Position;
|
||||
vPosition = Position;
|
||||
}
|
||||
@@ -33,6 +33,8 @@
|
||||
#include "util/time.h"
|
||||
#include "util//spice.h"
|
||||
|
||||
|
||||
|
||||
#include <ghoul/filesystem/filesystem>
|
||||
#include <ghoul/logging/logging>
|
||||
|
||||
@@ -150,6 +152,7 @@ bool OpenSpaceEngine::initialize() {
|
||||
|
||||
_engine->_interactionHandler->connectDevices();
|
||||
|
||||
_volumeRaycaster = new VolumeRaycaster();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -189,6 +192,7 @@ void OpenSpaceEngine::postSynchronizationPreDraw() {
|
||||
}
|
||||
|
||||
void OpenSpaceEngine::render() {
|
||||
_volumeRaycaster->render();
|
||||
_renderEngine->render();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "rendering/renderengine.h"
|
||||
#include <ghoul/misc/configurationmanager.h>
|
||||
|
||||
#include <rendering/volumeraycaster.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class ScriptEngine;
|
||||
@@ -62,6 +64,7 @@ private:
|
||||
|
||||
static OpenSpaceEngine* _engine;
|
||||
|
||||
VolumeRaycaster* _volumeRaycaster;
|
||||
ghoul::ConfigurationManager* _configurationManager;
|
||||
InteractionHandler* _interactionHandler;
|
||||
RenderEngine* _renderEngine;
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
#include "volumeraycaster.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/opengl/texturereader.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
GLuint vertexArray = GL_FALSE;
|
||||
GLuint vertexPositionBuffer = GL_FALSE;
|
||||
GLint matrix_loc = -1;
|
||||
GLuint sgctFBO;
|
||||
|
||||
VolumeRaycaster::VolumeRaycaster() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
VolumeRaycaster::VolumeRaycaster(Camera* camera) {
|
||||
_camera = camera;
|
||||
initialize();
|
||||
}
|
||||
|
||||
VolumeRaycaster::~VolumeRaycaster() {}
|
||||
|
||||
void VolumeRaycaster::initialize() {
|
||||
const GLfloat size = 0.5f;
|
||||
const GLfloat vertex_texcoord_data[] = { // square of two triangles (sigh)
|
||||
-size, -size, 0.0f, 0.0f, 0.0f,
|
||||
size, size, 0.0f, 1.0f, 1.0f,
|
||||
-size, size, 0.0f, 0.0f, 1.0f,
|
||||
-size, -size, 0.0f, 0.0f, 0.0f,
|
||||
size, -size, 0.0f, 1.0f, 0.0f,
|
||||
size, size, 0.0f, 1.0f, 1.0f
|
||||
};
|
||||
|
||||
glGenVertexArrays(1, &vertexArray); // generate array
|
||||
glBindVertexArray(vertexArray); // bind array
|
||||
|
||||
glGenBuffers(1, &vertexPositionBuffer); // generate buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_texcoord_data), vertex_texcoord_data, GL_STATIC_DRAW);
|
||||
|
||||
// Vertex positions
|
||||
GLuint vertexLocation = 2;
|
||||
glEnableVertexAttribArray(vertexLocation);
|
||||
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), reinterpret_cast<void*>(0));
|
||||
|
||||
// Texture coordinates
|
||||
GLuint texcoordLocation = 0;
|
||||
glEnableVertexAttribArray(texcoordLocation);
|
||||
glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (void*)(3*sizeof(GLfloat)));
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer
|
||||
glBindVertexArray(0); //unbind array
|
||||
|
||||
_test = loadTexture(absPath("${BASE_PATH}/openspace-data/jonas.jpg"));
|
||||
|
||||
if (_test == nullptr)
|
||||
std::cout << "Image failed to load" << std::endl;
|
||||
|
||||
_test->uploadTexture();
|
||||
|
||||
myBox = new sgct_utils::SGCTBox(1.5f, sgct_utils::SGCTBox::Regular);
|
||||
|
||||
// ------ SETUP SHADERS -----------------
|
||||
_program = new ProgramObject("RaycastProgram");
|
||||
|
||||
ShaderObject* vertexShader = new ShaderObject(ShaderObject::ShaderTypeVertex, absPath("${BASE_PATH}/shaders/passthrough.vert"));
|
||||
ShaderObject* fragmentShader = new ShaderObject(ShaderObject::ShaderTypeFragment, absPath("${BASE_PATH}/shaders/passthrough.frag"));
|
||||
|
||||
_program->attachObject(vertexShader);
|
||||
_program->attachObject(fragmentShader);
|
||||
|
||||
// ------ SETUP FBO ---------------------
|
||||
_fbo = new FramebufferObject();
|
||||
_fbo->activate();
|
||||
|
||||
int x = sgct::Engine::instance()->getActiveXResolution();
|
||||
int y = sgct::Engine::instance()->getActiveYResolution();
|
||||
_texture = new Texture(glm::size3_t(x,y,1));
|
||||
_texture->uploadTexture();
|
||||
|
||||
_fbo->attachTexture(_texture);
|
||||
if (_fbo->isComplete())
|
||||
std::cout << "All is well" << std::endl;
|
||||
else
|
||||
std::cout << "Uh oh" << std::endl;
|
||||
|
||||
_fbo->deactivate();
|
||||
}
|
||||
|
||||
void VolumeRaycaster::loadUniforms() {
|
||||
glm::mat4 modelViewProjectionMatrix = sgct::Engine::instance()->getActiveModelViewProjectionMatrix();
|
||||
_program->setUniform("modelViewProjection", modelViewProjectionMatrix);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
_test->bind();
|
||||
_program->setUniform("texJonas", 0);
|
||||
}
|
||||
|
||||
void VolumeRaycaster::render() {
|
||||
// ------ DRAW TO FBO -------------------
|
||||
sgctFBO = FramebufferObject::getActiveObject(); // Save SGCTs main FBO
|
||||
|
||||
_fbo->activate();
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
_program->compileShaderObjects();
|
||||
_program->linkProgramObject();
|
||||
_program->activate();
|
||||
loadUniforms();
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_FRONT);
|
||||
myBox->draw();
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
_program->deactivate();
|
||||
_fbo->deactivate();
|
||||
|
||||
// ------ DRAW TO SCREEN ----------------
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sgctFBO); // Re-bind SGCTs main FBO
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
_program->compileShaderObjects();
|
||||
_program->linkProgramObject();
|
||||
_program->activate();
|
||||
loadUniforms();
|
||||
|
||||
glBindVertexArray(vertexArray);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindVertexArray(0);
|
||||
|
||||
_program->deactivate();
|
||||
}
|
||||
|
||||
}// namespace openspace
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef VOLUMERAYCASTER_H
|
||||
#define VOLUMERAYCASTER_H
|
||||
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/framebufferobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
|
||||
#include <util/camera.h>
|
||||
#include <sgct.h>
|
||||
|
||||
namespace openspace {
|
||||
using namespace ghoul::opengl;
|
||||
|
||||
class VolumeRaycaster {
|
||||
public:
|
||||
VolumeRaycaster();
|
||||
VolumeRaycaster(Camera* camera);
|
||||
~VolumeRaycaster();
|
||||
void initialize();
|
||||
void render();
|
||||
|
||||
private:
|
||||
void loadUniforms();
|
||||
|
||||
FramebufferObject* _fbo;
|
||||
Texture* _texture;
|
||||
Texture* _test;
|
||||
|
||||
Camera* _camera;
|
||||
ProgramObject* _program;
|
||||
sgct_utils::SGCTBox* myBox;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // VOLUMERAYCASTER_H
|
||||
Reference in New Issue
Block a user