glide_test1

annotate main.cpp @ 0:f3ddb2bb7024

first 3dfx glide test, initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 09 Mar 2014 06:27:58 +0200
parents
children
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 }