Skip to content
Snippets Groups Projects
Commit 7e4cf888 authored by Sander van Veen's avatar Sander van Veen
Browse files

Added subject 'graphics' and 'operating systems'.

Graphics include the following assignments:
 - ass1
 - ass2
 - ass4
 - ass6

Operating systems include the following assignments:
 - ass1
 - ass2
parent 16673a76
No related branches found
No related tags found
No related merge requests found
Showing
with 1397 additions and 0 deletions
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
.c.o:
$(CC) -c $(CFLAGS) $<
all: trirast
trirast: main.o trirast.o
$(CC) $(LDFLAGS) -o trirast main.o trirast.o
clean:
rm -f *.o
rm -f trirast
trirast.o : types.h trirast.c
types.o : types.h
main.o : triangles.h trirast.h types.h main.c
triangles.o : triangles.h triangles.h
trirast.o : types.h trirast.h
File added
/* Computer Graphics, Assignment, Triangle Rasterization
*
* Date ............ 28.07.2008
* Created by ...... Paul Melis
*/
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "types.h"
#include "trirast.h"
#include "triangles.h"
// Number of drawable pixels, i.e. x coordinates passed to PutPixel()
// should be in the range [0, framebuffer_width[. Analogous for y.
// (These values must both be a power of 2)
const int framebuffer_width = 128;
const int framebuffer_height = 64;
const int zoomed_pixel_size = 7;
int screen_width, screen_height;
int draw_optimized = 0;
int zoom = 1;
int scene = 1;
int draw_corners = 0;
int color_by_putpixel_count = 0;
byte *framebuffer;
void
InitOpenGL(void)
{
// Set the background color
glClearColor(0., 0., 0., 0.);
// Allocate a framebuffer, to be filled during triangle rasterization
framebuffer = (byte*)malloc(framebuffer_width*framebuffer_height*3);
// Setup texturing state (as we display the rasterization framebuffer
// using a textured quad)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE);
}
void PutPixel(int x, int y, byte r, byte g, byte b)
{
if (x < 0 || y < 0 || x >= framebuffer_width || y >= framebuffer_height)
{
printf("PutPixel(): x, y coordinates (%d, %d) outside of visible area!\n",
x, y);
return;
}
// The pixels in framebuffer[] are layed out sequentially,
// with the R, G and B values one after the other, e.g
// RGBRGBRGB...
framebuffer[3*(framebuffer_width*y+x)] = r;
framebuffer[3*(framebuffer_width*y+x)+1] = g;
framebuffer[3*(framebuffer_width*y+x)+2] = b;
}
void
DrawTriangles(void)
{
struct triangle tri;
for (unsigned int t = 0; t < sizeof(triangles)/sizeof(struct triangle); t++)
{
tri = triangles[t];
if (draw_optimized)
{
/* draw the triangle with the given color */
draw_triangle_optimized(
vertices[tri.i].x, vertices[tri.i].y,
vertices[tri.j].x, vertices[tri.j].y,
vertices[tri.k].x, vertices[tri.k].y,
colors[tri.c].r, colors[tri.c].g, colors[tri.c].b);
}
else
{
/* draw the triangle with the given color */
draw_triangle(
vertices[tri.i].x, vertices[tri.i].y,
vertices[tri.j].x, vertices[tri.j].y,
vertices[tri.k].x, vertices[tri.k].y,
colors[tri.c].r, colors[tri.c].g, colors[tri.c].b);
}
if (draw_corners)
{
PutPixel(vertices[tri.i].x, vertices[tri.i].y, 255, 255, 255);
PutPixel(vertices[tri.j].x, vertices[tri.j].y, 255, 255, 255);
PutPixel(vertices[tri.k].x, vertices[tri.k].y, 255, 255, 255);
}
}
}
void
DrawTrianglesOpenGL(void)
{
struct triangle tri;
glDisable(GL_TEXTURE_2D);
glBegin(GL_TRIANGLES);
for (unsigned int t = 0; t < sizeof(triangles)/sizeof(struct triangle); t++)
{
tri = triangles[t];
/* draw the triangle with the given color */
glColor3ub(colors[tri.c].r, colors[tri.c].g, colors[tri.c].b);
glVertex2f(vertices[tri.i].x, vertices[tri.i].y);
glVertex2f(vertices[tri.j].x, vertices[tri.j].y);
glVertex2f(vertices[tri.k].x, vertices[tri.k].y);
}
glEnd();
if (draw_corners)
{
glColor3ub(255, 255, 255);
glBegin(GL_POINTS);
for (unsigned int t = 0; t < sizeof(triangles)/sizeof(struct triangle); t++)
{
tri = triangles[t];
glVertex2f(vertices[tri.i].x, vertices[tri.i].y);
glVertex2f(vertices[tri.j].x, vertices[tri.j].y);
glVertex2f(vertices[tri.k].x, vertices[tri.k].y);
}
glEnd();
}
}
void
TestRasterizationSpeed(void)
{
const int N = 1000;
struct timeval t0, t1;
double diff;
//srand(123456);
gettimeofday(&t0, NULL);
if (draw_optimized)
{
for (int t = 0; t < N; t++)
{
draw_triangle_optimized(
rand()%framebuffer_width, rand()%framebuffer_height,
rand()%framebuffer_width, rand()%framebuffer_height,
rand()%framebuffer_width, rand()%framebuffer_height,
colors[t%6].r, colors[t%6].g, colors[t%6].b);
}
}
else
{
for (int t = 0; t < N; t++)
{
draw_triangle(
rand()%framebuffer_width, rand()%framebuffer_height,
rand()%framebuffer_width, rand()%framebuffer_height,
rand()%framebuffer_width, rand()%framebuffer_height,
colors[t%6].r, colors[t%6].g, colors[t%6].b);
}
}
gettimeofday(&t1, NULL);
/* calculate time used */
diff = t1.tv_sec - t0.tv_sec + (t1.tv_usec - t0.tv_usec)*1.0e-6;
printf("%d triangles in %.6f seconds, %.1f triangles/sec\n", N, diff, N/diff);
}
void
DrawPixels(void)
{
const int N = 1000000;
struct timeval t0, t1;
gettimeofday(&t0, NULL);
srand(123456);
for (int i = 0; i < N; i++)
{
PutPixel(rand()%framebuffer_width, rand()%framebuffer_height,
rand()%255, rand()%255, rand()%255);
}
gettimeofday(&t1, NULL);
/* calculate time used */
double diff = (t1.tv_sec + t1.tv_usec/1000000.0) - (t0.tv_sec + t0.tv_usec/1000000.0);
printf("%d pixels in %.6f seconds, %.1f pixels/sec\n", N, diff, N/diff);
}
void
DrawScene(void)
{
/* clear the draw buffer */
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
// clear the rasterization framebuffer
memset(framebuffer, 0, 3*framebuffer_width*framebuffer_height);
if (scene == 1)
DrawTriangles();
else if (scene == 2)
TestRasterizationSpeed();
else if (scene == 4)
DrawPixels();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if (scene != 9)
{
if (zoom)
glOrtho(0, framebuffer_width, 0, framebuffer_height, -1, 1);
else
glOrtho(0, screen_width, 0, screen_height, -1, 1);
// Draw textured quad
glEnable(GL_TEXTURE_2D);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,
framebuffer_width, framebuffer_height,
0, GL_RGB, GL_UNSIGNED_BYTE, framebuffer);
glColor3f(1, 1, 1);
glBegin(GL_QUADS);
glTexCoord2i(0, 0);
glVertex2i(0, 0);
glTexCoord2i(1, 0);
glVertex2i(framebuffer_width, 0);
glTexCoord2i(1, 1);
glVertex2i(framebuffer_width, framebuffer_height);
glTexCoord2i(0, 1);
glVertex2i(0, framebuffer_height);
glEnd();
}
else
{
if (zoom)
glOrtho(-0.5, framebuffer_width-0.5, -0.5, framebuffer_height-0.5, -1, 1);
else
glOrtho(-0.5, screen_width-0.5, -0.5, screen_height-0.5, -1, 1);
DrawTrianglesOpenGL();
glDisable(GL_TEXTURE_2D);
glColor3f(1, 1, 0);
glBegin(GL_POINTS);
glVertex2i(0, 0);
glVertex2i(framebuffer_width-1, framebuffer_height-1);
glEnd();
}
// finally, swap the draw buffers to make the triangles appear on screen
glutSwapBuffers();
}
void
KeyPressed(unsigned char key, int x, int y)
{
switch (key)
{
case '1':
case '2':
case '3':
case '4':
case '9':
{
scene = key - '0';
glutPostRedisplay();
break;
}
case 'o':
{
draw_optimized = 1 - draw_optimized;
printf("draw_optimized set to %d\n", draw_optimized);
glutPostRedisplay();
break;
}
case 'z':
{
zoom = 1 - zoom;
glutPostRedisplay();
break;
}
case 'd':
{
// debug
color_by_putpixel_count = 1 - color_by_putpixel_count;
printf("color_by_putpixel_count set to %d\n", color_by_putpixel_count);
glutPostRedisplay();
break;
}
case 'c':
{
// triangle corners
draw_corners = 1 - draw_corners;
glutPostRedisplay();
break;
}
case 'q':
exit(0);
}
}
int
main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
screen_width = framebuffer_width * zoomed_pixel_size;
screen_height = framebuffer_height * zoomed_pixel_size;
glutInitWindowSize(screen_width, screen_height);
glutInitWindowPosition(20, 20);
glutCreateWindow("Triangle rasterization");
glutDisplayFunc(&DrawScene);
glutIdleFunc(&DrawScene);
//glutReshapeFunc(&ReSizeScene);
//glutSpecialFunc(&specialKeyPressed);
glutKeyboardFunc(&KeyPressed);
//glutMouseFunc(&mouseFunc);
//glutMotionFunc(&motionFunc);
InitOpenGL();
glutMainLoop();
return 1;
}
File added
// Note: this file is only meant to be #included by main.c
#include "types.h"
struct color colors[] =
{
{ 255, 0, 0 },
{ 0, 255, 0 },
{ 0, 0, 255 },
{ 255, 255, 0 },
{ 0, 255, 255 },
{ 255, 0, 255 },
};
struct vertex vertices[] =
{
{ 0, 0 },
{ 10, 0 },
{ 0, 10 },
{ 10, 10 },
{ 30, 10 },
{ 10, 30 },
{ 40, 50 },
{ 23, 63 },
{ 60, 30 },
{ 110, 20 },
{ 80, 50 },
{ 100, 55 },
};
struct triangle triangles[] =
{
// i, j, k, c
{ 0, 1, 2, 0 },
{ 1, 2, 3, 1 },
{ 3, 4, 5, 2 },
{ 4, 5, 6, 0 },
{ 5, 7, 6, 1 },
{ 8, 9, 10, 2 },
{ 10, 9, 11, 1 },
};
File added
/* Computer Graphics, Assignment, Triangle Rasterization
* Filename ........ trirast.c
* Description ..... Implements triangle rasterization
* Date ............ 11.08.2008
* Created by ...... Paul Melis
*
* Student name .... Sander van Veen & Taddeus Kroes
* Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
* Collegekaart .... 6167969 & 6054129
* Date ............ 09-09-2010
* Comments ........
*/
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "types.h"
#define MIN(x, y, z) fminf(fminf(x, y), z)
#define MAX(x, y, z) fmaxf(fmaxf(x, y), z)
#define RAST(X, Y, a, b) ((y##a-y##b)*X+(x##b-x##a)*Y+x##a*y##b-x##b*y##a)
#define X_DIFF(a, b) (y##a-y##b)
#define Y_DIFF(a, b) (x##b-x##a - (x-x_min)*(y##a-y##b))
/*
* Rasterize a single triangle.
* The triangle is specified by its corner coordinates
* (x0,y0), (x1,y1) and (x2,y2).
* The triangle is drawn in color (r,g,b).
*/
void draw_triangle(float x0, float y0, float x1, float y1, float x2, float y2,
byte r, byte g, byte b)
{
GLint x, y;
GLfloat alpha, beta, gamma;
// Calculate bounding box
GLint x_min = floor(MIN(x0, x1, x2)),
x_max = ceil(MAX(x0, x1, x2));
GLint y_min = floor(MIN(y0, y1, y2)),
y_max = ceil(MAX(y0, y1, y2));
// Precalculated vars
GLfloat rast_alpha = RAST(x0, y0, 1, 2),
rast_beta = RAST(x1, y1, 2, 0),
rast_gamma = RAST(x2, y2, 0, 1),
rast_alpha_offset = rast_alpha * RAST(-1, -1, 1, 2),
rast_beta_offset = rast_beta * RAST(-1, -1, 2, 0),
rast_gamma_offset = rast_gamma * RAST(-1, -1, 0, 1);
for( y = y_min; y <= y_max; y++ )
{
for( x = x_min; x <= x_max; x++ )
{
alpha = RAST(x, y, 1, 2) / rast_alpha;
beta = RAST(x, y, 2, 0) / rast_beta;
gamma = RAST(x, y, 0, 1) / rast_gamma;
if( alpha >= 0 && beta >= 0 && gamma >= 0
&& ( (alpha > 0 || rast_alpha_offset > 0)
&& (beta > 0 || rast_beta_offset > 0)
&& (gamma > 0 || rast_gamma_offset > 0) ) )
{
PutPixel(x, y, r, g, b);
}
}
}
}
void draw_triangle_optimized(float x0, float y0, float x1, float y1,
float x2, float y2, byte r, byte g, byte b)
{
// Calculate bounding box
GLint x_min = floor(MIN(x0, x1, x2)),
x_max = ceil(MAX(x0, x1, x2));
GLint y_min = floor(MIN(y0, y1, y2)),
y_max = ceil(MAX(y0, y1, y2));
GLint x, y, drawing;
// Precalculated variables
GLfloat rast_alpha = RAST(x0, y0, 1, 2),
rast_beta = RAST(x1, y1, 2, 0),
rast_gamma = RAST(x2, y2, 0, 1),
rast_alpha_div = 1 / rast_alpha,
rast_beta_div = 1 / rast_beta,
rast_gamma_div = 1 / rast_gamma,
rast_alpha_offset = rast_alpha * RAST(-1, -1, 1, 2),
rast_beta_offset = rast_beta * RAST(-1, -1, 2, 0),
rast_gamma_offset = rast_gamma * RAST(-1, -1, 0, 1);
// Initialize incremental multipliers at (0,0) of bounding box
GLfloat alpha = RAST(x_min, y_min, 1, 2),
beta = RAST(x_min, y_min, 2, 0),
gamma = RAST(x_min, y_min, 0, 1),
k, l, m;
// Loop through the triangle's bounding box
for( y = y_min; y <= y_max; y++ )
{
drawing = 0;
for( x = x_min; x <= x_max; x++ )
{
k = alpha * rast_alpha_div;
l = beta * rast_beta_div;
m = gamma * rast_gamma_div;
if( k >= 0 && l >= 0 && m >= 0
&& (k > 0 || rast_alpha_offset > 0)
&& (l > 0 || rast_beta_offset > 0)
&& (m > 0 || rast_gamma_offset > 0) )
{
PutPixel(x, y, r, g, b);
drawing = 1;
}
else if( drawing )
break;
// Increment the multipliers horizontally
alpha += X_DIFF(1, 2);
beta += X_DIFF(2, 0);
gamma += X_DIFF(0, 1);
}
// Increment the multipliers vertically
alpha += Y_DIFF(1, 2);
beta += Y_DIFF(2, 0);
gamma += Y_DIFF(0, 1);
}
}
#ifndef TRIRAST_H
#define TRIRAST_H
#include "types.h"
void draw_triangle(float x0, float y0, float x1, float y1,
float x2, float y2, byte r, byte g, byte b);
void draw_triangle_optimized(float x0, float y0, float x1, float y1,
float x2, float y2, byte r, byte g, byte b);
#endif
File added
/* Computer Graphics, Assignment, Triangle Rasterization
* Filename ........ trirast.c
* Description ..... Implements triangle rasterization
* Date ............ 11.08.2008
* Created by ...... Paul Melis
*
* Student name .... Sander van Veen
* Student email ... sandervv@gmail.com
* Collegekaart .... 6167969
* Date ............
* Comments ........
*/
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "types.h"
#define MIN(x,y,z) fminf(fminf(x, y), z)
#define MAX(x,y,z) fmaxf(fmaxf(x, y), z)
#define RAST(X,Y,a,b) ((y##a-y##b)*X+(x##b-x##a)*Y+x##a*y##b-x##b*y##a)
/*
* Rasterize a single triangle.
* The triangle is specified by its corner coordinates
* (x0,y0), (x1,y1) and (x2,y2).
* The triangle is drawn in color (r,g,b).
*/
void draw_triangle(float x0, float y0, float x1, float y1, float x2, float y2,
byte r, byte g, byte b)
{
GLint x_min = floor(MIN(x0, x1, x2)),
x_max = ceil(MAX(x0, x1, x2));
GLint y_min = floor(MIN(y0, y1, y2)),
y_max = ceil(MAX(y0, y1, y2));
GLint x, y;
GLfloat alpha, beta, gamma,
rast_alpha = RAST(x0, y0, 1, 2),
rast_beta = RAST(x1, y1, 2, 0),
rast_gamma = RAST(x2, y2, 0, 1),
rast_alpha_offset = rast_alpha * RAST(-1, -1, 1, 2),
rast_beta_offset = rast_beta * RAST(-1, -1, 2, 0),
rast_gamma_offset = rast_gamma * RAST(-1, -1, 0, 1);
for( y = y_min; y <= y_max; y++ )
{
for( x = x_min; x <= x_max; x++ )
{
alpha = RAST(x, y, 1, 2) / rast_alpha;
beta = RAST(x, y, 2, 0) / rast_beta;
gamma = RAST(x, y, 0, 1) / rast_gamma;
//printf("alpha: %f\n", alpha);
//printf("beta: %f\n", beta);
//printf("gamma: %f\n", gamma);
if( alpha >= 0 && beta >= 0 && gamma >= 0
&& ( (alpha > 0 || rast_alpha_offset > 0)
&& (beta > 0 || rast_beta_offset > 0)
&& (gamma > 0 || rast_gamma_offset > 0) ) )
{
PutPixel(x, y, r, g, b);
}
}
}
}
void draw_triangle_optimized(float x0, float y0, float x1, float y1,
float x2, float y2, byte r, byte g, byte b)
{
// Calculate bounding box
GLint x_min = floor(MIN(x0, x1, x2)),
x_max = ceil(MAX(x0, x1, x2));
GLint y_min = floor(MIN(y0, y1, y2)),
y_max = ceil(MAX(y0, y1, y2));
GLint x, y,
x_diff = x_max - x_min + 1;
// Precalculated vars
GLfloat rast_alpha = RAST(x0, y0, 1, 2),
rast_beta = RAST(x1, y1, 2, 0),
rast_gamma = RAST(x2, y2, 0, 1),
rast_alpha_div = 1 / rast_alpha,
rast_beta_div = 1 / rast_beta,
rast_gamma_div = 1 / rast_gamma,
rast_alpha_offset = rast_alpha * RAST(-1, -1, 1, 2),
rast_beta_offset = rast_beta * RAST(-1, -1, 2, 0),
rast_gamma_offset = rast_gamma * RAST(-1, -1, 0, 1),
d_alpha_x = (y1-y2) * rast_alpha_div,
d_beta_x = (y2-y0) * rast_beta_div,
d_gamma_x = (y0-y1) * rast_gamma_div,
d_alpha_y = (x2-x1 - x_diff*(y1-y2)) * rast_alpha_div,
d_beta_y = (x0-x2 - x_diff*(y2-y0)) * rast_beta_div,
d_gamma_y = (x1-x0 - x_diff*(y0-y1)) * rast_gamma_div;
// Initialize incremental multipliers at (0,0)
GLfloat alpha = RAST(x_min, y_min, 1, 2) * rast_alpha_div,
beta = RAST(x_min, y_min, 2, 0) * rast_beta_div,
gamma = RAST(x_min, y_min, 0, 1) * rast_gamma_div;
// Loop through the triangle's bounding box
for( y = y_min; y <= y_max; y++ )
{
for( x = x_min; x <= x_max; x++ )
{
if( alpha >= 0 && beta >= 0 && gamma >= 0
&& ( (alpha > 0 || rast_alpha_offset > 0)
&& (beta > 0 || rast_beta_offset > 0)
&& (gamma > 0 || rast_gamma_offset > 0) ) )
{
PutPixel(x, y, r, g, b);
}
// Increment the multipliers horizontally
alpha += d_alpha_x;
beta += d_beta_x;
gamma += d_gamma_x;
}
// Increment the multipliers vertically
alpha += d_alpha_y;
beta += d_beta_y;
gamma += d_gamma_y;
}
}
#ifndef TYPES_H
#define TYPES_H
typedef unsigned char byte;
struct vertex
{
float x, y;
};
struct color
{
byte r, g, b;
};
struct triangle
{
// vertex indices
int i, j, k;
// color index
int c;
};
void PutPixel(int x, int y, byte r, byte g, byte b);
#endif
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 normals.o polys.o
$(CC) $(LDFLAGS) -o main $^
clean:
rm -f *.o
rm -f main
normals.o : normals.h polys.h normals.c
main.o : normals.h polys.h main.c
normals.o : polys.h normals.h
polys.o : polys.h
polys.o : polys.h polys.c
File added
File added
/* Computer Graphics, Assignment, Shading
*
* Filename ........ main.c
* Description ..... Creates OpenGL window and draws the scene.
* Date ............ 19.08.2008
*/
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.1415926535897932384626
#endif
#include "polys.h"
#include "normals.h"
polys *polylistFlat = NULL;
polys *polylistGouraud = NULL;
float camDistance = 25.0;
float camRotZ = 45.0, camAzimuth = 20.0;
float saved_camRotZ, saved_camAzimuth, saved_camDistance;
int mouse_mode = 0;
int mx, my;
#define color_roof {1.0,0.2,0.0,0.0}
#define color_wall {0.7,0.7,0.7,0.0}
#define color_garden {0.1,1.0,0.0,0.0}
#define base_NW {-1.5, -1.0, 1.0}
#define base_NE { 1.5, -1.0, 1.0}
#define base_SW {-1.5, -1.0,-1.0}
#define base_SE { 1.5, -1.0,-1.0}
#define base2_NW {-1.5, 1.5, 1.0}
#define base2_NE { 1.5, 1.5, 1.0}
#define base2_SW {-1.5, 1.5,-1.0}
#define base2_SE { 1.5, 1.5,-1.0}
#define base2_W {-1.5, 2.5, 0.0}
#define base2_E { 1.5, 2.5, 0.0}
#define roof_NW {-1.8, 1.3, 1.2}
#define roof_NE { 1.8, 1.3, 1.2}
#define roof_SW {-1.8, 1.3,-1.2}
#define roof_SE { 1.8, 1.3,-1.2}
#define roof_W {-1.8, 2.5, 0.0}
#define roof_E { 1.8, 2.5, 0.0}
#define garden_E {-4.5, 0.0, 0.0}
#define garden_NE {-3.5, 0.0, 3.5}
#define garden_NW { 3.5, 0.0, 3.5}
#define garden_W { 4.5, 0.0, 0.0}
#define garden_SW { 3.5, 0.0,-3.5}
#define garden_SE {-3.5, 0.0,-3.5}
#define n { 0.0, 0.0, 0.0}
#define nn { n, n, n, n, n, n}
#define center {0.0,0.0,0.0}
poly garden = {6, {garden_E,garden_NE,garden_NW,garden_W,garden_SW,garden_SE}, nn, n, center, color_garden};
poly wall_E = {5, {base_NE,base_SE,base2_SE,base2_E,base2_NE,n}, nn, n, center, color_wall};
poly wall_W = {5, {base_NW,base_SW,base2_SW,base2_W,base2_NW,n}, nn, n, center, color_wall};
poly wall_N = {4, {base_NW,base_NE,base2_NE,base2_NW,n,n}, nn, n, center, color_wall};
poly wall_S = {4, {base_SW,base_SE,base2_SE,base2_SW,n,n}, nn, n, center, color_wall};
poly roof_N = {4, {roof_NE,roof_NW,roof_W,roof_E,n,n}, nn, n, center, color_roof};
poly roof_S = {4, {roof_SE,roof_SW,roof_W,roof_E,n,n}, nn, n, center, color_roof};
GLfloat lightPosition[] = {2.0f, 10.0f, 2.0f, 0.0f};
GLfloat lightAmbient[] = {0.3f, 0.3f, 0.3f, 1.0f};
GLfloat lightDiffuse[] = {2.0f, 2.0f, 2.0f, 1.0f};
GLfloat lightSpecular[] = {1.0f, 1.0f, 1.0f, 1.0f};
void
createSphere(polys* list, double sx, double sy, double sz,
double ox, double oy, double oz, double r, double g, double b)
{
int latitude,longitude;
double dToR = M_PI/180.0;
GLfloat x, y, z;
poly p;
p.points = 4;
p.color[0] = r;
p.color[1] = g;
p.color[2] = b;
p.color[3] = 0;
p.inside.x = ox;
p.inside.y = oy;
p.inside.z = oz;
for (latitude = -90; latitude < 90; latitude += 10)
{
for (longitude = 0; longitude <= 360; longitude += 10)
{
x = ox + sin(longitude * dToR) * cos(latitude * dToR)*sx;
y = oy + sin(latitude * dToR)*sy;
z = oz + cos(longitude * dToR) * cos(latitude * dToR)*sz;
p.pts[0] = p.pts[3];
p.pts[1] = p.pts[2];
p.pts[2].x = x;
p.pts[2].y = y;
p.pts[2].z = z;
x = ox + sin(longitude * dToR) * cos((latitude+10) * dToR)*sx;
y = oy + sin((latitude+10) * dToR)*sy;
z = oz + cos(longitude * dToR) * cos((latitude+10) * dToR)*sz;
p.pts[3].x = x;
p.pts[3].y = y;
p.pts[3].z = z;
if (longitude != 0)
AddPolyToPolylist(list,p);
}
}
}
void
InitializePolygonlist(void)
{
polylistFlat = CreatePolylist(6);
AddPolyToPolylist(polylistFlat, wall_E);
AddPolyToPolylist(polylistFlat, wall_W);
AddPolyToPolylist(polylistFlat, wall_S);
AddPolyToPolylist(polylistFlat, wall_N);
AddPolyToPolylist(polylistFlat, roof_S);
AddPolyToPolylist(polylistFlat, roof_N);
polylistGouraud = CreatePolylist(10);
createSphere(polylistGouraud,6,3,6,0,-3,0,0,1,0);
printf("%d polygons to flat shade\n", polylistFlat->length);
printf("%d polygons to gouraud shade\n", polylistGouraud->length);
calcNormalsFlat(polylistFlat);
calcNormalsGouraud(polylistGouraud);
}
void
InitGL(void)
{
GLfloat light_ambient[] = {0.4,0.4,0.4,0.0};
GLfloat mat_shininess[] = { 50.0 };
glClearColor(0.7,0.7,1,1);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK);
glEnable(GL_COLOR_MATERIAL);
}
void
ReSizeGLScene(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,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity ();
}
void
drawPolylist(polys* list)
{
int i,j;
poly p;
for (i = 0; i < list->length; i++)
{
p = list->items[i];
glColor3f(p.color[0], p.color[1], p.color[2]);
glBegin(GL_POLYGON);
for (j = 0; j < p.points; j++)
{
glNormal3f(p.normal[j].x, p.normal[j].y, p.normal[j].z);
glVertex3f(p.pts[j].x, p.pts[j].y, p.pts[j].z);
}
glEnd();
}
}
void SetupCamera(void)
{
float cx, cy, cz;
float t;
float beta, gamma;
glLoadIdentity();
// degrees -> radians
beta = camAzimuth / 180.0 * M_PI;
gamma = camRotZ / 180.0 * M_PI;
cx = camDistance;
cy = cz = 0.0;
// Rotate around Z
t = cx;
cx = cx * cos(beta) + cy * sin(beta);
cy = t * sin(beta) + cy * cos(beta);
// Rotate around Y
t = cx;
cx = cx * cos(gamma) - cz * sin(gamma);
cz = t * sin(gamma) + cz * cos(gamma);
gluLookAt (cx, cy, cz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
void
DrawGLScene(void)
{
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_no_specular[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat light_position[] = { 5.0, 5.0, 5.0, 0.0 };
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
SetupCamera();
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_no_specular);
drawPolylist(polylistFlat);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
drawPolylist(polylistGouraud);
glutSwapBuffers();
}
void
keyPressed(unsigned char key, int x, int y)
{
switch (key)
{
case 'q':
exit(-1);
break;
}
}
void
specialKeyPressed(int key, int x, int 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 * 0.5;
if (camDistance < 0.5)
camDistance = 0.5;
else if (camDistance > 100.0)
camDistance = 100.0;
}
}
int
main(int argc, char **argv)
{
InitializePolygonlist();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutInitWindowPosition(0, 0);
glutCreateWindow("Shading");
glutDisplayFunc(&DrawGLScene);
glutIdleFunc(&DrawGLScene);
glutReshapeFunc(&ReSizeGLScene);
glutSpecialFunc(&specialKeyPressed);
glutKeyboardFunc(&keyPressed);
glutMotionFunc(&motionFunc);
glutMouseFunc(&mouseFunc);
InitGL();
glutMainLoop();
}
File added
/* Computer Graphics, Assignment, Intersections
* Filename ........ normals.c
* Description ..... Calculates Plane/Vertex normals
* Date ............ 19.08.2008
*
* Student name ....
* Student email ...
* Collegekaart ....
* Date ............
* Comments ........
*
* (always fill in these fields before submitting!!)
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "normals.h"
// Calculate flat shading normal for the given polygons. Note that
// you have to set normals for all *vertices* of the polygon, so you
// have to set the normal[] array in the poly struct.
void calcNormalsFlat(polys* list)
{
poly item;
int length = (*list).length;
for( int i = 0; i < length; i++ )
{
item = (*list).items[i];
for( int p = 0; p < item.points; p++ )
{
}
// int points;
// point pts[MAX_VERTICES];
// point normal[MAX_VERTICES]; // Vertex normals
// point pnormal; // Overall polygon normal
}
}
// Calculate normals for Gouraud shading. Again, the data to fill in
// is each poly's normal[] array. You can use poly's pnormal field
// to store temporary values if you like.
void calcNormalsGouraud(polys* list)
{
// To have some form of shading on the sphere, as shown in
// the assignment, we initally do flat shading here
calcNormalsFlat(list);
}
/* Computer Graphics, Assignment, Intersections
* Filename ........ normals.c
* Description ..... Calculates Plane/Vertex normals
* Date ............ 19.08.2008
*/
#ifndef NORMALS_H
#define NORMALS_H
#include "polys.h"
void calcNormalsFlat(polys* list);
void calcNormalsGouraud(polys* list);
#endif
File added
/* Computer Graphics, Assignment, Shading
*
* Filename ........ polys.c
* Description ..... Functions to manage lists of polygons
* Date ............ 19.08.2008
* Created by ...... Jurgen Sturm
* Cleaned up by ... Paul Melis
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "polys.h"
/* Create a list of polys, and immediately reserve space for `n' polys */
polys*
CreatePolylist(int n)
{
polys *l;
l = (polys*) malloc(sizeof(polys));
if (l == NULL)
{
printf("CreatePolylist(): could not allocate memory (l): %s\n",
strerror(errno));
exit(-1);
}
if (n > 0)
{
l->items = (poly*) malloc(n * sizeof(poly));
if (l->items == NULL)
{
printf("CreatePolylist(): could not allocate memory (data): %s\n",
strerror(errno));
exit(-1);
}
l->capacity = n;
l->length = 0;
}
else
{
l->capacity = 0;
l->length = 0;
l->items = NULL;
}
return l;
}
void
DestroyPolylist(polys *list)
{
if (list == NULL)
return;
list->capacity = 0;
list->length = 0;
free(list->items);
list = NULL;
}
/* exit() if no memory available, returns 0 if poly* is NULL, 1 otherwise */
int
GrowPolylist(polys *list, int delta)
{
poly *newdata;
if (list == NULL)
return 0;
newdata = (poly*) realloc(list->items, (list->capacity + delta)*sizeof(poly));
if (newdata == NULL)
{
printf("GrowPolylist(): could not allocate memory: %s\n",
strerror(errno));
exit(-1);
}
list->capacity += delta;
list->items = newdata;
return 1;
}
/* exit() if no memory available, returns 0 if poly* is NULL, 1 otherwise.
* Decreasing the data segment can, and will, destroy polygons if the new
* segment cannot contain all current data.
* The data segment cannot be reduced to a size less than 0 (size is clamped
* to zero).
* The new data segment will be a NULL pointer if the new size is 0. */
int
ShrinkPolylist(polys *list, int delta)
{
int n;
poly *newdata;
if (list == NULL)
return 0;
n = list->capacity - delta;
if (n < 1)
{
free(list->items);
list->items = NULL;
list->capacity = 0;
list->length = 0;
return 1;
}
newdata = (poly*)realloc(list->items, (list->capacity + delta)*sizeof(poly));
if (newdata == NULL)
{
printf("ShrinkPolylist(): could not allocate memory: %s\n",
strerror(errno));
exit(-1);
}
list->capacity -= delta;
list->items = newdata;
/* update list->length if neccesary */
if (list->length > list->capacity)
list->length = list->capacity;
return 1;
}
/* poly's are structs of (point) arrays, so they are passed by value instead
* of by reference (as do arrays) */
void
AddPolyToPolylist(polys *list, poly p)
{
int i;
if (list == NULL)
return;
for (i = 0; i < p.points; i++)
{
p.normal[i].x = 0;
p.normal[i].y = 0;
p.normal[i].z = 0;
}
/* polylist is full, so first add some space */
if (list->length == list->capacity)
{
/* grow arbitrary amount */
if (GrowPolylist(list, 8) != 1)
{
printf("AddPolyToList(): failed");
exit(-1);
}
}
list->items[list->length] = p;
list->length++;
}
polys*
CopyPolylist(polys* list)
{
int i;
polys *copy;
if (list == NULL)
return NULL;
copy = CreatePolylist(list->capacity);
/* not the most efficient, but certainly easiest & least error-prone */
for (i = 0; i < list->length; i++)
AddPolyToPolylist(copy, list->items[i]);
return copy;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment