rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include <stdlib.h>
|
nuclear@0
|
3 #include <glide.h>
|
nuclear@0
|
4 #include <windows.h>
|
nuclear@0
|
5 #include "mesh.h"
|
nuclear@0
|
6
|
nuclear@0
|
7 #define XSZ 640
|
nuclear@0
|
8 #define YSZ 480
|
nuclear@0
|
9
|
nuclear@0
|
10 void display(unsigned int msec);
|
nuclear@0
|
11 void process_vertex(Vertex *vres, const Vertex &vin);
|
nuclear@0
|
12 void draw_mesh(const std::vector<Vertex> &varr);
|
nuclear@0
|
13 void draw_triangle(const Vertex *v);
|
nuclear@0
|
14
|
nuclear@0
|
15 unsigned int start_time;
|
nuclear@0
|
16 Matrix4x4 mv_matrix, proj_matrix, norm_matrix;
|
nuclear@0
|
17 Vector4 mat_diffuse;
|
nuclear@0
|
18 Vector3 light_dir;
|
nuclear@0
|
19 std::vector<Vertex> torus;
|
nuclear@0
|
20
|
nuclear@0
|
21 int main(void)
|
nuclear@0
|
22 {
|
nuclear@0
|
23 GrHwConfiguration hwcfg;
|
nuclear@0
|
24
|
nuclear@0
|
25 if(!grSstQueryBoards(&hwcfg)) {
|
nuclear@0
|
26 fprintf(stderr, "No 3dfx graphics boards detected!\n");
|
nuclear@0
|
27 return 1;
|
nuclear@0
|
28 }
|
nuclear@0
|
29 printf("Found %d 3dfx graphics boards!\n", hwcfg.num_sst);
|
nuclear@0
|
30
|
nuclear@0
|
31 grGlideInit();
|
nuclear@0
|
32 if(!grSstQueryHardware(&hwcfg)) {
|
nuclear@0
|
33 fprintf(stderr, "No 3dfx graphics hardware detected!\n");
|
nuclear@0
|
34 return 1;
|
nuclear@0
|
35 }
|
nuclear@0
|
36 grSstSelect(0);
|
nuclear@0
|
37
|
nuclear@0
|
38 if(!grSstWinOpen(0, GR_RESOLUTION_640x480, GR_REFRESH_60Hz, GR_COLORFORMAT_RGBA,
|
nuclear@0
|
39 GR_ORIGIN_UPPER_LEFT, 2, 1)) {
|
nuclear@0
|
40 fprintf(stderr, "Failed to initialize glide device\n");
|
nuclear@0
|
41 return 1;
|
nuclear@0
|
42 }
|
nuclear@0
|
43
|
nuclear@0
|
44 printf("Voodoo graphics initialized sucessfully!\n");
|
nuclear@0
|
45
|
nuclear@0
|
46 // setup projection matrix
|
nuclear@0
|
47 proj_matrix.perspective(45.0f, 1.3333333f, 0.5, 250.0);
|
nuclear@0
|
48
|
nuclear@0
|
49 // generate torus mesh
|
nuclear@0
|
50 gen_torus(torus, 1.5, 0.5, 24, 12);
|
nuclear@0
|
51
|
nuclear@0
|
52 // light
|
nuclear@0
|
53 light_dir = normalize(Vector3(-0.6f, 1.0f, 2.0f));
|
nuclear@0
|
54
|
nuclear@0
|
55 // enable W-buffer (depth buffer)
|
nuclear@0
|
56 grDepthBufferMode(GR_DEPTHBUFFER_WBUFFER);
|
nuclear@0
|
57 grDepthMask(1);
|
nuclear@0
|
58 grDepthBufferFunction(GR_CMP_LESS);
|
nuclear@0
|
59
|
nuclear@0
|
60 // main loop
|
nuclear@0
|
61 start_time = GetTickCount();
|
nuclear@0
|
62 unsigned int msec = 0;
|
nuclear@0
|
63 while((msec = GetTickCount() - start_time) < 8000) {
|
nuclear@0
|
64 display(msec);
|
nuclear@0
|
65 }
|
nuclear@0
|
66
|
nuclear@0
|
67 grGlideShutdown();
|
nuclear@0
|
68 return 0;
|
nuclear@0
|
69 }
|
nuclear@0
|
70
|
nuclear@0
|
71 void display(unsigned int msec)
|
nuclear@0
|
72 {
|
nuclear@0
|
73 float t = (float)msec / 1000.0f;
|
nuclear@0
|
74
|
nuclear@0
|
75 grBufferClear(0x103060ff, 255, GR_WDEPTHVALUE_FARTHEST);
|
nuclear@0
|
76
|
nuclear@0
|
77 mv_matrix.set_identity();
|
nuclear@0
|
78 mv_matrix.translate(0, 0, -8);
|
nuclear@0
|
79 mv_matrix.rotate(t * 100.0f, 1, 0, 0);
|
nuclear@0
|
80 mv_matrix.rotate(t * 80.0f, 0, 0, 1);
|
nuclear@0
|
81
|
nuclear@0
|
82 norm_matrix = mv_matrix;
|
nuclear@0
|
83 norm_matrix[0][3] = norm_matrix[1][3] = norm_matrix[2][3] = 0.0f;
|
nuclear@0
|
84 norm_matrix[3][0] = norm_matrix[3][1] = norm_matrix[3][2] = 0.0f;
|
nuclear@0
|
85 norm_matrix[3][3] = 1.0f;
|
nuclear@0
|
86
|
nuclear@0
|
87 mat_diffuse = Vector4(1.0f, 0.6f, 0.2f, 1.0f);
|
nuclear@0
|
88 draw_mesh(torus);
|
nuclear@0
|
89
|
nuclear@0
|
90 grBufferSwap(1);
|
nuclear@0
|
91 }
|
nuclear@0
|
92
|
nuclear@0
|
93
|
nuclear@0
|
94 void process_vertex(Vertex *vres, const Vertex &vin)
|
nuclear@0
|
95 {
|
nuclear@0
|
96 // transform with the modelview matrix
|
nuclear@0
|
97 vres->pos = transform(vin.pos, mv_matrix);
|
nuclear@0
|
98 vres->normal = transform(vin.normal, norm_matrix);
|
nuclear@0
|
99
|
nuclear@0
|
100 // calculate lighting
|
nuclear@0
|
101 float ndotl = dot(vres->normal, light_dir);
|
nuclear@0
|
102 if(ndotl < 0.0) ndotl = 0.0;
|
nuclear@0
|
103
|
nuclear@0
|
104 Vector3 vdir(0, 0, 1);
|
nuclear@0
|
105 Vector3 half_dir = normalize(vdir + light_dir);
|
nuclear@0
|
106 float ndoth = dot(vres->normal, half_dir);
|
nuclear@0
|
107 if(ndoth < 0.0) ndoth = 0.0;
|
nuclear@0
|
108 float spec = pow(ndoth, 32.0);
|
nuclear@0
|
109
|
nuclear@0
|
110 float red = mat_diffuse.x * ndotl + spec;
|
nuclear@0
|
111 float green = mat_diffuse.y * ndotl + spec;
|
nuclear@0
|
112 float blue = mat_diffuse.z * ndotl + spec;
|
nuclear@0
|
113
|
nuclear@0
|
114
|
nuclear@0
|
115 vres->color.x = red > 1.0 ? 1.0 : red;
|
nuclear@0
|
116 vres->color.y = green > 1.0 ? 1.0 : green;
|
nuclear@0
|
117 vres->color.z = blue > 1.0 ? 1.0 : blue;
|
nuclear@0
|
118 vres->color.w = mat_diffuse.w;
|
nuclear@0
|
119
|
nuclear@0
|
120
|
nuclear@0
|
121 // transform with the projection matrix
|
nuclear@0
|
122 vres->pos = transform(vres->pos, proj_matrix);
|
nuclear@0
|
123
|
nuclear@0
|
124 // perspective division
|
nuclear@0
|
125 vres->pos.x = vres->pos.x / vres->pos.w;
|
nuclear@0
|
126 vres->pos.y = vres->pos.y / vres->pos.w;
|
nuclear@0
|
127 vres->pos.z = vres->pos.z / vres->pos.w;
|
nuclear@0
|
128
|
nuclear@0
|
129 // viewport transformation
|
nuclear@0
|
130 vres->pos.x = (vres->pos.x * 0.5 + 0.5) * (float)XSZ;
|
nuclear@0
|
131 vres->pos.y = (vres->pos.y * 0.5 + 0.5) * (float)YSZ;
|
nuclear@0
|
132 }
|
nuclear@0
|
133
|
nuclear@0
|
134
|
nuclear@0
|
135 void draw_mesh(const std::vector<Vertex> &varr)
|
nuclear@0
|
136 {
|
nuclear@0
|
137 static Vertex face_vert[3];
|
nuclear@0
|
138 size_t num = varr.size();
|
nuclear@0
|
139
|
nuclear@0
|
140 int face_vert_idx = 0;
|
nuclear@0
|
141
|
nuclear@0
|
142 for(int i=0; i<num; i++) {
|
nuclear@0
|
143 process_vertex(face_vert + face_vert_idx, varr[i]);
|
nuclear@0
|
144
|
nuclear@0
|
145 if(++face_vert_idx >= 3) {
|
nuclear@0
|
146 draw_triangle(face_vert);
|
nuclear@0
|
147 face_vert_idx = 0;
|
nuclear@0
|
148 }
|
nuclear@0
|
149 }
|
nuclear@0
|
150 }
|
nuclear@0
|
151
|
nuclear@0
|
152 void draw_triangle(const Vertex *v)
|
nuclear@0
|
153 {
|
nuclear@0
|
154 GrVertex face[3];
|
nuclear@0
|
155
|
nuclear@0
|
156 for(int i=0; i<3; i++) {
|
nuclear@0
|
157 face[i].x = v[i].pos.x;
|
nuclear@0
|
158 face[i].y = v[i].pos.y;
|
nuclear@0
|
159 face[i].r = v[i].color.x * 255.0;
|
nuclear@0
|
160 face[i].g = v[i].color.y * 255.0;
|
nuclear@0
|
161 face[i].b = v[i].color.z * 255.0;
|
nuclear@0
|
162 face[i].a = v[i].color.w * 255.0;
|
nuclear@0
|
163 face[i].oow = 1.0f / v[i].pos.w;
|
nuclear@0
|
164 }
|
nuclear@0
|
165
|
nuclear@0
|
166 grDrawTriangle(face, face + 1, face + 2);
|
nuclear@0
|
167 } |