gpmark
diff src/engine3d.cpp @ 0:5019d031b485
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 05 Jun 2013 22:33:37 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/engine3d.cpp Wed Jun 05 22:33:37 2013 +0300 1.3 @@ -0,0 +1,274 @@ 1.4 +#include <math.h> 1.5 +#include <stdio.h> 1.6 + 1.7 +#include "engine3d.h" 1.8 +#include "generate3d.h" 1.9 +#include "render3d.h" 1.10 +#include "main.h" 1.11 + 1.12 +point3d fpts[MAXDATA]; 1.13 +point3d norms[MAXDATA]; 1.14 +point3d pt_norms[MAXDATA]; 1.15 +point2d spts[MAXDATA]; 1.16 +point3d spls[MAXDATA]; 1.17 + 1.18 +unsigned short swp[MAXDATA]; 1.19 + 1.20 +int lightcalc = LIGHTVIEW; 1.21 + 1.22 +#define fp_mul 256 1.23 +#define fp_shr 8 1.24 +#define proj_shr 8 1.25 + 1.26 + 1.27 +vector3d CrossProduct(vector3d v1, vector3d v2) 1.28 +{ 1.29 + vector3d v; 1.30 + v.x=v1.y*v2.z-v1.z*v2.y; 1.31 + v.y=v1.z*v2.x-v1.x*v2.z; 1.32 + v.z=v1.x*v2.y-v1.y*v2.x; 1.33 + return v; 1.34 +} 1.35 + 1.36 + 1.37 +int DotProduct(vector3d v1, vector3d v2) 1.38 +{ 1.39 + return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; 1.40 +} 1.41 + 1.42 + 1.43 +vector3d Normalize(vector3d v) 1.44 +{ 1.45 + int d=(int)(sqrt(v.x*v.x+v.y*v.y+v.z*v.z)); 1.46 + if (d!=0) 1.47 + { 1.48 + v.x=(v.x<<fp_shr)/d; 1.49 + v.y=(v.y<<fp_shr)/d; 1.50 + v.z=(v.z<<fp_shr)/d; 1.51 + } 1.52 + else 1.53 + { 1.54 + v.x = 0; 1.55 + v.y = 0; 1.56 + v.z = 0; 1.57 + } 1.58 + return v; 1.59 +} 1.60 + 1.61 + 1.62 +vector3d NegVec(vector3d v) 1.63 +{ 1.64 + v.x=-v.x; 1.65 + v.y=-v.y; 1.66 + v.z=-v.z; 1.67 + return v; 1.68 +} 1.69 + 1.70 + 1.71 +void translate3d (object3d *obj) 1.72 +{ 1.73 + int i; 1.74 + int objposx = (int)(obj->pos.x * fp_mul); 1.75 + int objposy = (int)(obj->pos.y * fp_mul); 1.76 + int objposz = (int)(obj->pos.z * fp_mul); 1.77 + 1.78 + for (i=0; i<obj->npts; i++) 1.79 + { 1.80 + fpts[i].x += objposx; 1.81 + fpts[i].y += objposy; 1.82 + fpts[i].z += objposz; 1.83 + } 1.84 +} 1.85 + 1.86 +void rotate3d (object3d *obj) 1.87 +{ 1.88 + float cosxr = cos(obj->rot.x); float cosyr = cos(obj->rot.y); float coszr = cos(obj->rot.z); 1.89 + float sinxr = sin(obj->rot.x); float sinyr = sin(obj->rot.y); float sinzr = sin(obj->rot.z); 1.90 + 1.91 + int xvx = (int)((cosyr * coszr) * fp_mul); int xvy = (int)((sinxr * sinyr * coszr - cosxr * sinzr) * fp_mul); int xvz = (int)((cosxr * sinyr * coszr + sinxr * sinzr) * fp_mul); 1.92 + int yvx = (int)((cosyr * sinzr) * fp_mul); int yvy = (int)((cosxr * coszr + sinxr * sinyr * sinzr) * fp_mul); int yvz = (int)((-sinxr * coszr + cosxr * sinyr * sinzr) * fp_mul); 1.93 + int zvx = (int)((-sinyr) * fp_mul); int zvy = (int)((sinxr * cosyr) * fp_mul); int zvz = (int)((cosxr * cosyr) * fp_mul); 1.94 + 1.95 + int x, y, z; 1.96 + int i; 1.97 + for (i=0; i<obj->npts; i++) 1.98 + { 1.99 + x = obj->point[i].x; 1.100 + y = obj->point[i].y; 1.101 + z = obj->point[i].z; 1.102 + fpts[i].x = x * xvx + y * xvy + z * xvz; 1.103 + fpts[i].y = x * yvx + y * yvy + z * yvz; 1.104 + fpts[i].z = x * zvx + y * zvy + z * zvz; 1.105 + } 1.106 +} 1.107 + 1.108 + 1.109 +void rotate3d_normals (object3d *obj) 1.110 +{ 1.111 + float cosxr = cos(obj->rot.x); float cosyr = cos(obj->rot.y); float coszr = cos(obj->rot.z); 1.112 + float sinxr = sin(obj->rot.x); float sinyr = sin(obj->rot.y); float sinzr = sin(obj->rot.z); 1.113 + 1.114 + int xvx = (int)((cosyr * coszr) * fp_mul); int xvy = (int)((sinxr * sinyr * coszr - cosxr * sinzr) * fp_mul); int xvz = (int)((cosxr * sinyr * coszr + sinxr * sinzr) * fp_mul); 1.115 + int yvx = (int)((cosyr * sinzr) * fp_mul); int yvy = (int)((cosxr * coszr + sinxr * sinyr * sinzr) * fp_mul); int yvz = (int)((-sinxr * coszr + cosxr * sinyr * sinzr) * fp_mul); 1.116 + int zvx = (int)((-sinyr) * fp_mul); int zvy = (int)((sinxr * cosyr) * fp_mul); int zvz = (int)((cosxr * cosyr) * fp_mul); 1.117 + 1.118 + int x, y, z; 1.119 + int i; 1.120 + for (i=0; i<obj->npls; i++) 1.121 + { 1.122 + x = obj->normal[i].x; 1.123 + y = obj->normal[i].y; 1.124 + z = obj->normal[i].z; 1.125 + norms[i].x = x * xvx + y * xvy + z * xvz; 1.126 + norms[i].y = x * yvx + y * yvy + z * yvz; 1.127 + norms[i].z = x * zvx + y * zvy + z * zvz; 1.128 + } 1.129 +} 1.130 + 1.131 + 1.132 +void rotate3d_pt_normals (object3d *obj) 1.133 +{ 1.134 + float cosxr = cos(obj->rot.x); float cosyr = cos(obj->rot.y); float coszr = cos(obj->rot.z); 1.135 + float sinxr = sin(obj->rot.x); float sinyr = sin(obj->rot.y); float sinzr = sin(obj->rot.z); 1.136 + 1.137 + int xvx = (int)((cosyr * coszr) * fp_mul); int xvy = (int)((sinxr * sinyr * coszr - cosxr * sinzr) * fp_mul); int xvz = (int)((cosxr * sinyr * coszr + sinxr * sinzr) * fp_mul); 1.138 + int yvx = (int)((cosyr * sinzr) * fp_mul); int yvy = (int)((cosxr * coszr + sinxr * sinyr * sinzr) * fp_mul); int yvz = (int)((-sinxr * coszr + cosxr * sinyr * sinzr) * fp_mul); 1.139 + int zvx = (int)((-sinyr) * fp_mul); int zvy = (int)((sinxr * cosyr) * fp_mul); int zvz = (int)((cosxr * cosyr) * fp_mul); 1.140 + 1.141 + int x, y, z; 1.142 + int i; 1.143 + for (i=0; i<obj->npts; i++) 1.144 + { 1.145 + x = obj->pt_normal[i].x; 1.146 + y = obj->pt_normal[i].y; 1.147 + z = obj->pt_normal[i].z; 1.148 + pt_norms[i].x = x * xvx + y * xvy + z * xvz; 1.149 + pt_norms[i].y = x * yvx + y * yvy + z * yvz; 1.150 + pt_norms[i].z = x * zvx + y * zvy + z * zvz; 1.151 + } 1.152 +} 1.153 + 1.154 +void project3d (object3d *obj) 1.155 +{ 1.156 + int i; 1.157 + int smul = 1; 1.158 + 1.159 + for (i=0; i<obj->npts; i++) 1.160 + if (fpts[i].z > 0) 1.161 + { 1.162 + spts[i].x = ((fpts[i].x << proj_shr) / (fpts[i].z/smul)) + (ScreenWidth>>1); 1.163 + spts[i].y = ((fpts[i].y << proj_shr) / (fpts[i].z/smul)) + (ScreenHeight>>1); 1.164 + } 1.165 +} 1.166 + 1.167 +void CalcPolyColorStatic(object3d *obj) 1.168 +{ 1.169 + int i, c; 1.170 + for (i=0; i<obj->npls; i++) 1.171 + { 1.172 + c = norms[i].z>>8; 1.173 + if (c<0) c=0; 1.174 + if (c>255) c=255; 1.175 + spls[i].c = c; 1.176 + } 1.177 +} 1.178 + 1.179 +void CalcPointColorStatic(object3d *obj) 1.180 +{ 1.181 + int i, c; 1.182 + for (i=0; i<obj->npts; i++) 1.183 + { 1.184 + c = pt_norms[i].z>>8; 1.185 + if (c<0) c=0; 1.186 + if (c>255) c=255; 1.187 + spts[i].c = c; 1.188 + } 1.189 +} 1.190 + 1.191 +void CalcPolyColorDynamic(object3d *obj) 1.192 +{ 1.193 + vector3d light, v; 1.194 + light.x = 0; 1.195 + light.y = 0; 1.196 + light.z = 256; 1.197 + float c; 1.198 + 1.199 + int i; 1.200 + for (i=0; i<obj->npls; i++) 1.201 + { 1.202 + v.x = norms[i].x; 1.203 + v.y = norms[i].y; 1.204 + v.z = norms[i].z; 1.205 + c = DotProduct(v,light); 1.206 + spls[i].c = (int)c; 1.207 + if (c<0) spls[i].c = 0; 1.208 + if (spls[i].c>255) spls[i].c = 255; 1.209 + } 1.210 +} 1.211 + 1.212 +void CalcPointColorDynamic(object3d *obj) 1.213 +{ 1.214 + vector3d light, v; 1.215 + light.x = 0; 1.216 + light.y = 0; 1.217 + light.z = 256; 1.218 + float c; 1.219 + 1.220 + int i; 1.221 + for (i=0; i<obj->npts; i++) 1.222 + { 1.223 + v.x = pt_norms[i].x; 1.224 + v.y = pt_norms[i].y; 1.225 + v.z = pt_norms[i].z; 1.226 + c = DotProduct(v,light); 1.227 + if (c<0) c = 0; 1.228 + if (c>255) c = 255; 1.229 + spts[i].c = (int)c; 1.230 + } 1.231 +} 1.232 + 1.233 +void CalcPointColor(object3d *obj) 1.234 +{ 1.235 + if (lightcalc==LIGHTVIEW) CalcPointColorStatic(obj); 1.236 + if (lightcalc==LIGHTMOVE) CalcPointColorDynamic(obj); 1.237 +} 1.238 + 1.239 +void CalcPolyColor(object3d *obj) 1.240 +{ 1.241 + if (lightcalc==LIGHTVIEW) CalcPolyColorStatic(obj); 1.242 + if (lightcalc==LIGHTMOVE) CalcPolyColorDynamic(obj); 1.243 +} 1.244 + 1.245 +void Calc3d(object3d *obj) 1.246 +{ 1.247 + rotate3d(obj); 1.248 + translate3d(obj); 1.249 + project3d(obj); 1.250 +} 1.251 + 1.252 +void quicksort (int lo, int hi, int data[]) 1.253 +{ 1.254 + int m1 = lo; 1.255 + int m2 = hi; 1.256 + int temp0; 1.257 + unsigned short temp1; 1.258 + 1.259 + int mp = data[(lo + hi)>>1]; 1.260 + 1.261 + while (m1<=m2) 1.262 + { 1.263 + while (data[m1] < mp) m1++; 1.264 + while (mp < data[m2]) m2--; 1.265 + 1.266 + if (m1<=m2) 1.267 + { 1.268 + temp0 = data[m1]; data[m1] = data[m2]; data[m2] = temp0; 1.269 + temp1 = swp[m1]; swp[m1] = swp[m2]; swp[m2] = temp1; 1.270 + m1++; 1.271 + m2--; 1.272 + } 1.273 + } 1.274 + 1.275 + if (m2>lo) quicksort(lo, m2, data); 1.276 + if (m1<hi) quicksort(m1, hi, data); 1.277 +}