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:
Hans-Christian Helltegen
2014-02-26 23:38:33 +00:00
parent 5aab48f8bb
commit cb2cb177b3
11 changed files with 394 additions and 2 deletions
+17 -1
View File
@@ -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
+19
View File
@@ -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);
}
+15
View File
@@ -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;
}
+97
View File
@@ -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;
}
+53
View File
@@ -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);
}
+11
View File
@@ -0,0 +1,11 @@
#version 400 core
in vec4 Position;
out vec4 vPosition;
uniform mat4 modelViewProjection;
void main()
{
gl_Position = modelViewProjection * Position;
vPosition = Position;
}
+4
View File
@@ -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();
}
+3
View File
@@ -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;
+138
View File
@@ -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
+36
View File
@@ -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