Poor mans ray-casting works, added a function for reading .raw files

This commit is contained in:
Hans-Christian Helltegen
2014-02-27 23:26:32 +00:00
parent cb2cb177b3
commit 53140a1fcd
7 changed files with 169 additions and 81 deletions

19
shaders/exitpoints.frag Normal file
View File

@@ -0,0 +1,19 @@
#version 400 core
// uniform sampler2D texUnit;
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(texUnit, -texCoords+1);
}

View File

@@ -9,7 +9,6 @@ out vec2 texCoords;
void main() {
gl_Position = modelViewProjection * vec4(vertPosition, 1.0);
// vPosition = gl_Position.xyz;
vPosition = vertPosition;
texCoords = texCoordinate;
}

View File

@@ -1,19 +0,0 @@
#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);
}

View File

@@ -0,0 +1,33 @@
#version 400 core
uniform sampler2D texBack, texFront;
uniform sampler3D texVolume;
uniform int screenWidth, screenHeight;
in vec3 vPosition;
in vec2 texCoords;
out vec4 fragColor;
void main() {;
fragColor = vec4(texCoords, 1.0, 1.0);
vec3 front = texture(texFront, texCoords).xyz;
vec3 back = texture(texBack, texCoords).xyz;
vec3 direction = back-front;
direction = normalize(direction);
vec3 position = front;
float stepSize = 0.05;
vec4 color = vec4(0);
vec4 tmp;
for (int i = 0; i < 100; ++i) {
tmp = texture(texVolume, position);
if (tmp.r > color.r)
color = tmp;
position = position + direction * stepSize;
}
fragColor = vec4(color.rrr,1.0);
}

View File

@@ -0,0 +1,15 @@
#version 400 core
layout(location = 0) in vec2 texCoordinate;
layout(location = 2) in vec3 vertPosition;
out vec3 vPosition;
out vec2 texCoords;
// Source: http://stackoverflow.com/questions/2588875/whats-the-best-way-to-draw-a-fullscreen-quad-in-opengl-3-2
const vec2 screenScale = vec2(0.5, 0.5);
void main() {
texCoords = vertPosition.xy*screenScale+screenScale; // scale vertex attribute to [0-1] range
gl_Position = vec4(vertPosition.xy, 0.0, 1.0);
}

View File

@@ -2,29 +2,21 @@
#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 size = 1.0f;
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,
@@ -54,23 +46,35 @@ void VolumeRaycaster::initialize() {
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer
glBindVertexArray(0); //unbind array
_test = loadTexture(absPath("${BASE_PATH}/openspace-data/jonas.jpg"));
myBox = new sgct_utils::SGCTBox(1.0f, sgct_utils::SGCTBox::Regular);
if (_test == nullptr)
std::cout << "Image failed to load" << std::endl;
_test->uploadTexture();
myBox = new sgct_utils::SGCTBox(1.5f, sgct_utils::SGCTBox::Regular);
// ------ VOLUME READING ----------------
const char* filename = "../openspace-data/skull_256x256x256_8.raw";
int dimensions[3];
dimensions[0] = 256;dimensions[1] = 256;dimensions[2] = 256;
createVolumetexture(filename, dimensions);
// ------ SETUP SHADERS -----------------
_program = new ProgramObject("RaycastProgram");
_FBOProgram = new ProgramObject("RaycastProgram");
ShaderObject* vertexShader = new ShaderObject(ShaderObject::ShaderTypeVertex, absPath("${BASE_PATH}/shaders/exitpoints.vert"));
ShaderObject* fragmentShader = new ShaderObject(ShaderObject::ShaderTypeFragment, absPath("${BASE_PATH}/shaders/exitpoints.frag"));
_FBOProgram->attachObject(vertexShader);
_FBOProgram->attachObject(fragmentShader);
_FBOProgram->compileShaderObjects();
_FBOProgram->linkProgramObject();
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);
_screenProgram = new ProgramObject("RaycastProgram");
vertexShader = new ShaderObject(ShaderObject::ShaderTypeVertex, absPath("${BASE_PATH}/shaders/rendertoscreen.vert"));
fragmentShader = new ShaderObject(ShaderObject::ShaderTypeFragment, absPath("${BASE_PATH}/shaders/rendertoscreen.frag"));
_screenProgram->attachObject(vertexShader);
_screenProgram->attachObject(fragmentShader);
_screenProgram->compileShaderObjects();
_screenProgram->linkProgramObject();
_screenProgram->setUniform("texBack", 0);
_screenProgram->setUniform("texFront", 1);
_screenProgram->setUniform("texVolume", 2);
_screenProgram->setUniform("screenWidth", sgct::Engine::instance()->getActiveXResolution());
_screenProgram->setUniform("screenHeight", sgct::Engine::instance()->getActiveYResolution());
// ------ SETUP FBO ---------------------
_fbo = new FramebufferObject();
@@ -78,61 +82,95 @@ void VolumeRaycaster::initialize() {
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;
_backTexture = new Texture(glm::size3_t(x,y,1));
_frontTexture = new Texture(glm::size3_t(x,y,1));
_backTexture->uploadTexture();
_frontTexture->uploadTexture();
_fbo->attachTexture(_backTexture, GL_COLOR_ATTACHMENT0);
_fbo->attachTexture(_frontTexture, GL_COLOR_ATTACHMENT1);
_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
glm::mat4 modelViewProjectionMatrix = sgct::Engine::instance()->getActiveModelViewProjectionMatrix();
_FBOProgram->setUniform("modelViewProjection", modelViewProjectionMatrix);
// ------ DRAW TO FBO -------------------
_sgctFBO = FramebufferObject::getActiveObject(); // Save SGCTs main FBO
_fbo->activate();
_FBOProgram->activate();
// Draw backface
glDrawBuffer(GL_COLOR_ATTACHMENT0);
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();
// Draw frontface
glDrawBuffer(GL_COLOR_ATTACHMENT1);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.2f, 0.2f, 0.2f, 0);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
myBox->draw();
glDisable(GL_CULL_FACE);
_FBOProgram->deactivate();
_fbo->deactivate();
// ------ DRAW TO SCREEN ----------------
glBindFramebuffer(GL_FRAMEBUFFER, sgctFBO); // Re-bind SGCTs main FBO
glBindFramebuffer(GL_FRAMEBUFFER, _sgctFBO); // Re-bind SGCTs main FBO
_screenProgram->activate();
// Set textures
glActiveTexture(GL_TEXTURE0);
_backTexture->bind();
glActiveTexture(GL_TEXTURE1);
_frontTexture->bind();
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_3D, _volumeTexture);
// Draw screenquad
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();
_screenProgram->deactivate();
}
void VolumeRaycaster::createVolumetexture(const char *filename, int dimensions[3]) {
// Make sure that the texture is not used
if(glIsTexture(_volumeTexture))
glDeleteTextures(1, &_volumeTexture);
int size = dimensions[0]*dimensions[1]*dimensions[2];
GLubyte *data = new GLubyte[size];
if( FILE *fin = fopen(filename, "rb") ){
fread(data, sizeof(unsigned char), size, fin);
fclose(fin);
}
else
fprintf( stderr, "Could not open file '%s'\n", filename );
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glGenTextures(1, &_volumeTexture);
glBindTexture(GL_TEXTURE_3D, _volumeTexture);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
glTexImage3D(GL_TEXTURE_3D, 0, GL_R8, dimensions[0], dimensions[1],dimensions[2],0, GL_RED, GL_UNSIGNED_BYTE,data);
glBindTexture(GL_TEXTURE_3D, 0);
delete []data;
std::cout << "Volume texture created" << std::endl;
}
}// namespace openspace

View File

@@ -5,8 +5,8 @@
#include <ghoul/opengl/framebufferobject.h>
#include <ghoul/opengl/texture.h>
#include <util/camera.h>
#include <sgct.h>
#include <cstdio>
namespace openspace {
using namespace ghoul::opengl;
@@ -14,20 +14,23 @@ using namespace ghoul::opengl;
class VolumeRaycaster {
public:
VolumeRaycaster();
VolumeRaycaster(Camera* camera);
~VolumeRaycaster();
void initialize();
void render();
private:
void loadUniforms();
void createVolumetexture(const char *filename, int dimensions[3]);
FramebufferObject* _fbo;
Texture* _texture;
Texture* _test;
Texture* _backTexture;
Texture* _frontTexture;
Texture* _volume;
Camera* _camera;
ProgramObject* _program;
GLuint _volumeTexture;
GLuint _sgctFBO;
ProgramObject* _FBOProgram;
ProgramObject* _screenProgram;
sgct_utils::SGCTBox* myBox;
};