Commit f5c7e003 authored by Taddeüs Kroes's avatar Taddeüs Kroes

- Added graphics assignment 8.

 - Added last modifications to graphics assignment 7.
parent 20795120
...@@ -217,8 +217,9 @@ intersect_node(bvh_node *node, intersection_point *ip, ...@@ -217,8 +217,9 @@ intersect_node(bvh_node *node, intersection_point *ip,
} }
else else
{ {
// Leaf node, find shortest triangle and check if it is closer than the // Leaf node, find the shortest triangle in the leaf and check if it is
// current closest intersection // closer to the origin than the current closest intersection. If so,
// make it the new closest intersection.
triangle *triangles = leaf_node_triangles(node); triangle *triangles = leaf_node_triangles(node);
intersection_point ip2; intersection_point ip2;
...@@ -253,13 +254,6 @@ find_first_intersected_bvh_triangle(intersection_point* ip, ...@@ -253,13 +254,6 @@ find_first_intersected_bvh_triangle(intersection_point* ip,
ip->t = C_INFINITY; ip->t = C_INFINITY;
// If the root has no intersection, none of the BVH nodes does // If the root has no intersection, none of the BVH nodes does
//
// Note that this step if mkes the program less efficient when the root's
// bounding box has a relatively large surface in the camera screen (has
// lot of ray intersections). This is because every ray intersecting a
// triangle is now tested one time more and every non-intersection ray is
// tested one time less. So, when raytracing large objects, omitting this
// step would be advisable.
if( !bbox_intersect(&t0, &t1, bvh_root->bbox, ray_origin, if( !bbox_intersect(&t0, &t1, bvh_root->bbox, ray_origin,
ray_direction, 0.0, C_INFINITY) ) ray_direction, 0.0, C_INFINITY) )
{ {
......
/* Computer Graphics, Assignment, Ray-tracing 2 /* Computer Graphics, Assignment, Ray-tracing 2
* *
* Student name .... * Student name .... Sander van Veen & Taddeus Kroes
* Student email ... * Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
* Collegekaart .... * Collegekaart .... 6167969 & 6054129
* Date ............ * Date ............ 07.11.2010
* Comments ........
*
*
* (always fill in these fields before submitting!!)
*/ */
#include <sys/time.h> #include <sys/time.h>
...@@ -160,7 +156,7 @@ ray_trace(void) ...@@ -160,7 +156,7 @@ ray_trace(void)
vec3 forward_vector, right_vector, up_vector; vec3 forward_vector, right_vector, up_vector;
int i, j, k, l; int i, j, k, l;
vec3 right_step, down_step; vec3 right_step, down_step;
float image_plane_width, image_plane_height, diff[2] = {0.25, 0.75}; float image_plane_width, image_plane_height, pixel_diff[2] = {0.25, 0.75};
vec3 image_plane_topleft, image_plane_point; vec3 image_plane_topleft, image_plane_point;
vec3 ray_direction; vec3 ray_direction;
vec3 color; vec3 color;
...@@ -203,26 +199,34 @@ ray_trace(void) ...@@ -203,26 +199,34 @@ ray_trace(void)
{ {
for (i = 0; i < framebuffer_width; i++) for (i = 0; i < framebuffer_width; i++)
{ {
if( do_antialiasing) if( do_antialiasing )
{ {
color.x = color.y = color.z = 0; // Anti-aliasing is on, shoot 4 rays through each point and use the average
color.x = color.y = color.z = 0.0;
for( k = 0; k < 2; k++ ) for( k = 0; k < 2; k++ )
{ {
for( l = 0; l < 2; l++ ) for( l = 0; l < 2; l++ )
{ {
// Compute corresponding point on image plane // Compute corresponding point corner on image plane
image_plane_point = v3_add(image_plane_topleft, v3_multiply(right_step, i+diff[k])); image_plane_point = v3_add(
image_plane_point = v3_add(image_plane_point, v3_multiply(down_step, j+diff[l])); image_plane_topleft,
v3_multiply(right_step, i+pixel_diff[k])
);
image_plane_point = v3_add(
image_plane_point,
v3_multiply(down_step, j+pixel_diff[l])
);
// Compute direction for shooting the ray // Compute direction for shooting the ray
ray_direction = v3_subtract(image_plane_point, scene_camera_position); ray_direction = v3_subtract(image_plane_point, scene_camera_position);
// Determine ray color // Add ray color for this corner to the current color
color = v3_add(color, ray_color(0, scene_camera_position, ray_direction)); color = v3_add(color, ray_color(0, scene_camera_position, ray_direction));
} }
} }
// Divide by 4 to get the average of all corners, this is the point color
color = v3_multiply(color, 0.25); color = v3_multiply(color, 0.25);
} }
else else
......
CC=gcc
WARNING_FLAGS=-Wall -Wextra -Werror-implicit-function-declaration -Wshadow -Wstrict-prototypes -pedantic-errors
CFLAGS=-g -O2 -std=c99 $(WARNING_FLAGS)
LDFLAGS=-g -lGL -lglut -lGLU
.c.o:
$(CC) -c $(CFLAGS) $<
all: main
main: main.o volume.o
$(CC) $(LDFLAGS) -o main main.o volume.o
clean:
rm -f *.o
rm -f main
volume.o : volume.h
main.o : volume.h main.c
volume.o : volume.h volume.c
/* Computer Graphics, Assignment, Volume rendering with cubes/points
*
* Filename ........ main.c
* Description ..... Creates OpenGL window and draws the scene.
* Date ............ 29.10.2008
* Created by ...... Paul Melis
*
* Student name ....
* Student email ...
* Collegekaart ....
* Date ............
* Comments ........
*
*
* (always fill in these fields before submitting!!)
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#include "volume.h"
#include "v3math.h"
int display_mode=0; /* 0 = points, 1 = cubes */
int use_arrays=0;
unsigned char isovalue=128;
unsigned char epsilon=0;
int window;
int mouse_mode=0;
int mx, my;
float camDistance=100.0;
float camRotZ=45.0, camAzimuth=20.0;
float saved_camRotZ, saved_camAzimuth, saved_camDistance;
int regenerate_arrays=1;
int entered_number=0;
int display_fps_counter=0;
int backface_culling=0;
int show_normals=0;
#define MAX_VERTICES_IN_ARRAY 5000000
int num_vertices_in_array=0;
float vertices[3*MAX_VERTICES_IN_ARRAY];
float normals[3*MAX_VERTICES_IN_ARRAY];
void SetupCamera(void);
void DrawVolumeAxes(void);
void DrawVolumeUsingCurrentDisplayMode(void);
#define TIMER_FRAMERATE 15
#define POINT_SIZE 1.0
int timer = TIMER_FRAMERATE + 1;
struct timeval start, end;
float x_center = 0.0, y_center = 0.0, z_center = 0.0;
float normal_x_size = 0.0, normal_y_size = 0.0;
/* Draw the selected iso-value (range) using GL_POINTS */
void DrawVolumeAsPoints(void)
{
int x, y, z;
char value;
if( x_center == 0.0 || y_center == 0.0 || z_center == 0.0 )
{
x_center = .5 * sizex;
y_center = .5 * sizey;
z_center = .5 * sizez;
}
glBegin(GL_POINTS);
for( x = 0; x < nx; x++ )
for( y = 0; y < ny; y++ )
for( z = 0; z < nz; z++ )
if( (value = volume[voxel2idx(x, y, z)]) >= isovalue - epsilon
&& value <= isovalue + epsilon )
glVertex3f(x + x_center, y + y_center, z + z_center);
glEnd();
}
/* Draw the selected iso-value (range) using glutSolidCube()'s */
void DrawVolumeAsCubes(void)
{
int x, y, z;
char value;
if( x_center == 0.0 || y_center == 0.0 || z_center == 0.0 )
{
x_center = .5 * sizex;
y_center = .5 * sizey;
z_center = .5 * sizez;
}
for( x = 0; x < nx; x++ )
{
for( y = 0; y < ny; y++ )
{
for( z = 0; z < nz; z++ )
{
if( (value = volume[voxel2idx(x, y, z)]) >= isovalue - epsilon
&& value <= isovalue + epsilon )
{
glPushMatrix();
glTranslatef(x + x_center, y + y_center, z + z_center);
glScalef(sizex, sizey, sizez);
glutSolidCube(1.0);
glPopMatrix();
}
}
}
}
}
/* Fill the vertex array based on the current iso-value range,
so the array can be drawn as GL_POINTS, with one point per voxel
to be shown.
Be sure to set num_vertices_in_array.
*/
void
addVertex(int *index, float x, float y, float z)
{
vertices[(*index)++] = x;
vertices[(*index)++] = y;
vertices[(*index)++] = z;
num_vertices_in_array++;
}
void
addNormal(int index, float x, float y, float z)
{
//normals[index++] = (float)x;
//normals[index++] = (float)y;
//normals[index] = (float)z;
normals[index++] = x;
normals[index++] = y;
normals[index] = z;
}
void
addQuadX(int *index, float x, float y, float z,
float w, float h, float normal_x)
{
addNormal(*index, normal_x, 0, 0);
//addNormal(*index, normal_x, -1, -1);
addVertex(index, x, y, z);
addNormal(*index, normal_x, 0, 0);
//addNormal(*index, normal_x, 1, -1);
addVertex(index, x, y + w, z);
addNormal(*index, normal_x, 0, 0);
//addNormal(*index, normal_x, 1, 1);
addVertex(index, x, y + w, z + h);
addNormal(*index, normal_x, 0, 0);
//addNormal(*index, normal_x, -1, 1);
addVertex(index, x, y, z + h);
}
void
addQuadY(int *index, float x, float y, float z,
float w, float h, float normal_y)
{
addNormal(*index, 0, normal_y, 0);
//addNormal(*index, -1, normal_y, -1);
addVertex(index, x, y, z);
addNormal(*index, 0, normal_y, 0);
//addNormal(*index, 1, normal_y, -1);
addVertex(index, x + w, y, z);
addNormal(*index, 0, normal_y, 0);
//addNormal(*index, 1, normal_y, 1);
addVertex(index, x + w, y, z + h);
addNormal(*index, 0, normal_y, 0);
//addNormal(*index, -1, normal_y, 1);
addVertex(index, x, y, z + h);
}
void
addQuadZ(int *index, float x, float y, float z,
float w, float h, float normal_z)
{
addNormal(*index, 0, 0, normal_z);
//addNormal(*index, -1, -1, normal_z);
addVertex(index, x, y, z);
addNormal(*index, 0, 0, normal_z);
//addNormal(*index, -1, 1, normal_z);
addVertex(index, x, y + h, z);
addNormal(*index, 0, 0, normal_z);
//addNormal(*index, 1, 1, normal_z);
addVertex(index, x + w, y + h, z);
addNormal(*index, 0, 0, normal_z);
//addNormal(*index, 1, -1, normal_z);
addVertex(index, x + w, y, z);
}
void FillArrayWithPoints(void)
{
int x, y, z, index;
char value;
if( x_center == 0.0 || y_center == 0.0 || z_center == 0.0 )
{
x_center = .5 * sizex;
y_center = .5 * sizey;
z_center = .5 * sizez;
}
num_vertices_in_array = index = 0;
for( x = 0; x < nx; x++ )
{
for( y = 0; y < ny; y++ )
{
for( z = 0; z < nz; z++ )
{
if( (value = volume[voxel2idx(x, y, z)]) >= isovalue - epsilon
&& value <= isovalue + epsilon )
{
addVertex(&index, x + x_center, y + y_center, z + z_center);
}
}
}
}
}
/* Fill the vertex and normal arrays based on the current iso-value range,
so the arrays can be drawn as GL_QUADS, with one cube per voxel
to be shown (and six quads per cube).
Be sure to set num_vertices_in_array.
*/
void FillArrayWithCubes(void)
{
int x, y, z, index;
char value;
if( normal_x_size == 0.0 || normal_y_size == 0.0 )
{
normal_x_size = sizez / sizex;
normal_y_size = sizez / sizey;
}
num_vertices_in_array = index = 0;
for( x = 0; x < nx; x++ )
{
for( y = 0; y < ny; y++ )
{
for( z = 0; z < nz; z++ )
{
if( (value = volume[voxel2idx(x, y, z)]) >= isovalue - epsilon
&& value <= isovalue + epsilon )
{
addQuadX(&index, x, y, z, sizey, sizez, -normal_x_size);
addQuadY(&index, x, y, z, sizex, sizez, -normal_y_size);
addQuadZ(&index, x, y, z, sizex, sizey, -1.0);
addQuadX(&index, x + sizex, y, z, sizey, sizez, normal_x_size);
addQuadY(&index, x, y + sizey, z, sizex, sizez, normal_y_size);
addQuadZ(&index, x, y, z + sizez, sizex, sizey, 1.0);
}
}
}
}
}
void
reset_timer(void)
{
gettimeofday(&start, NULL);
timer = TIMER_FRAMERATE + 1;
}
void DrawScene(void)
{
/* clear the draw buffer */
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
/* set the model-view matrix */
SetupCamera();
/* draw an outline of where the volume resides */
DrawVolumeAxes();
/* draw the volume in the chosen mode */
DrawVolumeUsingCurrentDisplayMode();
glFinish();
if( display_fps_counter )
{
if( timer == TIMER_FRAMERATE )
{
gettimeofday(&end, NULL);
printf("Framerate: %.0f \n", round(TIMER_FRAMERATE / (double)(
end.tv_sec - start.tv_sec
+ (end.tv_usec - start.tv_usec) * 0.000001
)));
fflush(stdout);
}
timer = (timer + 1) % (TIMER_FRAMERATE + 1);
}
if( display_fps_counter && !timer )
gettimeofday(&start, NULL);
/* finally, swap the draw buffers to make the frame appear on screen */
glutSwapBuffers();
}
/* Draw a set of colored X, Y and Z axes that match the size (and location)
of the volume, so we can see where output should appear */
void
DrawVolumeAxes(void)
{
glPushAttrib(GL_LIGHTING_BIT);
glDisable(GL_LIGHTING);
glBegin(GL_LINES);
glColor3f(1, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(nx*sizex, 0, 0);
glColor3f(0, 1, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, ny*sizey, 0);
glColor3f(0, 0, 1);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, nz*sizez);
if( show_normals )
{
glColor3f(0, 0, 0);
for( int x = 0, y = 0; x < num_vertices_in_array; x++, y += 3 )
{
glVertex3f(vertices[y], vertices[y+1], vertices[y+2]);
glVertex3f(vertices[y] + normals[y], vertices[y+1] + normals[y+1], vertices[y+2] + normals[y+2]);
}
}
glEnd();
glPopAttrib();
}
void DrawVolumeUsingCurrentDisplayMode(void)
{
if (use_arrays)
{
if (regenerate_arrays == 1)
{
printf("Filling vertex/normal arrays... ");
fflush(stdout);
switch (display_mode)
{
case 0:
FillArrayWithPoints();
break;
case 1:
FillArrayWithCubes();
break;
}
printf("done, %d array vertices used (1 per point, 4 per quad)\n", num_vertices_in_array);
regenerate_arrays = 0;
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
if (display_mode > 0)
{
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, normals);
}
}
glColor3f(0.6, 0.0, 0.0);
if (display_mode == 0)
glDisable(GL_LIGHTING);
else
glEnable(GL_LIGHTING);
if (display_mode == 0)
{
/* points */
glPointSize(POINT_SIZE);
if (use_arrays)
glDrawArrays(GL_POINTS, 0, num_vertices_in_array);
else
DrawVolumeAsPoints();
}
else if (display_mode == 1)
{
/* cubes */
if (use_arrays)
glDrawArrays(GL_QUADS, 0, num_vertices_in_array);
else
{
glEnable(GL_RESCALE_NORMAL);
DrawVolumeAsCubes();
glDisable(GL_RESCALE_NORMAL);
}
}
if (use_arrays)
{
glDisableClientState(GL_VERTEX_ARRAY);
if (display_mode > 0)
glDisableClientState(GL_NORMAL_ARRAY);
}
}
void SetupCamera(void)
{
GLfloat light_position[4];
glLoadIdentity();
// Verbose, but straightforward way, of positioning the camera and lightsource.
// Assume the camera's final position is (cx, cy, cz).
// Start with c being (camDistance, 0, 0)
// First rotate around Y, then around Z.
// Now we have c at the given distance from the origin, with specified rotation angles.
float cx, cy, cz;
float t;
float beta, gamma;
// degrees -> radians
beta = camAzimuth / 180.0 * 3.1415926535;
gamma = camRotZ / 180.0 * 3.1415926535;
cx = camDistance;
cy = cz = 0.0;
// Rotate around Y
t = cx;
cx = cx * cos(beta) - cz * sin(beta);
cz = t * sin(beta) + cz * cos(beta);
// Rotate around Z
t = cx;
cx = cx * cos(gamma) + cy * sin(gamma);
cy = -t * sin(gamma) + cy * cos(gamma);
gluLookAt (cx, cy, cz, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
// Finally, translate because the lookat point is at the center of the volume.
glTranslatef(-0.5*nx*sizex, -0.5*ny*sizey, -0.5*nz*sizez);
// Place the light source at the camera position (head light)
light_position[0] = cx + 0.5*nx*sizex;
light_position[1] = cy + 0.5*ny*sizey;
light_position[2] = cz + 0.5*nz*sizez;
light_position[3] = 1.0;
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
}
void InitOpenGL(void)
{
GLfloat light_ambient[] = { 0.4, 0.4, 0.4, 0.0 };
GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 };
GLfloat mat_no_specular[] = { 0.0, 0.0, 0.0, 1.0 };
glClearColor(0.7, 0.7, 1, 1);
glEnable(GL_COLOR_MATERIAL);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_no_specular);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glShadeModel(GL_FLAT);
//glShadeModel(GL_SMOOTH);
}
void ReSizeScene(int Width, int Height)
{
if (Height==0)
Height=1;
glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height, 0.1f, 10000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity ();
}
void keyPressed(unsigned char key, int x, int y)
{
int redraw=0;
/* keep gcc happy, as we don't use these parameters */
(void)x;
(void)y;
switch (key)
{
case 'q':
exit(-1);
break;
case 'n':
show_normals = 1 - show_normals;
break;
case 'b':
backface_culling = 1 - backface_culling;
if (backface_culling)
{
glEnable(GL_CULL_FACE);
printf("Backface culling is now enabled\n");
}
else
{
glDisable(GL_CULL_FACE);
printf("Backface culling is now disabled\n");
}
glutPostRedisplay();
break;
case 'p':
/* switch to points mode */
display_mode = 0;
redraw = 1;
break;
case 'c':
/* switch to cubes mode */
display_mode = 1;
redraw = 1;
break;
case '[':
/* decrease isovalue */
{
int newvalue = isovalue-10;
if (newvalue < 0)
isovalue = 0;
else
isovalue = newvalue;
}
printf("Setting isovalue to %d\n", isovalue);
redraw = 1;
break;
case ']':
/* increase isovalue */
{
int newvalue = isovalue+10;
if (newvalue > 255)
isovalue = 255;
else
isovalue = newvalue;
}
printf("Setting isovalue to %d\n", isovalue);
redraw = 1;
break;
/* handle isovalue/epsilon entered by number */
case '0':
entered_number = entered_number*10;
break;
case '1':
entered_number = entered_number*10 + 1;
break;
case '2':
entered_number = entered_number*10 + 2;
break;
case '3':
entered_number = entered_number*10 + 3;
break;
case '4':
entered_number = entered_number*10 + 4;
break;
case '5':
entered_number = entered_number*10 + 5;
break;
case '6':
entered_number = entered_number*10 + 6;
break;
case '7':
entered_number = entered_number*10 + 7;
break;
case '8':
entered_number = entered_number*10 + 8;
break;
case '9':
entered_number = entered_number*10 + 9;
break;
case 'i':
/* update isovalue with number entered */
isovalue = entered_number % 256;
entered_number = 0;
printf("Setting isovalue to %d\n", isovalue);
redraw = 1;
break;
case '{':
/* decrease epsilon */
{
int newvalue = epsilon - 2;
if (newvalue < 0)
epsilon = 0;
else
epsilon = newvalue;
}
printf("Setting epsilon to %d\n", epsilon);
redraw = 1;
break;
case '}':
/* increase epsilon */
{
int newvalue = epsilon + 2;
if (newvalue > 255)
epsilon = 255;
else
epsilon = newvalue;
}
printf("Setting epsilon to %d\n", epsilon);
redraw = 1;
break;
case 'e':
/* update epsilon with number entered */
epsilon = entered_number % 256;
entered_number = 0;
printf("Setting epsilon to %d\n", epsilon);
redraw = 1;
break;
case 'f':
/* enable/display FPS counter display */
display_fps_counter = 1 - display_fps_counter;
break;
case 'a':
use_arrays = 1 - use_arrays;
if (use_arrays)
printf("Now using arrays\n");
else
printf("Stopped using arrays\n");
glutPostRedisplay();
break;
}
reset_timer();
if (redraw)
{
regenerate_arrays = 1;
glutPostRedisplay();
}
}
void specialKeyPressed(int key, int x, int y)
{
/* keep gcc happy, as we don't use these parameters */
(void)key;
(void)x;
(void)y;
}
static void
mouseFunc(int button, int state, int x, int y)
{
// guard against both left and right buttons being pressed at the same time,
// by only responding when a mouse button is pressed while another one
// hasn't been pressed yet
if (state == GLUT_DOWN && mouse_mode == 0)
{
if (button == GLUT_LEFT_BUTTON)
{
mouse_mode = GLUT_LEFT_BUTTON;
saved_camRotZ = camRotZ;
saved_camAzimuth = camAzimuth;
mx = x;
my = y;
}
else if (button == GLUT_RIGHT_BUTTON)
{
mouse_mode = GLUT_RIGHT_BUTTON;
saved_camDistance = camDistance;
my = y;
}
}
else if (state == GLUT_UP && button == mouse_mode)
{
// pressed button released
mouse_mode = 0;
}
}
static void
motionFunc(int x, int y)
{
int dx, dy;
if (mouse_mode == GLUT_LEFT_BUTTON)
{
dx = mx - x;
dy = my - y;
camRotZ = saved_camRotZ - dx * 0.25;
camAzimuth = saved_camAzimuth - dy * 0.25;
if (camAzimuth > 89.99)
camAzimuth = 89.99;
else if (camAzimuth < -89.99)
camAzimuth = -89.99;
}
else if (mouse_mode == GLUT_RIGHT_BUTTON)
{
dy = my - y;
camDistance = saved_camDistance - dy * sizex;
if (camDistance < 0.01)
camDistance = 0.01;
}
}
static void
initialize_volume(const char *fname, unsigned char iso)
{
read_volume(fname);
isovalue = iso;
if (epsilon > 0)
printf("Iso-value = %d (+/- %d)\n", isovalue, epsilon);
else
printf("Iso-value = %d\n", isovalue);
// Initial distance from camera position to center of volume
camDistance = 2.0 * nx * sizex;
}
int
main(int argc, char **argv)
{
glutInit(&argc, argv);
if (argc != 3)
{
printf("usage: %s datafile isovalue\n", argv[0]);
exit(0);
}
initialize_volume(argv[1], atoi(argv[2]));
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutInitWindowPosition(0, 0);
window = glutCreateWindow("OpenGL Framework");
glutDisplayFunc(&DrawScene);
glutIdleFunc(&DrawScene);
glutReshapeFunc(&ReSizeScene);
glutSpecialFunc(&specialKeyPressed);
glutKeyboardFunc(&keyPressed);
glutMouseFunc(&mouseFunc);
glutMotionFunc(&motionFunc);
InitOpenGL();
glutMainLoop();
return 1;
}
#ifndef V3MATH_H
#define V3MATH_H
#include <math.h>
typedef struct
{
float x, y, z;
}
vec3;
// Create a new 3-vector of floats
static inline vec3
v3_create(float x, float y, float z)
{
vec3 res;
res.x = x;
res.y = y;
res.z = z;
return res;
}
// Return -a
static inline vec3
v3_negate(vec3 a)
{
vec3 res;
res.x = - a.x;
res.y = - a.y;
res.z = - a.z;
return res;
}
// Return a + b
static inline vec3
v3_add(vec3 a,vec3 b)
{
vec3 res;
res.x = a.x+b.x;
res.y = a.y+b.y;
res.z = a.z+b.z;
return res;
}
// Return a - b
static inline vec3
v3_subtract(vec3 a, vec3 b)
{
vec3 res;
res.x = a.x-b.x;
res.y = a.y-b.y;
res.z = a.z-b.z;
return res;
}
// Return a / |a|
static inline vec3
v3_normalize(vec3 a)
{
vec3 res;
double l = sqrt(a.x*a.x + a.y*a.y + a.z*a.z);
res = a;
res.x /= l;
res.y /= l;
res.z /= l;
return res;
}
// Return a ^ b
static inline vec3
v3_crossprod(vec3 a, vec3 b)
{
vec3 res;
res.x = a.y*b.z - a.z*b.y;
res.y = a.z*b.x - a.x*b.z;
res.z = a.x*b.y - a.y*b.x;
return res;
}
// Return a * b
static inline float
v3_dotprod(vec3 a, vec3 b)
{
return a.x*b.x + a.y*b.y + a.z*b.z;
}
// Return a*s
static inline vec3
v3_multiply(vec3 a, float s)
{
vec3 res;
res.x = a.x*s;
res.y = a.y*s;
res.z = a.z*s;
return res;
}
// Return |a|
static inline float
v3_length(vec3 a)
{
return sqrt(a.x*a.x + a.y*a.y + a.z*a.z);
}
// Return the i-th component of a, i.e. for i=0
// this returns a.x
static inline float
v3_component(vec3 a, int i)
{
if (i == 0)
return a.x;
else if (i == 1)
return a.y;
else
return a.z;
}
// Set the i-th component of a to v
static inline vec3
v3_set_component(vec3 a, int i, float v)
{
vec3 res = a;
if (i == 0)
res.x = v;
else if (i == 1)
res.y = v;
else
res.z = v;
return res;
}
#endif
/* Computer Graphics, Assignment, Volume rendering with cubes/points
*
* Description ..... Creates OpenGL window and draws the scene.
* Date ............ 29.10.2008
* Created by ...... Paul Melis
*
* Student name ....
* Student email ...
* Collegekaart ....
* Date ............
* Comments ........
*
*
* (always fill in these fields before submitting!!)
*/
#include <stdio.h>
#include <stdlib.h>
#include "volume.h"
/* The voxels of the volume dataset, stored as a one-dimensional array */
unsigned char *volume;
/* The dimensions of the volume dataset */
int nx, ny, nz;
/* The size of a voxel */
float sizex, sizey, sizez;
/* Utility function to convert the index of a voxel
into an index in the volume array above */
int
voxel2idx(int i, int j, int k)
{
return (k*ny + j)*nx + i;
}
/* Utility function to read a volume dataset from a VTK file.
This will store the data in the "volume" array and update the dimension
and size values. */
void
read_volume(const char *fname)
{
FILE *f;
char s[256];
unsigned int nvoxels;
printf("Reading %s\n", fname);
f = fopen(fname, "rb");
if (!f)
{
fprintf(stderr, "read_volume(): Could not open file '%s' for reading!\n", fname);
exit(-1);
}
// header line
fgets(s, 255, f);
// comment line
fgets(s, 255, f);
// BINARY
fgets(s, 255, f);
// DATASET STRUCTURED_POINTS
fgets(s, 255, f);
// DIMENSIONS %d %d %d
fscanf(f, "%s %d %d %d\n", s, &nx, &ny, &nz);
printf("%d x %d x %d voxels\n", nx, ny, nz);
// ASPECT_RATIO/SPACING %f %f %f
fscanf(f, "%s %f %f %f\n", s, &sizex, &sizey, &sizez);
printf("voxel sizes: %.3f, %.3f, %.3f\n", sizex, sizey, sizez);
// ORIGIN ...
fgets(s, 255, f);
// POINT_DATA ...
fgets(s, 255, f);
// SCALARS ...
fgets(s, 255, f);
// LOOKUP_TABLE ...
fgets(s, 255, f);
// allocate memory to hold the volume data and read it from file
nvoxels = nx * ny * nz;
volume = (unsigned char*)malloc(nvoxels);
if (fread(volume, 1, nvoxels, f) < nvoxels)
{
printf("WARNING: not all data could be read!\n");
}
fclose(f);
}
#ifndef VOLUME_H
#define VOLUME_H
/* The data points in the volume dataset, stored as a one-dimensional array */
extern unsigned char *volume;
/* The dimensions of the volume dataset in number of voxels in each
dimension*/
extern int nx, ny, nz;
/* The size of a voxel for each dimension */
extern float sizex, sizey, sizez;
/* Utility function to convert the index of a datapoint
into an index in the volume array above */
int voxel2idx(int i, int j, int k);
/* Utility function to read a volume dataset from a file.
This will store the data in the "volume" array and update the dimension
and size values. */
void read_volume(const char *fname);
#endif
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
\usepackage{float} \usepackage{float}
\usepackage[dutch]{babel} \usepackage[dutch]{babel}
\usepackage{listings}
\lstset{ \lstset{
language=C, language=C,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment