rev |
line source |
nuclear@0
|
1 /*
|
nuclear@0
|
2 256-color 3D graphics hack for real-mode DOS.
|
nuclear@0
|
3 Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org>
|
nuclear@0
|
4
|
nuclear@0
|
5 This program is free software: you can redistribute it and/or modify
|
nuclear@0
|
6 it under the terms of the GNU General Public License as published by
|
nuclear@0
|
7 the Free Software Foundation, either version 3 of the License, or
|
nuclear@0
|
8 (at your option) any later version.
|
nuclear@0
|
9
|
nuclear@0
|
10 This program is distributed in the hope that it will be useful,
|
nuclear@0
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nuclear@0
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nuclear@0
|
13 GNU General Public License for more details.
|
nuclear@0
|
14
|
nuclear@0
|
15 You should have received a copy of the GNU General Public License
|
nuclear@0
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
nuclear@0
|
17 */
|
nuclear@0
|
18 #include <math.h>
|
nuclear@0
|
19 #include <assert.h>
|
nuclear@0
|
20 #include "mingl.h"
|
nuclear@0
|
21
|
nuclear@0
|
22
|
nuclear@0
|
23 void mgl_cube(float sz)
|
nuclear@0
|
24 {
|
nuclear@0
|
25 float hsz = sz * 0.5;
|
nuclear@0
|
26
|
nuclear@0
|
27 mgl_begin(MGL_QUADS);
|
nuclear@0
|
28 /* front */
|
nuclear@0
|
29 mgl_normal(0, 0, 1);
|
nuclear@3
|
30 mgl_texcoord2f(0, 1); mgl_vertex3f(-hsz, hsz, hsz);
|
nuclear@3
|
31 mgl_texcoord2f(0, 0); mgl_vertex3f(-hsz, -hsz, hsz);
|
nuclear@3
|
32 mgl_texcoord2f(1, 0); mgl_vertex3f(hsz, -hsz, hsz);
|
nuclear@3
|
33 mgl_texcoord2f(1, 1); mgl_vertex3f(hsz, hsz, hsz);
|
nuclear@0
|
34 /* back */
|
nuclear@0
|
35 mgl_normal(0, 0, -1);
|
nuclear@3
|
36 mgl_texcoord2f(0, 1); mgl_vertex3f(hsz, hsz, -hsz);
|
nuclear@3
|
37 mgl_texcoord2f(0, 0); mgl_vertex3f(hsz, -hsz, -hsz);
|
nuclear@3
|
38 mgl_texcoord2f(1, 0); mgl_vertex3f(-hsz, -hsz, -hsz);
|
nuclear@3
|
39 mgl_texcoord2f(1, 1); mgl_vertex3f(-hsz, hsz, -hsz);
|
nuclear@0
|
40 /* right */
|
nuclear@0
|
41 mgl_normal(1, 0, 0);
|
nuclear@3
|
42 mgl_texcoord2f(0, 1); mgl_vertex3f(hsz, hsz, hsz);
|
nuclear@3
|
43 mgl_texcoord2f(0, 0); mgl_vertex3f(hsz, -hsz, hsz);
|
nuclear@3
|
44 mgl_texcoord2f(1, 0); mgl_vertex3f(hsz, -hsz, -hsz);
|
nuclear@3
|
45 mgl_texcoord2f(1, 1); mgl_vertex3f(hsz, hsz, -hsz);
|
nuclear@0
|
46 /* left */
|
nuclear@0
|
47 mgl_normal(-1, 0, 0);
|
nuclear@3
|
48 mgl_texcoord2f(0, 1); mgl_vertex3f(-hsz, hsz, -hsz);
|
nuclear@3
|
49 mgl_texcoord2f(0, 0); mgl_vertex3f(-hsz, -hsz, -hsz);
|
nuclear@3
|
50 mgl_texcoord2f(1, 0); mgl_vertex3f(-hsz, -hsz, hsz);
|
nuclear@3
|
51 mgl_texcoord2f(1, 1); mgl_vertex3f(-hsz, hsz, hsz);
|
nuclear@0
|
52 /* top */
|
nuclear@0
|
53 mgl_normal(0, 1, 0);
|
nuclear@3
|
54 mgl_texcoord2f(0, 1); mgl_vertex3f(-hsz, hsz, -hsz);
|
nuclear@3
|
55 mgl_texcoord2f(0, 0); mgl_vertex3f(-hsz, hsz, hsz);
|
nuclear@3
|
56 mgl_texcoord2f(1, 0); mgl_vertex3f(hsz, hsz, hsz);
|
nuclear@3
|
57 mgl_texcoord2f(1, 1); mgl_vertex3f(hsz, hsz, -hsz);
|
nuclear@0
|
58 /* bottom */
|
nuclear@0
|
59 mgl_normal(0, -1, 0);
|
nuclear@3
|
60 mgl_texcoord2f(0, 1); mgl_vertex3f(hsz, -hsz, -hsz);
|
nuclear@3
|
61 mgl_texcoord2f(0, 0); mgl_vertex3f(hsz, -hsz, hsz);
|
nuclear@3
|
62 mgl_texcoord2f(1, 0); mgl_vertex3f(-hsz, -hsz, hsz);
|
nuclear@3
|
63 mgl_texcoord2f(1, 1); mgl_vertex3f(-hsz, -hsz, -hsz);
|
nuclear@0
|
64 mgl_end();
|
nuclear@0
|
65 }
|
nuclear@0
|
66
|
nuclear@0
|
67 void mgl_sphere(float rad, int usub, int vsub)
|
nuclear@0
|
68 {
|
nuclear@0
|
69 mgl_sphere_part(rad, usub, vsub, 1.0, 1.0);
|
nuclear@0
|
70 }
|
nuclear@0
|
71
|
nuclear@0
|
72 #define sphere_vertex(u, v) \
|
nuclear@0
|
73 do { \
|
nuclear@0
|
74 float x, y, z, theta, phi; \
|
nuclear@0
|
75 float costheta, sinphi; \
|
nuclear@0
|
76 theta = (u) * 2.0 * M_PI; \
|
nuclear@0
|
77 phi = (v) * M_PI; \
|
nuclear@0
|
78 costheta = cos(theta); \
|
nuclear@0
|
79 sinphi = sin(phi); \
|
nuclear@0
|
80 x = costheta * sinphi; \
|
nuclear@0
|
81 y = cos(phi); \
|
nuclear@0
|
82 z = sin(theta) * sinphi; \
|
nuclear@0
|
83 mgl_normal(x, y, z); \
|
nuclear@0
|
84 mgl_texcoord2f(u, v); \
|
nuclear@0
|
85 mgl_vertex3f(rad * x, rad * y, rad * z); \
|
nuclear@0
|
86 } while(0)
|
nuclear@0
|
87
|
nuclear@0
|
88 void mgl_sphere_part(float rad, int usub, int vsub, float umax, float vmax)
|
nuclear@0
|
89 {
|
nuclear@0
|
90 int i, j;
|
nuclear@0
|
91 float u, v, du, dv;
|
nuclear@0
|
92
|
nuclear@0
|
93 assert(usub > 2);
|
nuclear@0
|
94 assert(vsub > 2);
|
nuclear@0
|
95
|
nuclear@0
|
96 du = umax / (float)usub;
|
nuclear@0
|
97 dv = vmax / (float)vsub;
|
nuclear@0
|
98
|
nuclear@0
|
99 mgl_begin(MGL_QUADS);
|
nuclear@0
|
100
|
nuclear@0
|
101 u = 0.0;
|
nuclear@0
|
102 for(i=0; i<usub; i++) {
|
nuclear@0
|
103 v = 0.0;
|
nuclear@0
|
104 for(j=0; j<vsub; j++) {
|
nuclear@0
|
105 sphere_vertex(u, v);
|
nuclear@0
|
106 sphere_vertex(u + du, v);
|
nuclear@0
|
107 sphere_vertex(u + du, v + dv);
|
nuclear@0
|
108 sphere_vertex(u, v + dv);
|
nuclear@0
|
109 v += dv;
|
nuclear@0
|
110 }
|
nuclear@0
|
111 u += du;
|
nuclear@0
|
112 }
|
nuclear@0
|
113 mgl_end();
|
nuclear@0
|
114 }
|
nuclear@0
|
115
|
nuclear@0
|
116 void mgl_torus(float inner, float outer, int usub, int vsub)
|
nuclear@0
|
117 {
|
nuclear@0
|
118 mgl_torus_part(inner, outer, usub, vsub, 1.0, 0.0, 1.0);
|
nuclear@0
|
119 }
|
nuclear@0
|
120
|
nuclear@0
|
121 #define torus_vertex(u, v) \
|
nuclear@0
|
122 do { \
|
nuclear@0
|
123 float rx, ry, rz, cx, cy, cz, theta, phi; \
|
nuclear@0
|
124 float costheta, sintheta, sinphi; \
|
nuclear@0
|
125 theta = (u) * 2.0 * M_PI; \
|
nuclear@0
|
126 phi = (v) * 2.0 * M_PI; \
|
nuclear@0
|
127 costheta = cos(theta); \
|
nuclear@0
|
128 sintheta = sin(theta); \
|
nuclear@0
|
129 sinphi = sin(phi); \
|
nuclear@0
|
130 cx = costheta * inner; \
|
nuclear@0
|
131 cy = 0.0f; \
|
nuclear@0
|
132 cz = sintheta * inner; \
|
nuclear@0
|
133 rx = costheta * sinphi; \
|
nuclear@0
|
134 ry = cos(phi); \
|
nuclear@0
|
135 rz = sintheta * sinphi; \
|
nuclear@0
|
136 mgl_normal(rx, ry, rz); \
|
nuclear@0
|
137 mgl_texcoord2f(u, v); \
|
nuclear@0
|
138 mgl_vertex3f(outer * rx + cx, outer * ry + cy, outer * rz + cz); \
|
nuclear@0
|
139 } while(0)
|
nuclear@0
|
140
|
nuclear@0
|
141 void mgl_torus_part(float inner, float outer, int usub, int vsub, float umax, float vmin, float vmax)
|
nuclear@0
|
142 {
|
nuclear@0
|
143 int i, j;
|
nuclear@0
|
144 float u, v, du, dv;
|
nuclear@0
|
145
|
nuclear@0
|
146 assert(usub > 2);
|
nuclear@0
|
147 assert(vsub > 2);
|
nuclear@0
|
148
|
nuclear@0
|
149 du = umax / (float)usub;
|
nuclear@0
|
150 dv = (vmax - vmin) / (float)vsub;
|
nuclear@0
|
151
|
nuclear@0
|
152 mgl_begin(MGL_QUADS);
|
nuclear@0
|
153
|
nuclear@0
|
154 u = 0.0;
|
nuclear@0
|
155 for(i=0; i<usub; i++) {
|
nuclear@0
|
156 v = vmin;
|
nuclear@0
|
157 for(j=0; j<vsub; j++) {
|
nuclear@0
|
158 torus_vertex(u, v);
|
nuclear@0
|
159 torus_vertex(u + du, v);
|
nuclear@0
|
160 torus_vertex(u + du, v + dv);
|
nuclear@0
|
161 torus_vertex(u, v + dv);
|
nuclear@0
|
162 v += dv;
|
nuclear@0
|
163 }
|
nuclear@0
|
164 u += du;
|
nuclear@0
|
165 }
|
nuclear@0
|
166 mgl_end();
|
nuclear@0
|
167 }
|