Skip to content
Snippets Groups Projects
Commit 85db55d9 authored by Taddeüs Kroes's avatar Taddeüs Kroes
Browse files

Graphics ass11

Added framework.
parent 90b6be6e
No related branches found
No related tags found
No related merge requests found
Showing
with 35102 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 -lGLU `libpng12-config --libs`
.c.o:
$(CC) -c $(CFLAGS) $<
all: main
main: geometry.o main.o polys.o readpng.o bsp.o
$(CC) $(LDFLAGS) -o main geometry.o main.o polys.o readpng.o bsp.o
readpng.o: readpng.c
$(CC) -c $(CLFAGS) `libpng12-config --cflags` readpng.c
clean:
rm -f *.o
rm -f main
geometry.o : geometry.h polys.h geometry.c
polys.o : polys.h polys.c
main.o : bsp.h geometry.h polys.h readpng.h main.c
readpng.o : readpng.h readpng.c
bsp.o : bsp.h bsp.c polys.h
File added
/* Computer Graphics
*
* Filename ........ bsp.c
* Description ..... Functions related to Binary Space-Partitioning trees
* Date ............ 23.11.2009
* Created by ...... Paul Melis
*
* Student name ....
* Student email ...
* Collegekaart ....
* Date ............
* Comments ........
*
*
* (always fill in these fields before submitting!!)
*/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "bsp.h"
/* Given a list of polygons builds a BSP tree by recursively choosing
* one polygon that defines a split plane and dividing the other polygons
* arbitrarily into left and right subsets. This does NOT result in a
* correct BSP tree.
*
* Returns the root node of the BSP tree */
BSPNode*
BuildBSPTreeIncorrect(polys *polygons)
{
polys *left_polygons, *right_polygons;
BSPNode *left_tree, *right_tree;
BSPNode *root;
poly split_poly;
// Arbitrary initial capacity for the lists, they will grow as
// needed automatically
left_polygons = CreatePolylist(4);
right_polygons = CreatePolylist(4);
// Pick a polygon which defines the split plane
split_poly = polygons->items[0];
// Arbitrarily assign polys to left and right sublists
// This is where a "real" BSP construction routine would need
// to do much more work...
for (int i = 1; i < polygons->length; i++)
{
if (i % 2 == 0)
AddPolyToPolylist(left_polygons, polygons->items[i]);
else
AddPolyToPolylist(right_polygons, polygons->items[i]);
}
// Recursively subdivide the left and right lists
left_tree = NULL;
if (left_polygons->length > 0)
left_tree = BuildBSPTreeIncorrect(left_polygons);
right_tree = NULL;
if (right_polygons->length > 0)
right_tree = BuildBSPTreeIncorrect(right_polygons);
// We can free the child polygon lists, as each child polygon
// will now have been stored in a BSP node
DestroyPolylist(left_polygons);
DestroyPolylist(right_polygons);
// Create tree node and return it
root = (BSPNode*) malloc(sizeof(BSPNode));
root->polygon = split_poly;
root->left_child = left_tree;
root->right_child = right_tree;
return root;
}
/* Checks if the line segment p1 -> p2 intersects the
* plane defined by point plane_p and normal plane_n.
*
* Returns 1 if an intersection was found and sets t appropriately
* (the intersection point will be (1-t)*p1 + t*p2)
* Returns 0 otherwise. */
int
check_for_intersection(float *t, vec3 plane_p, vec3 plane_n, vec3 p1, vec3 p2)
{
float D = v3_dotprod(plane_n, plane_p);
float denom = v3_dotprod(plane_n, v3_subtract(p2, p1));
if (fabs(denom) < 1.0e-6)
{
// Line segment parallel to the plane, no intersection possible
return 0;
}
float tt = (D - v3_dotprod(plane_n, p1)) / denom;
if (tt < 0.0 || tt > 1.0)
{
// Although the infinite line through p1 and p2 intersects
// the plane, the line *segment* p1 -> p2 does not
return 0;
}
// We have an intersection, set t
*t = tt;
return 1;
}
/* Triangle 'p' is known to intersect the plane defined
* by 'plane_p' and 'plane_n'. One of the vertices of 'p'
* (the one with index 'in_plane') is known to lie in the plane.
* Array 'side' describes for each vertex of 'p' on which side
* of the plane it lies (see comment for split_triangle()).
*
* Split the triangle along the plane and add the resulting
* new triangles to the relevant list(s).
*
* Make sure to set the correct texture coordinates for each
* edge intersection point and set the correct triangle normal
* for new triangles.
*/
void
split_triangle_one_edge_intersection(polys *left_polygons, polys *right_polygons,
vec3 plane_p, vec3 plane_n, poly p, int *side, int in_plane)
{
}
/* Triangle 'p' is known to intersect the plane defined
* by 'plane_p' and 'plane_n'. One of the vertices of 'p'
* (the one with index 'single') is known to be alone on
* one side of the plane. Array 'side' describes for each
* vertex of 'p' on which side of the plane it lies (see comment
* for split_triangle()).
*
* Split the triangle along the plane and add the resulting
* new triangles to the relevant list(s).
*
* Make sure to set the correct texture coordinates for each
* edge intersection point and set the correct triangle normal
* for new triangles.
*/
void
split_triangle_two_edge_intersections(polys *left_polygons, polys *right_polygons,
vec3 plane_p, vec3 plane_n, poly p, int *side, int single)
{
}
/* Polygon 'p' (a triangle) is known to straddle the plane defined by
* point 'plane_p' and normal 'plane_n'. The array 'side' describes
* for each vertex of p on which side of the plane it lies
* (-1 = left of, 1 = right of, 0 = on the plane). The length of
* the 'side' array is equal to p.points.
*
* Split the triangle in multiple triangles based on intersections
* of the triangle's edges with the plane, using the two split functions
* above. Add the new triangles to the relevant list(s).
*/
void
split_triangle(polys *left_polygons, polys *right_polygons,
vec3 plane_p, vec3 plane_n, poly p, int *side)
{
}
/*
* Create a correct BSP-tree for the given list of transparent
* polygons. Return the root node of the tree.
*/
BSPNode*
BuildBSPTree(polys *polygons)
{
}
/* Computer Graphics
*
* Filename ........ bsp.h
* Description ..... Functions related to Binary Space-Partitioning trees
* Date ............ 22.11.2009
* Created by ...... Paul Melis
*/
#ifndef BSP_H
#define BSP_H
#include "polys.h"
typedef struct BSPNode
{
// May be NULL
struct BSPNode *left_child, *right_child;
// The polygon assigned to this node.
// It defines the split plane.
poly polygon;
}
BSPNode;
BSPNode* BuildBSPTreeIncorrect(polys *polygons);
BSPNode* BuildBSPTree(polys *polygons);
#endif
This diff is collapsed.
v 0.382683 0.000000 5.528998
v 0.707107 0.000000 5.312225
v 0.923880 0.000000 4.987802
v 1.000000 0.000000 4.605118
v 0.923880 0.000000 4.222435
v 0.707107 0.000000 3.898011
v 0.382683 0.000000 3.681239
v 0.270598 0.270598 3.681239
v 0.500000 0.500000 3.898011
v 0.653281 0.653282 4.222435
v 0.707107 0.707107 4.605118
v 0.653281 0.653282 4.987802
v 0.500000 0.500000 5.312225
v 0.270598 0.270598 5.528998
v -0.000000 0.382683 5.528998
v -0.000000 0.707107 5.312225
v -0.000000 0.923880 4.987802
v -0.000000 1.000000 4.605118
v -0.000000 0.923880 4.222435
v -0.000000 0.707107 3.898011
v -0.000000 0.382684 3.681239
v -0.270598 0.270598 3.681239
v -0.500000 0.500000 3.898011
v -0.653282 0.653281 4.222435
v -0.707107 0.707107 4.605118
v -0.653282 0.653281 4.987802
v -0.500000 0.500000 5.312225
v -0.270598 0.270598 5.528998
v -0.382683 -0.000000 5.528998
v -0.707107 -0.000000 5.312225
v -0.923880 -0.000000 4.987802
v -1.000000 -0.000000 4.605118
v -0.923880 -0.000000 4.222435
v -0.707107 -0.000000 3.898011
v -0.382684 -0.000000 3.681239
v -0.000000 -0.000000 3.679463
v -0.270598 -0.270598 3.681239
v -0.500000 -0.500000 3.898011
v -0.653281 -0.653282 4.222435
v -0.707107 -0.707107 4.605118
v -0.653281 -0.653282 4.987802
v -0.500000 -0.500000 5.312225
v -0.270598 -0.270598 5.528998
v 0.000000 -0.382683 5.528998
v 0.000000 -0.707107 5.312225
v 0.000000 -0.923880 4.987802
v 0.000000 -1.000000 4.605118
v 0.000000 -0.923880 4.222435
v 0.000000 -0.707107 3.898011
v 0.000000 -0.382684 3.681239
v 0.270598 -0.270598 3.681239
v 0.500000 -0.500000 3.898011
v 0.653282 -0.653281 4.222435
v 0.707107 -0.707107 4.605118
v 0.653282 -0.653281 4.987802
v 0.500000 -0.500000 5.312225
v 0.270598 -0.270598 5.528998
v 0.382683 -0.000000 5.624637
v 0.270598 -0.270598 5.624637
v 0.000000 -0.382683 5.624637
v -0.270598 -0.270598 5.624637
v -0.382683 -0.000000 5.624637
v -0.270598 0.270598 5.624637
v -0.000000 0.382683 5.624637
v 0.270598 0.270598 5.624637
p 3 -1
0.5 0.5 0.8 0.5
35 0.0 0.0
7 0.0 0.0
6 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
6 0.0 0.0
7 0.0 0.0
8 0.0 0.0
5 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
5 0.0 0.0
8 0.0 0.0
9 0.0 0.0
4 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
4 0.0 0.0
9 0.0 0.0
10 0.0 0.0
3 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
3 0.0 0.0
10 0.0 0.0
11 0.0 0.0
2 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
2 0.0 0.0
11 0.0 0.0
12 0.0 0.0
1 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
13 0.0 0.0
0 0.0 0.0
1 0.0 0.0
12 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
12 0.0 0.0
15 0.0 0.0
14 0.0 0.0
13 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
11 0.0 0.0
16 0.0 0.0
15 0.0 0.0
12 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
10 0.0 0.0
17 0.0 0.0
16 0.0 0.0
11 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
9 0.0 0.0
18 0.0 0.0
17 0.0 0.0
10 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
8 0.0 0.0
19 0.0 0.0
18 0.0 0.0
9 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
7 0.0 0.0
20 0.0 0.0
19 0.0 0.0
8 0.0 0.0
p 3 -1
0.5 0.5 0.8 0.5
35 0.0 0.0
20 0.0 0.0
7 0.0 0.0
p 3 -1
0.5 0.5 0.8 0.5
35 0.0 0.0
21 0.0 0.0
20 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
20 0.0 0.0
21 0.0 0.0
22 0.0 0.0
19 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
19 0.0 0.0
22 0.0 0.0
23 0.0 0.0
18 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
18 0.0 0.0
23 0.0 0.0
24 0.0 0.0
17 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
17 0.0 0.0
24 0.0 0.0
25 0.0 0.0
16 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
16 0.0 0.0
25 0.0 0.0
26 0.0 0.0
15 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
15 0.0 0.0
26 0.0 0.0
27 0.0 0.0
14 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
26 0.0 0.0
29 0.0 0.0
28 0.0 0.0
27 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
25 0.0 0.0
30 0.0 0.0
29 0.0 0.0
26 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
24 0.0 0.0
31 0.0 0.0
30 0.0 0.0
25 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
23 0.0 0.0
32 0.0 0.0
31 0.0 0.0
24 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
22 0.0 0.0
33 0.0 0.0
32 0.0 0.0
23 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
21 0.0 0.0
34 0.0 0.0
33 0.0 0.0
22 0.0 0.0
p 3 -1
0.5 0.5 0.8 0.5
35 0.0 0.0
34 0.0 0.0
21 0.0 0.0
p 3 -1
0.5 0.5 0.8 0.5
35 0.0 0.0
36 0.0 0.0
34 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
34 0.0 0.0
36 0.0 0.0
37 0.0 0.0
33 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
33 0.0 0.0
37 0.0 0.0
38 0.0 0.0
32 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
32 0.0 0.0
38 0.0 0.0
39 0.0 0.0
31 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
31 0.0 0.0
39 0.0 0.0
40 0.0 0.0
30 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
30 0.0 0.0
40 0.0 0.0
41 0.0 0.0
29 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
29 0.0 0.0
41 0.0 0.0
42 0.0 0.0
28 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
41 0.0 0.0
44 0.0 0.0
43 0.0 0.0
42 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
40 0.0 0.0
45 0.0 0.0
44 0.0 0.0
41 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
39 0.0 0.0
46 0.0 0.0
45 0.0 0.0
40 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
38 0.0 0.0
47 0.0 0.0
46 0.0 0.0
39 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
37 0.0 0.0
48 0.0 0.0
47 0.0 0.0
38 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
36 0.0 0.0
49 0.0 0.0
48 0.0 0.0
37 0.0 0.0
p 3 -1
0.5 0.5 0.8 0.5
35 0.0 0.0
49 0.0 0.0
36 0.0 0.0
p 3 -1
0.5 0.5 0.8 0.5
35 0.0 0.0
50 0.0 0.0
49 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
49 0.0 0.0
50 0.0 0.0
51 0.0 0.0
48 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
48 0.0 0.0
51 0.0 0.0
52 0.0 0.0
47 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
47 0.0 0.0
52 0.0 0.0
53 0.0 0.0
46 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
46 0.0 0.0
53 0.0 0.0
54 0.0 0.0
45 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
45 0.0 0.0
54 0.0 0.0
55 0.0 0.0
44 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
44 0.0 0.0
55 0.0 0.0
56 0.0 0.0
43 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
0 0.0 0.0
56 0.0 0.0
55 0.0 0.0
1 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
54 0.0 0.0
2 0.0 0.0
1 0.0 0.0
55 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
53 0.0 0.0
3 0.0 0.0
2 0.0 0.0
54 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
52 0.0 0.0
4 0.0 0.0
3 0.0 0.0
53 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
51 0.0 0.0
5 0.0 0.0
4 0.0 0.0
52 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
50 0.0 0.0
6 0.0 0.0
5 0.0 0.0
51 0.0 0.0
p 3 -1
0.5 0.5 0.8 0.5
35 0.0 0.0
6 0.0 0.0
50 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
56 0.0 0.0
0 0.0 0.0
57 0.0 0.0
58 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
43 0.0 0.0
56 0.0 0.0
58 0.0 0.0
59 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
42 0.0 0.0
43 0.0 0.0
59 0.0 0.0
60 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
28 0.0 0.0
42 0.0 0.0
60 0.0 0.0
61 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
27 0.0 0.0
28 0.0 0.0
61 0.0 0.0
62 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
14 0.0 0.0
27 0.0 0.0
62 0.0 0.0
63 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
13 0.0 0.0
14 0.0 0.0
63 0.0 0.0
64 0.0 0.0
p 4 -1
0.5 0.5 0.8 0.5
0 0.0 0.0
13 0.0 0.0
64 0.0 0.0
57 0.0 0.0
/* Computer Graphics, Assignment, Depth-sorting and transparency
* Description .....
* Date ............ 22.11.2007
* Created by ...... Paul Melis
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "geometry.h"
#include "polys.h"
#ifndef M_PI
#define M_PI 3.141592653589793
#endif
static void
setSpherePoint(vec3 *p, vec3* n, vec3* t, int latitude, int longitude,
double sx, double sy, double sz, double ox, double oy, double oz)
{
double dToR = M_PI / 180.0;
double len;
p->x = ox + sin(longitude * dToR) * cos(latitude * dToR) * sx;
p->y = oy + sin(latitude * dToR) * sy;
p->z = oz + cos(longitude * dToR) * cos(latitude * dToR) * sz;
t->x = longitude / 360.0;
t->y = (90.0 - latitude) / 180.0;
// calculate normal, this actually doesn't take the sphere size
// per axis into account, but should still be usable
n->x = p->x - ox;
n->y = p->y - oy;
n->z = p->z - oz;
len = n->x*n->x + n->y*n->y + n->z*n->z;
n->x /= len;
n->y /= len;
n->z /= len;
}
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;
poly p;
// prepare poly, as these values are the same for all generated polys
p.points = 4;
p.color[0] = r;
p.color[1] = g;
p.color[2] = b;
p.color[3] = 0;
// sweep over sphere's surface and generate polys
for (latitude = -90; latitude < 90; latitude += 10)
{
for (longitude = 0; longitude < 360; longitude += 10)
{
setSpherePoint(&(p.pts[0]), &(p.normal[0]), &(p.tcoord[0]),
latitude, longitude, sx, sy, sz, ox, oy, oz);
setSpherePoint(&(p.pts[1]), &(p.normal[1]), &(p.tcoord[1]),
latitude+10, longitude, sx, sy, sz, ox, oy, oz);
setSpherePoint(&(p.pts[2]), &(p.normal[2]), &(p.tcoord[2]),
latitude+10, longitude+10, sx, sy, sz, ox, oy, oz);
setSpherePoint(&(p.pts[3]), &(p.normal[3]), &(p.tcoord[3]),
latitude, longitude+10, sx, sy, sz, ox, oy, oz);
AddPolyToPolylist(list, p);
}
}
}
// Calculate the coordinates, normal vector and texture coordinates for
// a hemisphere point at the given latitude and longitude (in degrees).
// The radius of the hemisphere is s, the center point (at the base of the
// hemisphere) is ox,oy,oz.
static void
setHemispherePoint(vec3 *p, vec3* n, vec3* t, int latitude, int longitude,
double s, double ox, double oy, double oz)
{
double dToR = M_PI / 180.0;
double len;
p->x = ox + sin(longitude * dToR) * cos(latitude * dToR) * s;
p->y = oy + sin(latitude * dToR) * s;
p->z = oz + cos(longitude * dToR) * cos(latitude * dToR) * s;
t->x = longitude / 360.0;
t->y = 1.0 * latitude / 90.0;
// calculate normal
n->x = p->x - ox;
n->y = p->y - oy;
n->z = p->z - oz;
len = n->x*n->x + n->y*n->y + n->z*n->z;
n->x /= len;
n->y /= len;
n->z /= len;
}
void
createHemisphere(polys * list, double s, double ox, double oy, double oz,
double r, double g, double b)
{
int latitude, longitude;
poly p;
// prepare poly, as these values are the same for all generated polys
p.points = 4;
p.color[0] = r;
p.color[1] = g;
p.color[2] = b;
p.color[3] = 1;
// sweep over sphere's surface and generate polys
for (latitude = 0; latitude < 90; latitude += 10)
{
for (longitude = 0; longitude < 360; longitude += 10)
{
setHemispherePoint(&(p.pts[0]), &(p.normal[0]), &(p.tcoord[0]),
latitude, longitude, s, ox, oy, oz);
setHemispherePoint(&(p.pts[1]), &(p.normal[1]), &(p.tcoord[1]),
latitude, longitude+10, s, ox, oy, oz);
setHemispherePoint(&(p.pts[2]), &(p.normal[2]), &(p.tcoord[2]),
latitude+10, longitude+10, s, ox, oy, oz);
setHemispherePoint(&(p.pts[3]), &(p.normal[3]), &(p.tcoord[3]),
latitude+10, longitude, s, ox, oy, oz);
AddPolyToPolylist(list, p);
}
}
}
// Create a cylinder along the Y axis whose base center point is
// at (ox, oy, oz), having the given radius and height.
// Use the given color for the generated polygons.
void
createCylinder(polys * list, double radius, double height,
double ox, double oy, double oz,
double r, double g, double b)
{
int longitude;
GLfloat x, z;
GLfloat x2, z2;
double dToR = M_PI / 180.0;
double len;
poly p;
int i;
// prepare poly datastructure, as these values are the same for all generated polys
p.points = 4;
p.color[0] = r;
p.color[1] = g;
p.color[2] = b;
p.color[3] = 0;
// sweep around cylinder axis
for (longitude = 0; longitude < 360; longitude += 10)
{
x = ox + sin(longitude * dToR) * radius;
z = oz + cos(longitude * dToR) * radius;
x2 = ox + sin((longitude+10) * dToR) * radius;
z2 = oz + cos((longitude+10) * dToR) * radius;
p.pts[0].x = x; p.pts[0].y = oy; p.pts[0].z = z;
p.pts[1].x = x; p.pts[1].y = oy+height; p.pts[1].z = z;
p.pts[2].x = x2; p.pts[2].y = oy+height; p.pts[2].z = z2;
p.pts[3].x = x2; p.pts[3].y = oy; p.pts[3].z = z2;
for (i = 0; i < 4; i++)
{
p.normal[i].x = p.pts[i].x - ox;
p.normal[i].y = 0.0;
p.normal[i].z = p.pts[i].z - oz;
len = p.normal[i].x*p.normal[i].x + p.normal[i].z*p.normal[i].z;
p.normal[i].x /= len;
p.normal[i].z /= len;
}
p.tcoord[0].x = p.tcoord[1].x = longitude / 360.0;
p.tcoord[2].x = p.tcoord[3].x = (longitude+10) / 360.0;
p.tcoord[0].y = p.tcoord[3].y = 1.0;
p.tcoord[1].y = p.tcoord[2].y = 0.0;
AddPolyToPolylist(list, p);
}
}
// Read the vertex data for a single polygon and store it in 'p'.
// Called from loadPolygonalObject() after a 'p ...' line (+ color)
// has been read.
static void
readPolyVertices(poly *p, FILE *f, const vec3 *vertex_list, int num_vertices_to_read,
int texture_id, GLuint opengl_texture_name)
{
char line[1024];
int num_read;
int pidx;
int vidx;
float s, t;
p->points = num_vertices_to_read;
num_read = 0;
pidx = 0;
while (num_read < num_vertices_to_read)
{
if (fgets(line, 1024, f) == NULL)
{
printf("Unexpected end-of-file reading poly vertices!\n");
exit(-1);
}
if (sscanf(line, "%d %f %f\n", &vidx, &s, &t) == 3)
{
//printf("%d %f %f %f %f %f\n", vidx, nx, ny, nz, s, t);
p->pts[pidx] = vertex_list[vidx];
p->texture_id = texture_id;
p->opengl_texture_name = opengl_texture_name;
p->tcoord[pidx].x = s;
p->tcoord[pidx].y = t;
num_read++;
pidx++;
}
else if (line[0] && line[0] != '#')
{
printf("Expected line declaring polygon vertex, got instead:\n");
printf("%s\n", line);
exit(-1);
}
}
}
// Read a polygonal object from a .OBJ file.
// Scale the input coordinates uniformly with a factor s followed by
// a translation (tx,ty,tz). This allows a very simple transformation
// on the loaded data, e.g. to position objects in the scene.
void
loadPolygonalObject(polys* list, const char *objfile, GLuint *texture_names, int num_textures,
double s, double tx, double ty, double tz)
{
FILE *f;
char line[1024];
float x, y, z;
vec3 *vertices;
int num_vertices;
int num_vertices_allocated;
poly p;
float colr, colg, colb, cola;
int num_poly_vertices, texture_id;
int i;
float len;
vec3 v, w, n;
int texture_name;
f = fopen(objfile, "rt");
if (!f)
{
fprintf(stderr, "loadPolygonalObject(): Could not open file '%s' for reading!\n", objfile);
exit(-1);
}
printf("Reading %s\n", objfile);
num_vertices = 0;
num_vertices_allocated = 1024;
vertices = malloc(num_vertices_allocated * sizeof(vec3));
while (fgets(line, 1024, f))
{
if (sscanf(line, "v %f %f %f\n", &x, &y, &z))
{
// vertex
//printf("vertex: %f %f %f\n", x, y, z);
// current vertex list is full, add more space
if (num_vertices == num_vertices_allocated)
{
num_vertices_allocated = (int)(1.5 * num_vertices_allocated);
vertices = realloc(vertices, num_vertices_allocated * sizeof(vec3));
if (vertices == NULL)
{
printf("No memory to hold vertices!\n");
exit(-1);
}
}
// store vertex, after scaling and translation
vertices[num_vertices].x = tx + s*x;
vertices[num_vertices].y = ty + s*y;
vertices[num_vertices].z = tz + s*z;
num_vertices++;
}
else if (sscanf(line, "p %d %d\n", &num_poly_vertices, &texture_id))
{
if (num_poly_vertices < 3)
{
printf("In %s, line:\n", objfile);
printf("%s\n", line);
printf("Need at least 3 vertices to define a polygon!\n");
exit(-1);
}
else if (num_poly_vertices > 4)
{
printf("In %s, line:\n", objfile);
printf("%s\n", line);
printf("Polygons may only consist of 3 or 4 vertices, sorry\n");
printf("(this is due to OpenGL not handling concave polygons very well)\n");
exit(-1);
}
// read polygon color
if (fscanf(f, "%f %f %f %f\n", &colr, &colg, &colb, &cola) == EOF)
{
printf("Could not read polygon color!\n");
exit(-1);
}
p.color[0] = colr;
p.color[1] = colg;
p.color[2] = colb;
p.color[3] = cola;
texture_name = -1;
if (texture_id > num_textures)
printf("Texture ID (%d) out of range (<= %d)\n", texture_id, num_textures-1);
else if (texture_id >= 0)
// Determine corresponding OpenGL texture name
texture_name = texture_names[texture_id];
// read vertices making up poly
readPolyVertices(&p, f, vertices, num_poly_vertices, texture_id, texture_name);
// Use first 3 polygon vertices to calculate the polygon normal vector
// (i.e. assumes polygon is planar)
v.x = p.pts[2].x - p.pts[1].x;
v.y = p.pts[2].y - p.pts[1].y;
v.z = p.pts[2].z - p.pts[1].z;
w.x = p.pts[0].x - p.pts[1].x;
w.y = p.pts[0].y - p.pts[1].y;
w.z = p.pts[0].z - p.pts[1].z;
n.x = v.y * w.z - v.z * w.y;
n.y = v.z * w.x - v.x * w.z;
n.z = v.x * w.y - v.y * w.x;
len = sqrt(n.x * n.x + n.y * n.y + n.z * n.z);
n.x /= len;
n.y /= len;
n.z /= len;
// Set vertex normals to polygon normal
for (i = 0; i < num_poly_vertices; i++)
p.normal[i] = n;
// Add polygon
AddPolyToPolylist(list, p);
}
}
//printf("%d vertices read\n", num_vertices);
fclose(f);
free(vertices);
}
#ifndef GEOMETRY_H
#define GEOMETRY_H
#include "polys.h"
// Create a sphere centered at (ox, oy, oz), having sizes
// sx, sy and sz in X, Y and Z respectively. Use the given color.
void
createSphere(polys * list, double sx, double sy, double sz, double ox,
double oy, double oz, double r, double g, double b);
// Create a hemisphere whose base point is at (ox, oy, oz), having radius s.
// Use the given color.
void
createHemisphere(polys * list, double s, double ox, double oy, double oz,
double r, double g, double b);
// Create a cylinder along the Y axis whose base center point is
// at (ox, oy, oz), having the given radius and height.
// Use the given color for the generated polygons.
void
createCylinder(polys * list, double radius, double height,
double ox, double oy, double oz,
double r, double g, double b);
// Read a polygonal object from a .OBJ file.
// Scale the input coordinates uniformly with a factor s followed by
// a translation (tx,ty,tz).
void
loadPolygonalObject(polys * list, const char *objfile, GLuint *texture_names, int num_textures,
double s, double tx, double ty, double tz);
#endif
v -0.299609 0.000000 4.581704
v -0.271560 0.000000 4.650124
v -0.191683 0.000000 4.708128
v -0.072139 0.000000 4.746885
v 0.068874 0.000000 4.760495
v 0.224853 -0.000000 4.658367
v 0.329430 -0.000000 4.712994
v 0.375700 0.000000 4.650124
v 0.375700 0.022108 4.630084
v 0.329430 0.029671 4.674540
v 0.224853 0.024771 4.635912
v 0.068874 0.057770 4.708128
v -0.072139 0.053372 4.698505
v -0.191683 0.040849 4.671099
v -0.271560 0.022108 4.630084
v -0.271560 0.031265 4.581704
v -0.191683 0.057770 4.581704
v -0.072139 0.075480 4.581704
v 0.068874 0.081699 4.581704
v 0.224853 0.035031 4.581704
v 0.329430 0.041961 4.581704
v 0.375700 0.031265 4.581704
v 0.375700 0.022108 4.533323
v 0.329430 0.029671 4.488867
v 0.224853 0.024771 4.527495
v 0.068874 0.057770 4.494184
v -0.072139 0.053372 4.491802
v -0.191683 0.040849 4.519207
v -0.271560 0.022108 4.533323
v -0.271560 -0.000000 4.513283
v -0.191683 -0.000000 4.482179
v -0.072139 -0.000000 4.467538
v 0.068874 -0.000000 4.462441
v 0.224853 -0.000000 4.505041
v 0.329430 -0.000000 4.450413
v 0.375700 -0.000000 4.513283
v 0.403749 -0.000000 4.581704
v 0.375700 -0.022108 4.533323
v 0.329430 -0.029671 4.488867
v 0.224853 -0.024771 4.527495
v 0.068874 -0.057770 4.494184
v -0.072139 -0.053372 4.491802
v -0.191683 -0.040849 4.519208
v -0.271560 -0.022108 4.533323
v -0.271560 -0.031265 4.581704
v -0.191683 -0.057770 4.581704
v -0.072139 -0.075480 4.581704
v 0.068874 -0.081699 4.581704
v 0.224853 -0.035031 4.581704
v 0.329430 -0.041961 4.581704
v 0.375700 -0.031265 4.581704
v 0.375700 -0.022108 4.630084
v 0.329430 -0.029671 4.674540
v 0.224853 -0.024771 4.635912
v 0.068874 -0.057770 4.708128
v -0.072139 -0.053372 4.698505
v -0.191683 -0.040849 4.671099
v -0.271560 -0.022108 4.630085
v 0.068874 -0.057770 4.494184
v 0.068874 -0.081699 4.581704
v -0.072139 -0.075480 4.581704
v -0.072139 -0.053372 4.491802
v 0.068874 0.057770 4.494184
v -0.072139 0.053372 4.491802
v -0.072139 0.075480 4.581704
v 0.068874 0.081699 4.581704
v 0.067339 0.104029 4.532372
v 0.035043 0.116076 4.442444
v -0.041377 0.112954 4.438537
v -0.073673 0.098301 4.529950
v 0.034841 -0.109676 4.442885
v 0.067339 -0.101504 4.533247
v -0.073673 -0.095677 4.531074
v -0.041175 -0.106388 4.439116
p 3 -1
0.8 0.4 0 1
36 0.0 0.0
8 0.0 0.0
7 0.0 0.0
p 4 -1
0.8 0.4 0 1
7 0.0 0.0
8 0.0 0.0
9 0.0 0.0
6 0.0 0.0
p 4 -1
0.8 0.4 0 1
6 0.0 0.0
9 0.0 0.0
10 0.0 0.0
5 0.0 0.0
p 4 -1
0.8 0.4 0 1
5 0.0 0.0
10 0.0 0.0
11 0.0 0.0
4 0.0 0.0
p 4 -1
0.8 0.4 0 1
4 0.0 0.0
11 0.0 0.0
12 0.0 0.0
3 0.0 0.0
p 4 -1
0.8 0.4 0 1
3 0.0 0.0
12 0.0 0.0
13 0.0 0.0
2 0.0 0.0
p 4 -1
0.8 0.4 0 1
2 0.0 0.0
13 0.0 0.0
14 0.0 0.0
1 0.0 0.0
p 3 -1
0.8 0.4 0 1
14 0.0 0.0
0 0.0 0.0
1 0.0 0.0
p 3 -1
0.8 0.4 0 1
15 0.0 0.0
0 0.0 0.0
14 0.0 0.0
p 4 -1
0.8 0.4 0 1
13 0.0 0.0
16 0.0 0.0
15 0.0 0.0
14 0.0 0.0
p 4 -1
0.8 0.4 0 1
12 0.0 0.0
17 0.0 0.0
16 0.0 0.0
13 0.0 0.0
p 4 -1
0.8 0.4 0 1
11 0.0 0.0
18 0.0 0.0
17 0.0 0.0
12 0.0 0.0
p 4 -1
0.8 0.4 0 1
10 0.0 0.0
19 0.0 0.0
18 0.0 0.0
11 0.0 0.0
p 4 -1
0.8 0.4 0 1
9 0.0 0.0
20 0.0 0.0
19 0.0 0.0
10 0.0 0.0
p 4 -1
0.8 0.4 0 1
8 0.0 0.0
21 0.0 0.0
20 0.0 0.0
9 0.0 0.0
p 3 -1
0.8 0.4 0 1
36 0.0 0.0
21 0.0 0.0
8 0.0 0.0
p 3 -1
0.8 0.4 0 1
36 0.0 0.0
22 0.0 0.0
21 0.0 0.0
p 4 -1
0.8 0.4 0 1
21 0.0 0.0
22 0.0 0.0
23 0.0 0.0
20 0.0 0.0
p 4 -1
0.8 0.4 0 1
20 0.0 0.0
23 0.0 0.0
24 0.0 0.0
19 0.0 0.0
p 4 -1
0.8 0.4 0 1
19 0.0 0.0
24 0.0 0.0
25 0.0 0.0
18 0.0 0.0
p 4 -1
0.8 0.4 0 1
17 0.0 0.0
26 0.0 0.0
27 0.0 0.0
16 0.0 0.0
p 4 -1
0.8 0.4 0 1
16 0.0 0.0
27 0.0 0.0
28 0.0 0.0
15 0.0 0.0
p 3 -1
0.8 0.4 0 1
28 0.0 0.0
0 0.0 0.0
15 0.0 0.0
p 3 -1
0.8 0.4 0 1
29 0.0 0.0
0 0.0 0.0
28 0.0 0.0
p 4 -1
0.8 0.4 0 1
27 0.0 0.0
30 0.0 0.0
29 0.0 0.0
28 0.0 0.0
p 4 -1
0.8 0.4 0 1
26 0.0 0.0
31 0.0 0.0
30 0.0 0.0
27 0.0 0.0
p 4 -1
0.8 0.4 0 1
25 0.0 0.0
32 0.0 0.0
31 0.0 0.0
26 0.0 0.0
p 4 -1
0.8 0.4 0 1
24 0.0 0.0
33 0.0 0.0
32 0.0 0.0
25 0.0 0.0
p 4 -1
0.8 0.4 0 1
23 0.0 0.0
34 0.0 0.0
33 0.0 0.0
24 0.0 0.0
p 4 -1
0.8 0.4 0 1
22 0.0 0.0
35 0.0 0.0
34 0.0 0.0
23 0.0 0.0
p 3 -1
0.8 0.4 0 1
36 0.0 0.0
35 0.0 0.0
22 0.0 0.0
p 3 -1
0.8 0.4 0 1
36 0.0 0.0
37 0.0 0.0
35 0.0 0.0
p 4 -1
0.8 0.4 0 1
35 0.0 0.0
37 0.0 0.0
38 0.0 0.0
34 0.0 0.0
p 4 -1
0.8 0.4 0 1
34 0.0 0.0
38 0.0 0.0
39 0.0 0.0
33 0.0 0.0
p 4 -1
0.8 0.4 0 1
33 0.0 0.0
39 0.0 0.0
40 0.0 0.0
32 0.0 0.0
p 4 -1
0.8 0.4 0 1
32 0.0 0.0
40 0.0 0.0
41 0.0 0.0
31 0.0 0.0
p 4 -1
0.8 0.4 0 1
31 0.0 0.0
41 0.0 0.0
42 0.0 0.0
30 0.0 0.0
p 4 -1
0.8 0.4 0 1
30 0.0 0.0
42 0.0 0.0
43 0.0 0.0
29 0.0 0.0
p 3 -1
0.8 0.4 0 1
43 0.0 0.0
0 0.0 0.0
29 0.0 0.0
p 3 -1
0.8 0.4 0 1
44 0.0 0.0
0 0.0 0.0
43 0.0 0.0
p 4 -1
0.8 0.4 0 1
42 0.0 0.0
45 0.0 0.0
44 0.0 0.0
43 0.0 0.0
p 4 -1
0.8 0.4 0 1
41 0.0 0.0
46 0.0 0.0
45 0.0 0.0
42 0.0 0.0
p 4 -1
0.8 0.4 0 1
39 0.0 0.0
48 0.0 0.0
47 0.0 0.0
40 0.0 0.0
p 4 -1
0.8 0.4 0 1
38 0.0 0.0
49 0.0 0.0
48 0.0 0.0
39 0.0 0.0
p 4 -1
0.8 0.4 0 1
37 0.0 0.0
50 0.0 0.0
49 0.0 0.0
38 0.0 0.0
p 3 -1
0.8 0.4 0 1
36 0.0 0.0
50 0.0 0.0
37 0.0 0.0
p 3 -1
0.8 0.4 0 1
36 0.0 0.0
51 0.0 0.0
50 0.0 0.0
p 4 -1
0.8 0.4 0 1
50 0.0 0.0
51 0.0 0.0
52 0.0 0.0
49 0.0 0.0
p 4 -1
0.8 0.4 0 1
49 0.0 0.0
52 0.0 0.0
53 0.0 0.0
48 0.0 0.0
p 4 -1
0.8 0.4 0 1
48 0.0 0.0
53 0.0 0.0
54 0.0 0.0
47 0.0 0.0
p 4 -1
0.8 0.4 0 1
47 0.0 0.0
54 0.0 0.0
55 0.0 0.0
46 0.0 0.0
p 4 -1
0.8 0.4 0 1
46 0.0 0.0
55 0.0 0.0
56 0.0 0.0
45 0.0 0.0
p 4 -1
0.8 0.4 0 1
45 0.0 0.0
56 0.0 0.0
57 0.0 0.0
44 0.0 0.0
p 3 -1
0.8 0.4 0 1
57 0.0 0.0
0 0.0 0.0
44 0.0 0.0
p 3 -1
0.8 0.4 0 1
1 0.0 0.0
0 0.0 0.0
57 0.0 0.0
p 4 -1
0.8 0.4 0 1
56 0.0 0.0
2 0.0 0.0
1 0.0 0.0
57 0.0 0.0
p 4 -1
0.8 0.4 0 1
55 0.0 0.0
3 0.0 0.0
2 0.0 0.0
56 0.0 0.0
p 4 -1
0.8 0.4 0 1
54 0.0 0.0
4 0.0 0.0
3 0.0 0.0
55 0.0 0.0
p 4 -1
0.8 0.4 0 1
53 0.0 0.0
5 0.0 0.0
4 0.0 0.0
54 0.0 0.0
p 4 -1
0.8 0.4 0 1
52 0.0 0.0
6 0.0 0.0
5 0.0 0.0
53 0.0 0.0
p 4 -1
0.8 0.4 0 1
51 0.0 0.0
7 0.0 0.0
6 0.0 0.0
52 0.0 0.0
p 3 -1
0.8 0.4 0 1
36 0.0 0.0
7 0.0 0.0
51 0.0 0.0
p 4 -1
0.8 0.4 0 1
40 0.0 0.0
47 0.0 0.0
59 0.0 0.0
58 0.0 0.0
p 4 -1
0.8 0.4 0 1
47 0.0 0.0
46 0.0 0.0
60 0.0 0.0
59 0.0 0.0
p 4 -1
0.8 0.4 0 1
46 0.0 0.0
41 0.0 0.0
61 0.0 0.0
60 0.0 0.0
p 4 -1
0.8 0.4 0 1
41 0.0 0.0
40 0.0 0.0
58 0.0 0.0
61 0.0 0.0
p 4 -1
0.8 0.4 0 1
25 0.0 0.0
26 0.0 0.0
63 0.0 0.0
62 0.0 0.0
p 4 -1
0.8 0.4 0 1
26 0.0 0.0
17 0.0 0.0
64 0.0 0.0
63 0.0 0.0
p 4 -1
0.8 0.4 0 1
18 0.0 0.0
25 0.0 0.0
62 0.0 0.0
65 0.0 0.0
p 4 -1
0.8 0.4 0 1
17 0.0 0.0
18 0.0 0.0
65 0.0 0.0
64 0.0 0.0
p 4 -1
0.8 0.4 0 1
62 0.0 0.0
67 0.0 0.0
66 0.0 0.0
65 0.0 0.0
p 4 -1
0.8 0.4 0 1
63 0.0 0.0
68 0.0 0.0
67 0.0 0.0
62 0.0 0.0
p 4 -1
0.8 0.4 0 1
64 0.0 0.0
69 0.0 0.0
68 0.0 0.0
63 0.0 0.0
p 4 -1
0.8 0.4 0 1
65 0.0 0.0
66 0.0 0.0
69 0.0 0.0
64 0.0 0.0
p 4 -1
0.8 0.4 0 1
66 0.0 0.0
67 0.0 0.0
68 0.0 0.0
69 0.0 0.0
p 4 -1
0.8 0.4 0 1
59 0.0 0.0
71 0.0 0.0
70 0.0 0.0
58 0.0 0.0
p 4 -1
0.8 0.4 0 1
60 0.0 0.0
72 0.0 0.0
71 0.0 0.0
59 0.0 0.0
p 4 -1
0.8 0.4 0 1
61 0.0 0.0
73 0.0 0.0
72 0.0 0.0
60 0.0 0.0
p 4 -1
0.8 0.4 0 1
58 0.0 0.0
70 0.0 0.0
73 0.0 0.0
61 0.0 0.0
p 4 -1
0.8 0.4 0 1
70 0.0 0.0
71 0.0 0.0
72 0.0 0.0
73 0.0 0.0
v -250 250 -0.01
v -250 -250 -0.01
v 250 -250 -0.01
v 250 250 -0.01
# (3=grass texture)
p 4 3
0.5 1.0 0.5 1
0 0 0
1 100 0
2 100 50
3 0 50
\ No newline at end of file
v -20 20 0
v 20 20 0
v 20 -20 0
v -20 -20 0
v -20 20 8
v 20 20 8
v 20 -20 8
v -20 -20 8
v -20 -16 8
v -20 -16 0
# (6=hek texture)
p 4 6
1.0 1.0 1.0 1
3 0 0
2 10 0
6 10 2
7 0 2
p 4 6
1.0 1.0 1.0 1
2 0 0
1 10 0
5 10 2
6 0 2
p 4 6
1.0 1.0 1.0 1
1 0 0
0 10 0
4 10 2
5 0 2
p 4 6
1.0 1.0 1.0 1
0 0 0
9 10 0
8 10 2
4 0 2
# 0-3: on ground plane
v 10 8 0
v -10 8 0
v -10 -8 0
v 10 -8 0
# 4-7: above ground plane
v 10 8 10
v -10 8 10
v -10 -8 10
v 10 -8 10
# 8-9: roof vertices
v 10 0 16
v -10 0 16
# 10-13: window hole (10x5) in long wall
v -5 -8 3
v 5 -8 3
v 5 -8 8
v -5 -8 8
# 14-17: window hole (10x5) in short wall
v 10 -5 3
v 10 5 3
v 10 5 8
v 10 -5 8
# 0: brick only
# 1: brick + window
# 2: roof
# long wall with real hole for window
# (made out of 4 quads)
# 18-21, vertices along the long edges
v -5 -8 0
v 5 -8 0
v 5 -8 10
v -5 -8 10
p 4 0
1 1 1 1
2 0.0 0.0
18 0.25 0.0
21 0.25 1.0
6 0.0 1.0
p 4 0
1 1 1 1
18 0.25 0.0
19 0.75 0.0
11 0.75 0.3
10 0.25 0.3
p 4 0
1 1 1 1
13 0.25 0.8
12 0.75 0.8
20 0.75 1.0
21 0.25 1.0
p 4 0
1 1 1 1
19 0.75 0.0
3 1.0 0.0
7 1.0 1.0
20 0.75 1.0
# short wall with real hole for window
# (made out of 4 quads)
# 22-25, vertices along the short edges
v 10 -5 0
v 10 5 0
v 10 5 10
v 10 -5 10
p 4 0
1 1 1 1
3 0.1 0.0
22 0.25 0.0
25 0.25 1.0
7 0.1 1.0
p 4 0
1 1 1 1
22 0.25 0.0
23 0.75 0.0
15 0.75 0.3
14 0.25 0.3
p 4 0
1 1 1 1
17 0.25 0.8
16 0.75 0.8
24 0.75 1.0
25 0.25 1.0
p 4 0
1 1 1 1
23 0.75 0.0
0 1.0 0.0
4 1.0 1.0
24 0.75 1.0
# long wall with fake (textured) window
p 4 1
1 1 1 1
0 0.0 0.0
1 1.0 0.0
5 1.0 1.0
4 0.0 1.0
# short wall with fake (textured) window
p 4 1
1 1 1 1
1 0.1 0.0
2 0.9 0.0
6 0.9 1.0
5 0.1 1.0
# real window in long wall
# -1 = untextured, use given color, ignore texture coordinates
# note the alpha of 0.5
p 4 -1
0.7 0.7 0.7 0.5
10 0.0 0.0
11 0.0 0.0
12 0.0 0.0
13 0.0 0.0
# real window in short wall
# -1 = untextured, use given color, ignore texture coordinates
# note the alpha of 0.5
p 4 -1
0.7 0.7 0.7 0.5
14 0.0 0.0
15 0.0 0.0
16 0.0 0.0
17 0.0 0.0
# roof polygons
p 4 2
1 1 1 1
6 0.0 0.0
7 2.0 0.0
8 2.0 1.0
9 0.0 1.0
p 4 2
1 1 1 1
4 0.0 0.0
5 2.0 0.0
9 2.0 1.0
8 0.0 1.0
# "triangles" at the side of the roof
p 3 0
1 1 1 1
7 0.1 1.0
4 0.9 1.0
8 0.5 1.6
p 3 0
1 1 1 1
5 0.1 1.0
6 0.9 1.0
9 0.5 1.6
/* Computer Graphics, Assignment, Depth-sorting and transparency
* Description ..... Depth-Sorting
* Date ............ 23.11.2009
* Created by ...... Paul Melis
*
* Student name ....
* Student email ...
* Collegekaart ....
* Date ............
* Comments ........
*
*
* (always fill in these fields before submitting!!)
*/
#if defined(__GNUC__)
#define glCheckError(s) { GLenum error; if ((error=glGetError())) \
fprintf(stderr, "* GL error - %s (%s; %s, line %d): %s\n", \
(s), __FUNCTION__,__FILE__,__LINE__, gluErrorString(error)); }
#else /* __GNUC__ */
#define glCheckError(s) { GLenum error; if ((error=glGetError())) \
fprintf(stderr, "* GL error - %s (line %d): %s\n", \
(s), __LINE__, gluErrorString(error)); }
#endif /* __GNUC__ */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#include "polys.h"
#include "readpng.h"
#include "geometry.h"
#include "bsp.h"
struct texture_data
{
const char *filename;
int contains_transparency;
};
struct texture_data texture_files[] =
{
// File name, transparency flag (the flag will be set during image loading)
{ "textures/wall_bricks_only.png", 0 },
{ "textures/wall_with_window.png", 0 },
{ "textures/roof2.png", 0 },
{ "textures/grass.png", 0 },
{ "textures/tree.png", 0 },
{ "textures/sky.png", 0 },
{ "textures/hek2.png", 0 },
{ NULL, 0 },
};
GLuint *texture_names;
int num_textures;
polys *scene_polygons;
polys *scene_opaque_polygons;
polys *scene_transparent_polygons;
polys *polylistSkydome;
BSPNode *bsp_root;
int show_textures = 0;
int show_polygons_as_lines = 0;
int do_depth_sorting = 0;
int sort_using_rays = 0;
int draw_opaque_polygons = 1;
vec3 camPosition;
float camDistance = 35.0;
float camRotZ = -45.0, camAzimuth = 20.0;
float saved_camRotZ, saved_camAzimuth, saved_camDistance;
int mouse_mode = 0;
int mx, my;
GLfloat mat_sun[] = { 1.0, 1.0, 0.5, 1.0 };
GLfloat mat_no_sun[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat mat_ambient[] = { 0.4, 0.4, 0.4, 1.0 };
GLfloat mat_diffuse[] = { 1, 1, 1, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_no_diffuse[] = { 1.0, 0.0, 0.0, 1.0 };
GLfloat mat_no_specular[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat mat_shininess[] = { 50.0 };
GLfloat mat_no_shininess[] = { 0.0 };
GLfloat light_position[] = { -8.0, -8.0, 8.0, 0.0 };
GLfloat light_ambient[] = { 0.4, 0.4, 0.4, 0.0 };
GLfloat light_diffuse[] = { 0.6, 0.6, 0.6, 0.0 };
// Rough center points of the objects in the scene.
// Note: these positions are only used for rotating around them
// with the camera, not to place objects in the scene.
#define NUM_OBJECTS 4
vec3 object_positions[NUM_OBJECTS] =
{
/* house, goldfish, tree, somewhere at the side of the house */
{0.0, 0.0, 5.0},
{0.0, 0.0, 4.5},
{5.0, 18.0, 10.0},
{0.0, 10.0, 0.0},
};
// Determines around which object the camera rotates
int current_object = 0;
void
InitializePolygonlists(void)
{
polys *model_polygons;
poly p;
scene_polygons = CreatePolylist(128);
model_polygons = CreatePolylist(128);
// Load the models from .obj files and create a single polylist
// (scene_polygons) to hold all polygons
// House
loadPolygonalObject(model_polygons, "house.obj", texture_names, num_textures,
1.0, 0.0, 0.0, 0.0);
AppendPolylist(scene_polygons, model_polygons);
// Ground
ClearPolylist(model_polygons);
loadPolygonalObject(model_polygons, "ground.obj", texture_names, num_textures,
1.0, 0.0, 0.0, 0.0);
AppendPolylist(scene_polygons, model_polygons);
// Table
ClearPolylist(model_polygons);
loadPolygonalObject(model_polygons, "table.obj", texture_names, num_textures,
1.0, 0.0, 0.0, 0.0);
AppendPolylist(scene_polygons, model_polygons);
#if 0
// Tree
ClearPolylist(model_polygons);
loadPolygonalObject(model_polygons, "tree.obj", texture_names, num_textures,
0.6, 5.0, 16.0, 0.0);
AppendPolylist(scene_polygons, model_polygons);
#endif
#if 0
// Fish bowl
ClearPolylist(model_polygons);
loadPolygonalObject(model_polygons, "fishbowl.obj", texture_names, num_textures,
1.0, 0.0, 0.0, 0.0);
AppendPolylist(scene_polygons, model_polygons);
// Goldfish
ClearPolylist(model_polygons);
loadPolygonalObject(model_polygons, "goldfish.obj", texture_names, num_textures,
1.0, 0.0, 0.0, 0.0);
AppendPolylist(scene_polygons, model_polygons);
#endif
#if 0
// Fence
ClearPolylist(model_polygons);
loadPolygonalObject(model_polygons, "hek.obj", texture_names, num_textures,
1.0, 0.0, 0.0, 0.0);
AppendPolylist(scene_polygons, model_polygons);
#endif
#if 0
// A transparent cow (moooh!)
ClearPolylist(model_polygons);
loadPolygonalObject(model_polygons, "cow.obj", texture_names, num_textures,
10.0, -3.0, -15.0, 0.0);
AppendPolylist(scene_polygons, model_polygons);
#endif
// The skydome
polylistSkydome = CreatePolylist(1000);
createHemisphere(polylistSkydome, 250, 0, 0, 0, 1, 1, 1);
for (int i = 0; i < polylistSkydome->length; i++)
polylistSkydome->items[i].opengl_texture_name = texture_names[5];
// Done!
printf("%d polygons in the scene\n", scene_polygons->length);
//
// Sort polygons by type (opaque versus transparent)
//
// Estimate needed list size
scene_opaque_polygons = CreatePolylist(scene_polygons->length/2);
scene_transparent_polygons = CreatePolylist(scene_polygons->length/2);
for (int i = 0; i < scene_polygons->length; i++)
{
p = scene_polygons->items[i];
if (
// Non-textured transparent polygon
(p.texture_id == -1 && p.color[3] < 1.0)
||
// Textured transparent polygon
(p.texture_id >= 0 && texture_files[p.texture_id].contains_transparency)
)
{
// We split quads into two triangles, so that all transparent
// geometry is defined with triangles only. This makes the
// splitting during BSP construction much easier as
// we only have to handle one type of primitive that can be
// split in only a few ways.
if (p.points == 4)
{
poly q = p;
// q is defined by points 0, 1 and 2 of p
q.points = 3;
AddPolyToPolylist(scene_transparent_polygons, q);
// second q is defined by points 0, 2 and 3 of p
q.pts[1] = p.pts[2];
q.tcoord[1] = p.tcoord[2];
q.pts[2] = p.pts[3];
q.tcoord[2] = p.tcoord[3];
AddPolyToPolylist(scene_transparent_polygons, q);
}
else if (p.points == 3)
AddPolyToPolylist(scene_transparent_polygons, p);
else
printf("Skipping polygon with %d points, only quads or triangles allowed\n", p.points);
}
else
{
// Opaque polygon
AddPolyToPolylist(scene_opaque_polygons, p);
}
}
printf("%d opaque polygons\n", scene_opaque_polygons->length);
printf("%d transparent polygons\n", scene_transparent_polygons->length);
// Build BSP tree
bsp_root = BuildBSPTreeIncorrect(scene_transparent_polygons);
}
void
InitGL(void)
{
GLvoid *image_data;
int i, width, height;
int has_alpha_channel;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat) 800 / (GLfloat) 600, 0.1f, 1000.0f);
glClearColor(0.7, 0.7, 1, 1);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE); // We want 2-sided geometry
glEnable(GL_COLOR_MATERIAL);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_no_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_no_shininess);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Using GL_REPLACE will effectively disable lighting.
// The default mode, GL_MODULATE, will use the texture color to
// module the shaded material color, so the end result still
// contains the shading.
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// generate OpenGL texture names
num_textures = 0;
for (i = 0; texture_files[i].filename != NULL; i++)
num_textures++;
texture_names = malloc(num_textures * sizeof(GLuint));
glGenTextures(num_textures, texture_names);
glCheckError("glGenTextures");
// create textures from image files
GLint texture_internal_format;
GLenum texture_format, texture_type;
for (i = 0; i < num_textures; i++)
{
image_data = (GLvoid *) readPNGFile(texture_files[i].filename, &width, &height, &has_alpha_channel);
if (image_data)
{
printf("texture %d (OpenGL name = %d): %s, %d x %d\n", i,
texture_names[i], texture_files[i].filename, width, height);
if (has_alpha_channel)
{
// Convert the RGB image to RGBA, by replacing
// red pixels with transparent ones
printf("... contains alpha channel\n");
texture_files[i].contains_transparency = 1;
texture_internal_format = GL_RGBA8;
texture_format = GL_RGBA;
texture_type = GL_UNSIGNED_BYTE;
}
else
{
texture_internal_format = GL_RGB8;
texture_format = GL_RGB;
texture_type = GL_UNSIGNED_BYTE;
}
glBindTexture(GL_TEXTURE_2D, texture_names[i]);
glCheckError("glBindTexture");
#if 0
// No mipmapping
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glCheckError("glTexParameteri");
glTexImage2D(GL_TEXTURE_2D, 0, texture_internal_format,
width, height, 0, texture_format, texture_type, image_data);
glCheckError("glTexImage2D");
#else
// Mipmapping
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glCheckError("glTexParameteri");
gluBuild2DMipmaps(GL_TEXTURE_2D, texture_internal_format, width, height,
texture_format, texture_type, image_data);
glCheckError("gluBuild2DMipmaps");
#endif
// Free the image data, as OpenGL will have made its internal
// copy by now
free(image_data);
}
else
{
perror(texture_files[i].filename);
exit(0);
}
}
}
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, 1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// Draw a single polygon, taking into account the texture
// and transparency properties of the polygon
void
DrawPolygon(poly p)
{
if (p.opengl_texture_name >= 0)
{
// Textured
glColor3f(p.color[0], p.color[1], p.color[2]);
glBindTexture(GL_TEXTURE_2D, p.opengl_texture_name);
}
else
{
// Untextured (but colored and possibly with alpha transparency)
glColor4f(p.color[0], p.color[1], p.color[2], p.color[3]);
glBindTexture(GL_TEXTURE_2D, 0);
}
glBegin(GL_POLYGON);
for (int j = 0; j < p.points; j++)
{
glNormal3f(p.normal[j].x, p.normal[j].y, p.normal[j].z);
glTexCoord2f(p.tcoord[j].x, p.tcoord[j].y);
glVertex3f(p.pts[j].x, p.pts[j].y, p.pts[j].z);
}
glEnd();
}
// Draw all the polygons in a list
void
DrawPolylist(polys * list)
{
int i;
for (i = 0; i < list->length; i++)
DrawPolygon(list->items[i]);
}
// Use the BSP tree to draw transparent geometry in the correct
// order, based on the given eye position
void
DrawBSPTree(BSPNode *node, vec3 eye_position)
{
}
void
SetupCamera(void)
{
float cx, cy, cz;
float t;
float beta, gamma;
vec3 op;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Verbose, but straightforward way, of positioning the camera.
// Assume the camera's final position is (cx, cy, cz) and Z is up.
// 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.
// 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);
// Translate view to rotate around the selected object
op = object_positions[current_object];
gluLookAt(cx+op.x, cy+op.y, cz+op.z, op.x, op.y, op.z, 0.0, 0.0, 1.0);
camPosition.x = cx + op.x;
camPosition.y = cy + op.y;
camPosition.z = cz + op.z;
}
void
DrawGLScene(void)
{
float tx, ty, tz;
float a, rx, ry, rz;
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
// set camera based on previous mouse input
SetupCamera();
// Set the light position. We do that after setting up the
// camera so that the light position will keep its world position.
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
// Draw the scene
if (show_polygons_as_lines)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDisable(GL_TEXTURE_2D);
}
else
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
if (show_textures)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
}
else
glDisable(GL_TEXTURE_2D);
}
if (draw_opaque_polygons)
{
DrawPolylist(scene_opaque_polygons);
// Draw the skydome with lighting turned off
glPushAttrib(GL_LIGHTING_BIT);
glDisable(GL_LIGHTING);
glPushMatrix();
glRotatef(90, 1, 0, 0);
DrawPolylist(polylistSkydome);
glPopMatrix();
glPopAttrib();
}
// XXX use BSP to draw
DrawBSPTree(bsp_root, camPosition);
#if 0
// Axes
glPushAttrib(GL_LIGHTING_BIT);
glDisable(GL_LIGHTING);
glBegin(GL_LINES);
glColor3f(1,0,0);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glColor3f(0,1,0);
glVertex3f(0,0,0);
glVertex3f(0,1,0);
glColor3f(0,0,1);
glVertex3f(0,0,0);
glVertex3f(0,0,1);
glEnd();
glPopAttrib();
#endif
// Finally, swap back and front buffers
glutSwapBuffers();
}
void
keyPressed(unsigned char key, int x, int y)
{
(void)x;
(void)y;
switch (key)
{
case 'o':
draw_opaque_polygons = 1 - draw_opaque_polygons;
glutPostRedisplay();
break;
case 't':
show_textures = 1 - show_textures;
glutPostRedisplay();
break;
case 'l':
show_polygons_as_lines = 1;
glutPostRedisplay();
break;
case 'p':
show_polygons_as_lines = 0;
glutPostRedisplay();
break;
case 'd':
do_depth_sorting = 1 - do_depth_sorting;
printf("Depth sorting now %s\n", do_depth_sorting ? "on" : "off");
glutPostRedisplay();
break;
case 'r':
sort_using_rays = 1 - sort_using_rays;
printf("Depth sorting using rays now %s\n", sort_using_rays ? "on" : "off");
glutPostRedisplay();
break;
case 'v':
current_object = (current_object + 1) % NUM_OBJECTS;
glutPostRedisplay();
break;
case 'q':
exit(-1);
}
}
void
specialKeyPressed(int key, int x, int y)
{
(void)x;
(void)y;
(void)key;
DrawGLScene();
}
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.1)
camDistance = 0.1;
else if (camDistance > 1000.0)
camDistance = 1000.0;
}
}
int
main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_ALPHA | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutInitWindowPosition(0, 0);
glutCreateWindow("OpenGL Framework");
glutDisplayFunc(&DrawGLScene);
glutIdleFunc(&DrawGLScene);
glutReshapeFunc(&ReSizeGLScene);
glutSpecialFunc(&specialKeyPressed);
glutKeyboardFunc(&keyPressed);
glutMouseFunc(&mouseFunc);
glutMotionFunc(&motionFunc);
InitGL();
InitializePolygonlists();
glutMainLoop();
return 1;
}
/* Computer Graphics
*
* 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;
}
void
ClearPolylist(polys *list)
{
list->length = 0;
}
/* exit() if no memory available, returns 0 if poly* is NULL, 1 otherwise */
static 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. */
static 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)
{
if (list == NULL)
return;
/* 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++;
}
/* Append the items of 'to_append' to 'list' */
void
AppendPolylist(polys *list, polys *to_append)
{
for (int i = 0; i < to_append->length; i++)
AddPolyToPolylist(list, to_append->items[i]);
}
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;
}
/* Computer Graphics
*
* Filename ........ polys.h
* Description ..... Functions to manage lists of polygons (header file)
* Date ............ 19.08.2008
* Created by ...... Jurgen Sturm
* Cleaned up by ... Paul Melis
*/
#ifndef POLYS_H
#define POLYS_H
#include <GL/gl.h>
#include "v3math.h"
#define MAX_VERTICES 4
typedef struct poly
{
// Number of vertices
int points;
// Vertices and their normals
vec3 pts[MAX_VERTICES];
vec3 normal[MAX_VERTICES];
// Overall polygon color
GLfloat color[4];
// Texture identifier as set in a .obj file (can be -1)
int texture_id;
// OpenGL texture name
// (note: signed, so we can use -1 to denote 'no texture')
GLint opengl_texture_name;
// Texture coordinates per vertex
vec3 tcoord[MAX_VERTICES];
}
poly;
typedef struct polys
{
/* size of the poly array "items" below */
int capacity;
/* number of poly's stored, also index of the first free position
* in the "items" array. If this number is equal to "capacity" above,
* then this list is full */
int length;
/* array of polygons, with length "capacity" of which only the first "length"
* items will be in use */
poly *items;
}
polys;
/* Create an empty list of polys, initially reserving space for 'n' polys */
polys* CreatePolylist(int n);
/* Destroy a list of polygons */
void DestroyPolylist(polys *list);
/* 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);
/* Append the items of 'to_append' to 'list' */
void AppendPolylist(polys *list, polys *to_append);
/* Copies the list of polys `list', calls AddPolytoPolylist() for each poly
* in the given list. */
polys* CopyPolylist(polys *list);
/* Clear a list of polygons. Note: this does not de-allocate the item array */
void ClearPolylist(polys *list);
#endif
/*
The following code is based on:
http://www.iwr.uni-heidelberg.de/groups/ngg/CG200708/Txt/png.c
The original copyright notice:
* png.c -- png texture loader
* last modification: aug. 14, 2007
*
* Copyright (c) 2005-2007 David HENRY
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* gcc -Wall -ansi -lGL -lGLU -lglut
* `libpng12-config --cflags --libs` png.c -o png
*/
#include <stdio.h>
#include <stdlib.h>
#include <png.h>
#include "readpng.h"
// Returns NULL if loading failed, or a pointer to
// a malloc()ed pixel buffer otherwise.
// The output parameters width, height and has_alpha_channel will be
// set apropriately in the latter case
GLubyte*
readPNGFile(const char *filename, int *width, int *height, int *has_alpha_channel)
{
png_byte magic[8];
png_structp png_ptr;
png_infop info_ptr;
png_uint_32 w, h;
png_bytep *row_pointers = NULL;
GLubyte *texels;
int bytes_per_pixel;
int bit_depth, color_type;
FILE *f;
int i;
f = fopen (filename, "rb");
if (!f)
{
fprintf(stderr, "Could not open '%s'!\n", filename);
return NULL;
}
// Read and check magic number
fread(magic, 1, sizeof (magic), f);
if (!png_check_sig(magic, sizeof(magic)))
{
fprintf(stderr, "Not a valid PNG file: '%s'\n", filename);
fclose(f);
return NULL;
}
// Create png read struct
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
{
fclose(f);
return NULL;
}
// Create png info struct
info_ptr = png_create_info_struct (png_ptr);
if (!info_ptr)
{
fclose(f);
png_destroy_read_struct (&png_ptr, NULL, NULL);
return NULL;
}
if (setjmp (png_jmpbuf (png_ptr)))
{
fclose(f);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
if (row_pointers)
free(row_pointers);
// XXX free texels
return NULL;
}
png_init_io(png_ptr, f);
png_set_sig_bytes(png_ptr, sizeof (magic));
// Read png info
png_read_info(png_ptr, info_ptr);
// Get some data from the header
bit_depth = png_get_bit_depth(png_ptr, info_ptr);
color_type = png_get_color_type(png_ptr, info_ptr);
// Check if we can handle this image type
if (bit_depth != 8)
{
// XXX proper cleanup
return NULL;
}
if (color_type == PNG_COLOR_TYPE_RGB)
{
bytes_per_pixel = 3;
*has_alpha_channel = 0;
}
else if (color_type == PNG_COLOR_TYPE_RGBA)
{
bytes_per_pixel = 4;
*has_alpha_channel = 1;
}
else
{
return NULL;
}
png_get_IHDR (png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, NULL, NULL, NULL);
*width = w;
*height = h;
// Allocate memory for pixel data
texels = (GLubyte*) malloc(w * h * bytes_per_pixel);
// Allocate memory for the row pointers array
row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * h);
// Set up the row pointers
for (i = 0; i < h; ++i)
row_pointers[i] = (png_bytep) (texels + (h - (i + 1)) * w * bytes_per_pixel);
// Read pixel data using the row pointers
png_read_image(png_ptr, row_pointers);
// Finish decompression and release memory
png_read_end(png_ptr, NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
// Cleanup
free(row_pointers);
fclose(f);
return texels;
}
#ifndef READPNG_H
#define READPNG_H
#include <GL/gl.h>
GLubyte* readPNGFile(const char *filename, int *width, int *height, int *has_alpha_channel);
#endif
v 2.627827 2.556087 0.025656
v 2.627827 2.214265 0.025656
v 2.286005 2.214265 0.025656
v 2.286005 2.556087 0.025656
v 2.627827 2.556087 3.596503
v 2.627827 2.214265 3.596503
v 2.286005 2.214265 3.596503
v 2.286005 2.556087 3.596503
v 2.627827 -2.316548 0.025656
v 2.627827 -2.658370 0.025656
v 2.286005 -2.658370 0.025656
v 2.286005 -2.316548 0.025656
v 2.627827 -2.316548 3.596503
v 2.627827 -2.658370 3.596503
v 2.286005 -2.658370 3.596503
v 2.286005 -2.316548 3.596503
v -2.230601 -2.316548 0.025656
v -2.230601 -2.658370 0.025656
v -2.572424 -2.658370 0.025656
v -2.572423 -2.316548 0.025656
v -2.230601 -2.316548 3.596503
v -2.230602 -2.658370 3.596503
v -2.572424 -2.658370 3.596503
v -2.572424 -2.316548 3.596503
v -2.230601 2.556087 0.025656
v -2.230601 2.214265 0.025656
v -2.572424 2.214265 0.025656
v -2.572423 2.556087 0.025656
v -2.230601 2.556087 3.596503
v -2.230602 2.214265 3.596503
v -2.572424 2.214265 3.596503
v -2.572424 2.556087 3.596503
v 2.781483 2.781482 3.530788
v 2.781483 -2.781483 3.530788
v -2.781483 -2.781482 3.530788
v -2.781482 2.781484 3.530788
v 2.781484 2.781481 3.673192
v 2.781481 -2.781484 3.673192
v -2.781484 -2.781482 3.673192
v -2.781482 2.781483 3.673192
p 4 -1
0.8 0.2 0.1 1
0 0.0 0.0
4 0.0 0.0
5 0.0 0.0
1 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
1 0.0 0.0
5 0.0 0.0
6 0.0 0.0
2 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
2 0.0 0.0
6 0.0 0.0
7 0.0 0.0
3 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
4 0.0 0.0
0 0.0 0.0
3 0.0 0.0
7 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
8 0.0 0.0
12 0.0 0.0
13 0.0 0.0
9 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
9 0.0 0.0
13 0.0 0.0
14 0.0 0.0
10 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
10 0.0 0.0
14 0.0 0.0
15 0.0 0.0
11 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
12 0.0 0.0
8 0.0 0.0
11 0.0 0.0
15 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
16 0.0 0.0
20 0.0 0.0
21 0.0 0.0
17 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
17 0.0 0.0
21 0.0 0.0
22 0.0 0.0
18 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
18 0.0 0.0
22 0.0 0.0
23 0.0 0.0
19 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
20 0.0 0.0
16 0.0 0.0
19 0.0 0.0
23 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
24 0.0 0.0
28 0.0 0.0
29 0.0 0.0
25 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
25 0.0 0.0
29 0.0 0.0
30 0.0 0.0
26 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
26 0.0 0.0
30 0.0 0.0
31 0.0 0.0
27 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
28 0.0 0.0
24 0.0 0.0
27 0.0 0.0
31 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
32 0.0 0.0
33 0.0 0.0
34 0.0 0.0
35 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
36 0.0 0.0
39 0.0 0.0
38 0.0 0.0
37 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
32 0.0 0.0
36 0.0 0.0
37 0.0 0.0
33 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
33 0.0 0.0
37 0.0 0.0
38 0.0 0.0
34 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
34 0.0 0.0
38 0.0 0.0
39 0.0 0.0
35 0.0 0.0
p 4 -1
0.8 0.2 0.1 1
36 0.0 0.0
32 0.0 0.0
35 0.0 0.0
39 0.0 0.0
graphics/ass11/textures/grass.png

132 KiB

graphics/ass11/textures/hek2.png

352 B

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