Improved twopass raycaster. Started working on singlepassraycaster

This commit is contained in:
Hans-Christian Helltegen
2014-02-28 21:41:56 +00:00
parent 53140a1fcd
commit 986c7a764f
9 changed files with 197 additions and 128 deletions
-11
View File
@@ -1,19 +1,8 @@
#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);
}
-3
View File
@@ -1,14 +1,11 @@
#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 = vertPosition;
texCoords = texCoordinate;
}
+2
View File
@@ -94,4 +94,6 @@ void main()
FragColor.rgb = Lo;
FragColor.a = 1-T;
FragColor = vec4(1.0, 0.0, 1.0, 1.0);
}
+3 -3
View File
@@ -6,9 +6,9 @@ layout(triangle_strip, max_vertices = 24) out;
in vec4 vPosition[1];
uniform mat4 modelViewProjection;
// uniform mat4 ProjectionMatrix;
// uniform mat4 ViewMatrix;
// uniform mat4 Modelview;
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
+7 -5
View File
@@ -1,11 +1,13 @@
#version 400 core
layout(location = 5) in vec3 vertPosition;
uniform mat4 modelViewProjection;
in vec4 Position;
out vec4 vPosition;
uniform mat4 modelViewProjection;
void main()
{
gl_Position = modelViewProjection * Position;
vPosition = Position;
void main() {
vec4 vPos = vec4(vertPosition, 1.0);
gl_Position = modelViewProjection * vPos;
vPosition = vPos;
}
@@ -3,6 +3,7 @@
uniform sampler2D texBack, texFront;
uniform sampler3D texVolume;
uniform int screenWidth, screenHeight;
uniform float stepSize;
in vec3 vPosition;
in vec2 texCoords;
@@ -14,18 +15,14 @@ void main() {;
vec3 front = texture(texFront, texCoords).xyz;
vec3 back = texture(texBack, texCoords).xyz;
vec3 direction = back-front;
float directionLength = length(direction);
direction = normalize(direction);
vec3 position = front;
float stepSize = 0.05;
vec4 color = vec4(0);
vec4 tmp;
vec4 tmp, color = vec4(0);
for (int i = 0; i < 100; ++i) {
while (length(position-front) < directionLength && color.r != 1.0) {
tmp = texture(texVolume, position);
if (tmp.r > color.r)
color = tmp;
color = max(color, tmp); // MIP
position = position + direction * stepSize;
}
+176 -94
View File
@@ -3,11 +3,26 @@
#include <glm/glm.hpp>
#include <ghoul/filesystem/filesystem.h>
#include <iostream>
#include <cmath>
namespace openspace {
GLuint vertexArray = GL_FALSE;
GLuint vertexPositionBuffer = GL_FALSE;
GLuint CubeCenterVbo, SlotPosition;
float _stepSize = 0.05f;
sgct::SharedDouble curr_time(0.0);
void keyCallback(int key, int action);
GLuint CreatePointVbo(float x, float y, float z) {
float p[] = {x, y, z};
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(p), &p[0], GL_STATIC_DRAW);
return vbo;
}
VolumeRaycaster::VolumeRaycaster() {
initialize();
@@ -46,42 +61,69 @@ void VolumeRaycaster::initialize() {
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer
glBindVertexArray(0); //unbind array
myBox = new sgct_utils::SGCTBox(1.0f, sgct_utils::SGCTBox::Regular);
// myBox = new sgct_utils::SGCTBox(1.0f, 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);
const char* filename = absPath("${BASE_PATH}/openspace-data/skull_256x256x256_8.raw").c_str();
glm::ivec3 dimensions = glm::ivec3(256);
_volume = createVolumetexture(filename, dimensions);
// ------ SETUP SHADERS -----------------
_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();
_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();
_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());
_twopassProgram = new ProgramObject("RaycastProgram");
vertexShader = new ShaderObject(ShaderObject::ShaderTypeVertex,
absPath("${BASE_PATH}/shaders/twopassraycaster.vert"));
fragmentShader = new ShaderObject(ShaderObject::ShaderTypeFragment,
absPath("${BASE_PATH}/shaders/twopassraycaster.frag"));
_twopassProgram->attachObject(vertexShader);
_twopassProgram->attachObject(fragmentShader);
_twopassProgram->compileShaderObjects();
_twopassProgram->linkProgramObject();
_twopassProgram->setUniform("texBack", 0);
_twopassProgram->setUniform("texFront", 1);
_twopassProgram->setUniform("texVolume", 2);
_twopassProgram->setUniform("screenWidth", sgct::Engine::instance()->getActiveXResolution());
_twopassProgram->setUniform("screenHeight", sgct::Engine::instance()->getActiveYResolution());
_twopassProgram->setUniform("stepSize", _stepSize);
float top = sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewport()->getFrustum()->getTop();
float near = sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewport()->getFrustum()->getNear();
float FOV = float(atan(top / near)) * (180.0 / 3.141592653589793) * 2.0f;
float focalLength = 1.0f / tan(FOV / 2);
int x = sgct::Engine::instance()->getActiveXResolution();
int y = sgct::Engine::instance()->getActiveYResolution();
CubeCenterVbo = CreatePointVbo(0, 0, 0);
_singlepassProgram = new ProgramObject("RaycastProgram");
vertexShader = new ShaderObject(ShaderObject::ShaderTypeVertex,
absPath("${BASE_PATH}/shaders/singlepassraycaster.vert"));
fragmentShader = new ShaderObject(ShaderObject::ShaderTypeFragment,
absPath("${BASE_PATH}/shaders/singlepassraycaster.frag"));
ShaderObject* geometryShader = new ShaderObject(ShaderObject::ShaderTypeGeometry,
absPath("${BASE_PATH}/shaders/singlepassraycaster.gs"));
_singlepassProgram->attachObject(vertexShader);
_singlepassProgram->attachObject(fragmentShader);
_singlepassProgram->attachObject(geometryShader);
_singlepassProgram->compileShaderObjects();
_singlepassProgram->linkProgramObject();
_singlepassProgram->setUniform("FocalLength", focalLength);
_singlepassProgram->setUniform("WindowSize", glm::vec2(x,y));
_singlepassProgram->setUniform("Density", 2);
sgct::Engine::instance()->setKeyboardCallbackFunction(keyCallback);
// ------ SETUP FBO ---------------------
_fbo = new FramebufferObject();
_fbo->activate();
int x = sgct::Engine::instance()->getActiveXResolution();
int y = sgct::Engine::instance()->getActiveYResolution();
_backTexture = new Texture(glm::size3_t(x,y,1));
_frontTexture = new Texture(glm::size3_t(x,y,1));
_backTexture->uploadTexture();
@@ -92,85 +134,125 @@ void VolumeRaycaster::initialize() {
_fbo->deactivate();
}
void VolumeRaycaster::render() {
glm::mat4 modelViewProjectionMatrix = sgct::Engine::instance()->getActiveModelViewProjectionMatrix();
_FBOProgram->setUniform("modelViewProjection", modelViewProjectionMatrix);
void keyCallback(int key, int action) {
switch( key ) {
case GLFW_KEY_UP:
case 'W':
_stepSize += 0.01;
std::cout << "Stepsize: " << _stepSize << std::endl;
break;
// ------ DRAW TO FBO -------------------
_sgctFBO = FramebufferObject::getActiveObject(); // Save SGCTs main FBO
_fbo->activate();
_FBOProgram->activate();
case GLFW_KEY_DOWN:
case 'S':
if (_stepSize > 0.015)
_stepSize -= 0.01;
// Draw backface
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glClearColor(0.2f, 0.2f, 0.2f, 0);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
myBox->draw();
glDisable(GL_CULL_FACE);
// 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
_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);
glBindVertexArray(vertexArray);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
_screenProgram->deactivate();
std::cout << "Stepsize: " << _stepSize << std::endl;
break;
}
}
void VolumeRaycaster::createVolumetexture(const char *filename, int dimensions[3]) {
// Make sure that the texture is not used
if(glIsTexture(_volumeTexture))
glDeleteTextures(1, &_volumeTexture);
void VolumeRaycaster::render() {
float speed = 50.0f;
curr_time.setVal(sgct::Engine::getTime());
glm::mat4 scene_mat = glm::rotate( glm::mat4(1.0f), static_cast<float>( curr_time.getVal() ) * speed, glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 modelViewProjectionMatrix = sgct::Engine::instance()->getActiveModelViewProjectionMatrix() * scene_mat;
int size = dimensions[0]*dimensions[1]*dimensions[2];
//// ------ TWO PASS ----------------------
//// ------ DRAW TO FBO -------------------
// _sgctFBO = FramebufferObject::getActiveObject(); // Save SGCTs main FBO
// _fbo->activate();
// _fboProgram->activate();
// _fboProgram->setUniform("modelViewProjection", modelViewProjectionMatrix);
//
//// Draw backface
// glDrawBuffer(GL_COLOR_ATTACHMENT0);
// glClearColor(0.2f, 0.2f, 0.2f, 0);
// glClear(GL_COLOR_BUFFER_BIT);
// glEnable(GL_CULL_FACE);
// glCullFace(GL_FRONT);
// myBox->draw();
// glDisable(GL_CULL_FACE);
//
//// 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
// _twopassProgram->activate();
// _twopassProgram->setUniform("stepSize", _stepSize);
//
//// Set textures
// glActiveTexture(GL_TEXTURE0);
// _backTexture->bind();
// glActiveTexture(GL_TEXTURE1);
// _frontTexture->bind();
// glActiveTexture(GL_TEXTURE2);
// _volume->bind();
//
//// Draw screenquad
// glClearColor(0.2f, 0.2f, 0.2f, 0);
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glBindVertexArray(vertexArray);
// glDrawArrays(GL_TRIANGLES, 0, 6);
// glBindVertexArray(0);
//
// _twopassProgram->deactivate();
// ------ SINGLE PASS -------------------
glm::mat4 modelView = sgct::Engine::instance()->getActiveModelViewMatrix();
glm::vec3 eyePos = *sgct::Engine::instance()->getUserPtr()->getPosPtr();
_singlepassProgram->setUniform("modelViewProjection", modelViewProjectionMatrix);
_singlepassProgram->setUniform("Modelview", modelView);
_singlepassProgram->setUniform("RayOrigin", glm::transpose(modelView)*glm::vec4(eyePos, 1.0));
_singlepassProgram->setUniform("ProjectionMatrix", sgct::Engine::instance()->getActiveProjectionMatrix());
_singlepassProgram->setUniform("ViewMatrix", sgct::Engine::instance()->getActiveViewMatrix());
CubeCenterVbo = CreatePointVbo(0, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, CubeCenterVbo);
GLuint SlotPosition = 5;
glEnableVertexAttribArray(SlotPosition);
glVertexAttribPointer(SlotPosition, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glEnableVertexAttribArray(SlotPosition);
glClearColor(0.2f, 0.2f, 0.2f, 0);
glClear(GL_COLOR_BUFFER_BIT);
_singlepassProgram->activate();
glActiveTexture(GL_TEXTURE2);
_volume->bind();
glDrawArrays(GL_POINTS, 0, 1);
_singlepassProgram->deactivate();
}
Texture* VolumeRaycaster::createVolumetexture(const char *filename, glm::ivec3 dimensions) {
int size = dimensions.x*dimensions.y*dimensions.z;
GLubyte *data = new GLubyte[size];
if( FILE *fin = fopen(filename, "rb") ){
fread(data, sizeof(unsigned char), size, fin);
fclose(fin);
fread(data, sizeof(unsigned char), size, fin);
fclose(fin);
} else {
fprintf( stderr, "Could not open file '%s'\n", filename );
}
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);
Texture* texture = new Texture(data, glm::size3_t(dimensions),
Texture::Format::Red, GL_R8, GL_UNSIGNED_BYTE,
Texture::FilterMode::Linear, Texture::WrappingMode::ClampToBorder);
texture->uploadTexture();
delete []data;
std::cout << "Volume texture created" << std::endl;
return texture;
}
}// namespace openspace
+4 -4
View File
@@ -19,19 +19,19 @@ public:
void render();
private:
void createVolumetexture(const char *filename, int dimensions[3]);
Texture* createVolumetexture(const char *filename, glm::ivec3 dimensions);
FramebufferObject* _fbo;
Texture* _backTexture;
Texture* _frontTexture;
Texture* _volume;
GLuint _volumeTexture;
GLuint _sgctFBO;
ProgramObject* _FBOProgram;
ProgramObject* _screenProgram;
ProgramObject *_fboProgram, *_twopassProgram, *_singlepassProgram;
sgct_utils::SGCTBox* myBox;
};
} // namespace openspace