Commit f1402849e5be2c2d9ce26a0d7f4c74b5748b8a74
0 parents
renewed commit
Showing
101 changed files
with
25830 additions
and
0 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 101 files are displayed.
1 | +++ a/CHECK_OPENGL_ERROR.h | ||
1 | +#ifndef RTS_OPENGL_ERROR | ||
2 | +#define RTS_OPENGL_ERROR | ||
3 | + | ||
4 | +#include <stdio.h> | ||
5 | +#include <GL/gl.h> | ||
6 | +#include <GL/glu.h> | ||
7 | + | ||
8 | +#define CHECK_OPENGL_ERROR \ | ||
9 | +{ GLenum error; \ | ||
10 | + while ( (error = glGetError()) != GL_NO_ERROR) { \ | ||
11 | + printf( "OpenGL ERROR: %s\nCHECK POINT: %s (line %d)\n", gluErrorString(error), __FILE__, __LINE__ ); \ | ||
12 | + } \ | ||
13 | +} | ||
14 | + | ||
15 | +#endif | ||
0 | \ No newline at end of file | 16 | \ No newline at end of file |
1 | +++ a/PerformanceDataTemplate.h | ||
1 | +// add the following to a cpp file: | ||
2 | +// PerformanceData PD; | ||
3 | + | ||
4 | + | ||
5 | +#pragma once | ||
6 | +#include <ostream> | ||
7 | +using namespace std; | ||
8 | + | ||
9 | +enum PerformanceDataType | ||
10 | +{ | ||
11 | + PD_DISPLAY=0, | ||
12 | + PD_SPS, | ||
13 | + PD_UNUSED0, | ||
14 | + | ||
15 | + //my stuff | ||
16 | + SIMULATE_SPECTRUM, | ||
17 | + SIMULATE_GPU, | ||
18 | + KRAMERS_KRONIG, | ||
19 | + | ||
20 | + | ||
21 | + | ||
22 | + //end my stuff | ||
23 | + PERFORMANCE_DATA_TYPE_COUNT | ||
24 | +}; | ||
25 | + | ||
26 | +static char PDTypeNames[][255] = { | ||
27 | + "Display ", | ||
28 | + "Simulation Total ", | ||
29 | + " ----------------- ", | ||
30 | + //my stuff | ||
31 | + "Simulate Spectrum ", | ||
32 | + " GPU Portion ", | ||
33 | + "Kramers-Kronig ", | ||
34 | + | ||
35 | + //end my stuff | ||
36 | + | ||
37 | +}; | ||
38 | +#ifdef WIN32 | ||
39 | +#include <stdio.h> | ||
40 | +#include <windows.h> | ||
41 | +#include <float.h> | ||
42 | + | ||
43 | +#include <iostream> | ||
44 | +#include <iomanip> | ||
45 | + | ||
46 | +//------------------------------------------------------------------------------- | ||
47 | + | ||
48 | +class PerformanceData | ||
49 | +{ | ||
50 | +public: | ||
51 | + PerformanceData() { ClearAll(); QueryPerformanceFrequency(&cps); } | ||
52 | + ~PerformanceData(){} | ||
53 | + | ||
54 | + void ClearAll() | ||
55 | + { | ||
56 | + for ( int i=0; i<PERFORMANCE_DATA_TYPE_COUNT; i++ ) { | ||
57 | + for ( int j=0; j<256; j++ ) times[i][j] = 0; | ||
58 | + pos[i] = 0; | ||
59 | + minTime[i] = 0xFFFFFFFF; | ||
60 | + maxTime[i] = 0; | ||
61 | + totalTime[i] = 0; | ||
62 | + dataReady[i] = false; | ||
63 | + } | ||
64 | + } | ||
65 | + | ||
66 | + void StartTimer( int type ) { QueryPerformanceCounter( &startTime[type] );} | ||
67 | + void EndTimer( int type ) { | ||
68 | + LARGE_INTEGER endTime; | ||
69 | + QueryPerformanceCounter( &endTime ); | ||
70 | + double t = (double)(endTime.QuadPart - startTime[type].QuadPart); | ||
71 | + //unsigned int t = GetTickCount() - startTime[type]; | ||
72 | + if ( t < minTime[type] ) minTime[type] = t; | ||
73 | + if ( t > maxTime[type] ) maxTime[type] = t; | ||
74 | + totalTime[type] -= times[type][ pos[type] ]; | ||
75 | + times[type][ pos[type] ] = t; | ||
76 | + totalTime[type] += t; | ||
77 | + pos[type]++; | ||
78 | + if ( pos[type] == 0 ) dataReady[type] = true; | ||
79 | + } | ||
80 | + | ||
81 | + void PrintResult( ostream &os,int i=PERFORMANCE_DATA_TYPE_COUNT) | ||
82 | + { | ||
83 | + os.setf(ios::fixed); | ||
84 | + if ((i<PERFORMANCE_DATA_TYPE_COUNT)&&(i>=0)){ | ||
85 | + double a = GetAvrgTime(i); | ||
86 | + if ( a ) | ||
87 | + os<< PDTypeNames[i]<<" : avrg="<<setw(8)<<setprecision(3)<<a<<"\tmin="<<setw(8)<<setprecision(3)<< GetMinTime(i) <<"\tmax="<<setw(8)<<setprecision(3)<< GetMaxTime(i) <<endl ; | ||
88 | + else | ||
89 | + os<< PDTypeNames[i]<<" : avrg= -----\tmin= -----\tmax= -----"<<endl; | ||
90 | + } | ||
91 | + } | ||
92 | + | ||
93 | + void PrintResults( ostream &os) | ||
94 | + { | ||
95 | + for ( int i=0; i<PERFORMANCE_DATA_TYPE_COUNT; i++ ) | ||
96 | + PrintResult(os,i); | ||
97 | + } | ||
98 | + | ||
99 | + double GetLastTime( int type ) { return times[type][pos[type]]; } | ||
100 | + double GetAvrgTime( int type ) { double a = 1000.0 * totalTime[type] / (float)cps.QuadPart / ( (dataReady[type]) ? 256.0 : (double)pos[type] ); return (_finite(a))? a:0; } | ||
101 | + double GetMinTime( int type ) { return 1000.0 * minTime[type] / (float)cps.LowPart; } | ||
102 | + double GetMaxTime( int type ) { return 1000.0 * maxTime[type] / (float)cps.LowPart; } | ||
103 | + | ||
104 | +private: | ||
105 | + double times[PERFORMANCE_DATA_TYPE_COUNT][256]; | ||
106 | + unsigned char pos[PERFORMANCE_DATA_TYPE_COUNT]; | ||
107 | + LARGE_INTEGER startTime[PERFORMANCE_DATA_TYPE_COUNT]; | ||
108 | + double minTime[ PERFORMANCE_DATA_TYPE_COUNT ]; | ||
109 | + double maxTime[ PERFORMANCE_DATA_TYPE_COUNT ]; | ||
110 | + double totalTime[ PERFORMANCE_DATA_TYPE_COUNT ]; | ||
111 | + bool dataReady[ PERFORMANCE_DATA_TYPE_COUNT ]; | ||
112 | + LARGE_INTEGER cps; | ||
113 | +}; | ||
114 | + | ||
115 | +//------------------------------------------------------------------------------- | ||
116 | +#else | ||
117 | + | ||
118 | +class PerformanceData{ | ||
119 | +public: | ||
120 | + PerformanceData() {;}; | ||
121 | + ~PerformanceData(){;}; | ||
122 | + void ClearAll(){;}; | ||
123 | + void StartTimer( int type ) {;}; | ||
124 | + void EndTimer( int type ) {;}; | ||
125 | + void PrintResults( ostream &os){;}; | ||
126 | + void PrintResult( ostream &os, int i=PERFORMANCE_DATA_TYPE_COUNT){;}; | ||
127 | + double GetLastTime( int type ) { return 0.0; }; | ||
128 | + double GetAvrgTime( int type ) { return 0.0; }; | ||
129 | + double GetMinTime( int type ) { return 0.0; }; | ||
130 | + double GetMaxTime( int type ) { return 0.0; }; | ||
131 | +}; | ||
132 | + | ||
133 | +#endif | ||
134 | +//------------------------------------------------------------------------------- | ||
135 | + | ||
136 | +extern PerformanceData PD; | ||
137 | + | ||
138 | +//------------------------------------------------------------------------------- |
1 | +++ a/cudaHandleError.h | ||
1 | +#include <stdio.h> | ||
2 | +#include "cuda_runtime.h" | ||
3 | +#include "device_launch_parameters.h" | ||
4 | + | ||
5 | +#ifndef CUDA_HANDLE_ERROR_H | ||
6 | +#define CUDA_HANDLE_ERROR_H | ||
7 | + | ||
8 | +//handle error macro | ||
9 | +static void HandleError( cudaError_t err, const char *file, int line ) { | ||
10 | + if (err != cudaSuccess) { | ||
11 | + FILE* outfile = fopen("cudaErrorLog.txt", "w"); | ||
12 | + fprintf(outfile, "%s in %s at line %d\n", cudaGetErrorString( err ), file, line ); | ||
13 | + fclose(outfile); | ||
14 | + exit( EXIT_FAILURE ); | ||
15 | + printf("%s in %s at line %d\n", cudaGetErrorString( err ), file, line ); | ||
16 | + } | ||
17 | +} | ||
18 | +#define HANDLE_ERROR( err ) (HandleError( err, __FILE__, __LINE__ )) | ||
19 | + | ||
20 | +static cudaEvent_t tStartEvent; | ||
21 | +static cudaEvent_t tStopEvent; | ||
22 | +static void gpuStartTimer() | ||
23 | +{ | ||
24 | + //set up timing events | ||
25 | + cudaEventCreate(&tStartEvent); | ||
26 | + cudaEventCreate(&tStopEvent); | ||
27 | + cudaEventRecord(tStartEvent, 0); | ||
28 | +} | ||
29 | + | ||
30 | +static float gpuStopTimer() | ||
31 | +{ | ||
32 | + cudaEventRecord(tStopEvent, 0); | ||
33 | + cudaEventSynchronize(tStopEvent); | ||
34 | + float elapsedTime; | ||
35 | + cudaEventElapsedTime(&elapsedTime, tStartEvent, tStopEvent); | ||
36 | + cudaEventDestroy(tStartEvent); | ||
37 | + cudaEventDestroy(tStopEvent); | ||
38 | + return elapsedTime; | ||
39 | +} | ||
40 | + | ||
41 | +#endif |
1 | +++ a/objJedi.cpp | ||
1 | +/*BUG NOTES | ||
2 | +The standard function calls for inserting vertices don't work anymore. I've fixed points | ||
3 | +but everything beyond that has to be updated. | ||
4 | +*/ | ||
5 | + | ||
6 | +#include "objJedi.h" | ||
7 | +#include "rtsvector3D.h" | ||
8 | +#include "rtspoint3D.h" | ||
9 | +#include <string> | ||
10 | +//variable for use in global functions | ||
11 | +rtsOBJ g_OBJ; | ||
12 | + | ||
13 | +/********UTILITY METHODS*******************************/ | ||
14 | +void rtsOBJ::Scale(float scale_x, float scale_y, float scale_z) | ||
15 | +{ | ||
16 | + vector<vertex_position>::iterator i; | ||
17 | + for(i = v_list.begin(); i!= v_list.end(); i++) | ||
18 | + { | ||
19 | + (*i).x *= scale_x; | ||
20 | + (*i).y *= scale_y; | ||
21 | + (*i).z *= scale_z; | ||
22 | + } | ||
23 | +} | ||
24 | + | ||
25 | +void rtsOBJ::Translate(float trans_x, float trans_y, float trans_z) | ||
26 | +{ | ||
27 | + vector<vertex_position>::iterator i; | ||
28 | + for(i = v_list.begin(); i!= v_list.end(); i++) | ||
29 | + { | ||
30 | + (*i).x += trans_x; | ||
31 | + (*i).y += trans_y; | ||
32 | + (*i).z += trans_z; | ||
33 | + } | ||
34 | + | ||
35 | +} | ||
36 | + | ||
37 | +float rtsOBJ::GetDistance(float x, float y, float z) | ||
38 | +{ | ||
39 | + //gets the distance between the specified point and the nearest surface of the OBJ | ||
40 | + //currently only works for lines | ||
41 | + | ||
42 | + //cout<<"Primitives: "<<primitives.size()<<endl; | ||
43 | + int num_primitives = primitives.size(); | ||
44 | + point3D<double> p0, p1, p2; | ||
45 | + double min_dist = 255; | ||
46 | + double dist, numerator, denominator; | ||
47 | + int p, l; | ||
48 | + vector3D<double> v, w; | ||
49 | + double c1, c2, b; | ||
50 | + point3D<double> Pb; | ||
51 | + | ||
52 | + //for each line | ||
53 | + for(l=0; l<num_primitives; l++) | ||
54 | + { | ||
55 | + if(primitives[l].type & OBJ_LINES) | ||
56 | + { | ||
57 | + //for each point | ||
58 | + for(p = 1; p<primitives[l].p.size(); p++) | ||
59 | + { | ||
60 | + | ||
61 | + vertex_position v1 = v_list[primitives[l].p[p-1].v]; | ||
62 | + vertex_position v2 = v_list[primitives[l].p[p].v]; | ||
63 | + p1.x = v1.x; | ||
64 | + p1.y = v1.y; | ||
65 | + p1.z = v1.z; | ||
66 | + p2.x = v2.x; | ||
67 | + p2.y = v2.y; | ||
68 | + p2.z = v2.z; | ||
69 | + | ||
70 | + p0.x = x; | ||
71 | + p0.y = y; | ||
72 | + p0.z = z; | ||
73 | + | ||
74 | + v = p2 - p1; | ||
75 | + w = p0 - p1; | ||
76 | + if((c1 = w*v) <= 0) | ||
77 | + dist = (p1 - p0).Length(); | ||
78 | + else if((c2 = v*v) <= c1) | ||
79 | + dist = (p2 - p0).Length(); | ||
80 | + else | ||
81 | + { | ||
82 | + b = c1/c2; | ||
83 | + Pb = p1 + b*v; | ||
84 | + dist = (Pb - p0).Length(); | ||
85 | + } | ||
86 | + if(dist < min_dist) | ||
87 | + min_dist = dist; | ||
88 | + | ||
89 | + | ||
90 | + | ||
91 | + } | ||
92 | + } | ||
93 | + } | ||
94 | + //cout<<"---------------------------------------------"<<endl; | ||
95 | + | ||
96 | + return min_dist; | ||
97 | + | ||
98 | + | ||
99 | +} | ||
100 | + | ||
101 | +/********CLASS METHOD DEFINITIONS**********************/ | ||
102 | +//constructors | ||
103 | + | ||
104 | +//constructor | ||
105 | +rtsOBJ::rtsOBJ() | ||
106 | +{ | ||
107 | + g_CurrentMode = OBJ_NONE; | ||
108 | + g_NumVertices = 0; | ||
109 | + g_AttributeMask = 0x0; | ||
110 | + g_AttributeResetMask = 0x0; | ||
111 | + g_LatestVT = 0; | ||
112 | + g_LatestVN = 0; | ||
113 | + | ||
114 | + m_bounds.min.x = m_bounds.min.y = m_bounds.min.z = 99999; | ||
115 | + m_bounds.max.x = m_bounds.max.y = m_bounds.max.z = -99999; | ||
116 | + | ||
117 | + current_primitive_mask = 0x0; | ||
118 | +} | ||
119 | + | ||
120 | +void rtsOBJ::CopyOBJ(const rtsOBJ& obj) | ||
121 | +{ | ||
122 | + current_vt = obj.current_vt; | ||
123 | + current_vn = obj.current_vn; | ||
124 | + vt_changed = obj.vt_changed; //true if a new vt or vn was inserted since the last vertex | ||
125 | + vn_changed = obj.vn_changed; | ||
126 | + current_primitive_mask = obj.current_primitive_mask; //defines what coordinates are being used by the current primitive | ||
127 | + //global variable storing the current render mode | ||
128 | + g_CurrentMode = obj.g_CurrentMode; | ||
129 | + //output file stream | ||
130 | + //g_objFile = obj.g_objFile; | ||
131 | + //obj file object | ||
132 | + //objData g_OBJ; | ||
133 | + //number of vertices since the last BEGIN | ||
134 | + g_NumVertices = obj.g_NumVertices; | ||
135 | + /*Attribute mask. This indicates what attributes are stored for each vertex. | ||
136 | + Only a single mask applies to each vertex between objBegin() and objEnd(). The | ||
137 | + attribute mask is flipped the first time an attribute is set but it is fixed after | ||
138 | + the first vertex is passed.*/ | ||
139 | + g_AttributeMask = obj.g_AttributeMask; | ||
140 | + /*Attribute reset mask. This indicates whether or not an attribute has been | ||
141 | + reset since the last vertex was rendered. This applies to OBJ_VT and OBJ_VN*/ | ||
142 | + g_AttributeResetMask = obj.g_AttributeResetMask; | ||
143 | + //latest texture coordinate sent | ||
144 | + g_LatestVT = obj.g_LatestVT; | ||
145 | + //latest vertex normal sent | ||
146 | + g_LatestVN = obj.g_LatestVN; | ||
147 | + m_bounds = obj.m_bounds; | ||
148 | + | ||
149 | + | ||
150 | + v_list = obj.v_list; | ||
151 | + vt_list = obj.vt_list; | ||
152 | + vn_list = obj.vn_list; | ||
153 | + primitives = obj.primitives; | ||
154 | + | ||
155 | + points = obj.points; | ||
156 | + lines = obj.lines; | ||
157 | + faces = obj.faces; | ||
158 | +} | ||
159 | + | ||
160 | +//opens an obj file for rendering | ||
161 | +OBJint rtsOBJ::objOpen(const char* filename) | ||
162 | +{ | ||
163 | + g_objFile.open(filename); | ||
164 | + return OBJ_OK; | ||
165 | +} | ||
166 | + | ||
167 | +//close the obj file | ||
168 | +OBJint rtsOBJ::objClose() | ||
169 | +{ | ||
170 | + //TODO: write obj data | ||
171 | + f_OutputVertices(); | ||
172 | + f_OutputTextureCoordinates(); | ||
173 | + f_OutputVertexNormals(); | ||
174 | + f_OutputPoints(); | ||
175 | + f_OutputLines(); | ||
176 | + f_OutputFaces(); | ||
177 | + | ||
178 | + //close the file | ||
179 | + g_objFile.close(); | ||
180 | + | ||
181 | + //delete all of the data from the global object | ||
182 | + f_ClearAll(); | ||
183 | + return OBJ_OK; | ||
184 | +} | ||
185 | + | ||
186 | +OBJint rtsOBJ::objBegin(OBJint mode) | ||
187 | +{ | ||
188 | + //make sure that we aren't currently rendering | ||
189 | + if(g_CurrentMode != OBJ_NONE) | ||
190 | + return OBJ_ERROR; | ||
191 | + //make sure that the given mode is valid | ||
192 | + if(mode < OBJ_POINTS || mode > OBJ_POLYGON) | ||
193 | + return OBJ_ERROR; | ||
194 | + | ||
195 | + //otherwise, go ahead and set the mode | ||
196 | + g_CurrentMode = mode; | ||
197 | + //set the number of vertices to zero | ||
198 | + g_NumVertices = 0; | ||
199 | + | ||
200 | + //reset the current state primitive state | ||
201 | + current_primitive_mask = 0x0; | ||
202 | + | ||
203 | + return OBJ_OK; | ||
204 | +} | ||
205 | + | ||
206 | +OBJint rtsOBJ::objEnd() | ||
207 | +{ | ||
208 | + OBJint error = OBJ_OK; | ||
209 | + //check to make sure the number of rendered vertices is valid for the current mode | ||
210 | + switch(g_CurrentMode) | ||
211 | + { | ||
212 | + case OBJ_NONE: | ||
213 | + //can't quit if we haven't started | ||
214 | + error = OBJ_ERROR; | ||
215 | + break; | ||
216 | + case OBJ_LINES: | ||
217 | + //if less than two vertices or an odd number of vertices | ||
218 | + if(g_NumVertices < 2 || g_NumVertices%2 != 0) | ||
219 | + { | ||
220 | + //if there wasn't a vertex at all | ||
221 | + if(g_NumVertices == 0) | ||
222 | + error = OBJ_ERROR; | ||
223 | + //if there was at least one vertex | ||
224 | + else | ||
225 | + { | ||
226 | + //pop the last line off the list | ||
227 | + primitives.pop_back(); | ||
228 | + lines.pop_back(); | ||
229 | + error = OBJ_ERROR; | ||
230 | + } | ||
231 | + } | ||
232 | + break; | ||
233 | + case OBJ_LINE_STRIP: | ||
234 | + //if less than two vertices | ||
235 | + if(g_NumVertices < 2) | ||
236 | + { | ||
237 | + //if there wasn't a vertex at all | ||
238 | + if(g_NumVertices == 0) | ||
239 | + error = OBJ_ERROR; | ||
240 | + //if there was at least one vertex | ||
241 | + else | ||
242 | + { | ||
243 | + //pop the last line off the list | ||
244 | + primitives.pop_back(); | ||
245 | + lines.pop_back(); | ||
246 | + error = OBJ_ERROR; | ||
247 | + } | ||
248 | + } | ||
249 | + break; | ||
250 | + case OBJ_LINE_LOOP: | ||
251 | + //if less than three vertices | ||
252 | + if(g_NumVertices < 3) | ||
253 | + { | ||
254 | + //pop the last line off the list | ||
255 | + primitives.pop_back(); | ||
256 | + lines.pop_back(); | ||
257 | + error = OBJ_ERROR; | ||
258 | + } | ||
259 | + //connect the first and last points | ||
260 | + else | ||
261 | + { | ||
262 | + error = f_TerminateLineLoop(); | ||
263 | + } | ||
264 | + break; | ||
265 | + case OBJ_TRIANGLES: | ||
266 | + //if less than three vertices or not a power of three | ||
267 | + if(g_NumVertices < 3 || g_NumVertices%3 !=0) | ||
268 | + { | ||
269 | + primitives.pop_back(); | ||
270 | + faces.pop_back(); | ||
271 | + error = OBJ_ERROR; | ||
272 | + } | ||
273 | + break; | ||
274 | + case OBJ_TRIANGLE_STRIP: | ||
275 | + //if less than three vertices | ||
276 | + if(g_NumVertices < 3) | ||
277 | + { | ||
278 | + primitives.pop_back(); | ||
279 | + faces.pop_back(); | ||
280 | + error = OBJ_ERROR; | ||
281 | + } | ||
282 | + break; | ||
283 | + case OBJ_TRIANGLE_FAN: | ||
284 | + //if less than three vertices | ||
285 | + if(g_NumVertices < 3) | ||
286 | + { | ||
287 | + primitives.pop_back(); | ||
288 | + faces.pop_back(); | ||
289 | + error = OBJ_ERROR; | ||
290 | + } | ||
291 | + break; | ||
292 | + case OBJ_QUADS: | ||
293 | + if(g_NumVertices < 4 || g_NumVertices%4 != 0) | ||
294 | + { | ||
295 | + primitives.pop_back(); | ||
296 | + faces.pop_back(); | ||
297 | + error = OBJ_ERROR; | ||
298 | + } | ||
299 | + break; | ||
300 | + case OBJ_QUAD_STRIP: | ||
301 | + //has to be at least 4 vertices and an even number | ||
302 | + if(g_NumVertices < 4 || g_NumVertices%2 != 0) | ||
303 | + { | ||
304 | + primitives.pop_back(); | ||
305 | + faces.pop_back(); | ||
306 | + error = OBJ_ERROR; | ||
307 | + } | ||
308 | + break; | ||
309 | + case OBJ_POLYGON: | ||
310 | + //has to be at least three vertices | ||
311 | + if(g_NumVertices < 3) | ||
312 | + { | ||
313 | + primitives.pop_back(); | ||
314 | + faces.pop_back(); | ||
315 | + error = OBJ_ERROR; | ||
316 | + } | ||
317 | + break; | ||
318 | + } | ||
319 | + | ||
320 | + //reset the attribute mask | ||
321 | + g_AttributeMask = 0x0; | ||
322 | + //just for closure, reset the attribute reset mask | ||
323 | + g_AttributeResetMask = 0x0; | ||
324 | + //stop rendering | ||
325 | + g_CurrentMode = OBJ_NONE; | ||
326 | + return error; | ||
327 | +} | ||
328 | + | ||
329 | +OBJint rtsOBJ::f_InsertVertexf(float x, float y, float z, float w, unsigned char mask) | ||
330 | +{ | ||
331 | + //make sure we're rendering | ||
332 | + if(g_CurrentMode == OBJ_NONE) | ||
333 | + return OBJ_ERROR; | ||
334 | + | ||
335 | + //insert the vertex into the vertex vector | ||
336 | + vertex_position v; | ||
337 | + v.x = x; v.y = y; v.z=z; v.w=w; v.mask = mask; | ||
338 | + v_list.push_back(v); | ||
339 | + f_AdjustExtents(v); //set the bounding box | ||
340 | + //insert texture coordinate and normal if specified for this primitive | ||
341 | + if((current_primitive_mask & OBJ_VT) && (vt_changed)) | ||
342 | + vt_list.push_back(current_vt); | ||
343 | + if((current_primitive_mask & OBJ_VN) && (vn_changed)) | ||
344 | + vn_list.push_back(current_vn); | ||
345 | + | ||
346 | + | ||
347 | + //increment the number of vertices inserted | ||
348 | + g_NumVertices++; | ||
349 | + | ||
350 | + //handle each case of the vertex creation individually | ||
351 | + OBJint error = OBJ_OK; | ||
352 | + switch(g_CurrentMode) | ||
353 | + { | ||
354 | + case OBJ_POINTS: | ||
355 | + error = f_InsertPointVertex(); | ||
356 | + break; | ||
357 | + case OBJ_LINES: | ||
358 | + error = f_InsertLineVertex(); | ||
359 | + break; | ||
360 | + case OBJ_LINE_LOOP: | ||
361 | + error = f_InsertLineLoopVertex(); | ||
362 | + break; | ||
363 | + case OBJ_LINE_STRIP: | ||
364 | + error = f_InsertLineStripVertex(); | ||
365 | + break; | ||
366 | + case OBJ_TRIANGLES: | ||
367 | + error = f_InsertTriangleVertex(); | ||
368 | + break; | ||
369 | + case OBJ_TRIANGLE_STRIP: | ||
370 | + error = f_InsertTriangleStripVertex(); | ||
371 | + break; | ||
372 | + case OBJ_TRIANGLE_FAN: | ||
373 | + error = f_InsertTriangleFanVertex(); | ||
374 | + break; | ||
375 | + case OBJ_QUADS: | ||
376 | + error = f_InsertQuadVertex(); | ||
377 | + break; | ||
378 | + case OBJ_QUAD_STRIP: | ||
379 | + error = f_InsertQuadStripVertex(); | ||
380 | + break; | ||
381 | + case OBJ_POLYGON: | ||
382 | + error = f_InsertPolygonVertex(); | ||
383 | + break; | ||
384 | + } | ||
385 | + //set the reset mask to zero | ||
386 | + g_AttributeResetMask = 0x0; | ||
387 | + | ||
388 | + //set the attribute mask to include vertex position | ||
389 | + g_AttributeMask = g_AttributeMask | OBJ_V; | ||
390 | + | ||
391 | + //return the result of the insertion | ||
392 | + return error; | ||
393 | +} | ||
394 | + | ||
395 | +OBJint rtsOBJ::objVertex1f(float x) | ||
396 | +{ | ||
397 | + return f_InsertVertexf(x, 0.0, 0.0, 0.0, OBJ_V_X); | ||
398 | +} | ||
399 | + | ||
400 | +OBJint rtsOBJ::objVertex2f(float x, float y) | ||
401 | +{ | ||
402 | + return f_InsertVertexf(x, y, 0.0, 0.0, OBJ_V_X | OBJ_V_Y); | ||
403 | +} | ||
404 | + | ||
405 | +OBJint rtsOBJ::objVertex3f(float x, float y, float z) | ||
406 | +{ | ||
407 | + return f_InsertVertexf(x, y, z, 0.0, OBJ_V_X | OBJ_V_Y | OBJ_V_Z); | ||
408 | + | ||
409 | +} | ||
410 | + | ||
411 | +OBJint rtsOBJ::objVertex4f(float x, float y, float z, float w) | ||
412 | +{ | ||
413 | + return f_InsertVertexf(x, y, z, w, OBJ_V_X | OBJ_V_Y | OBJ_V_Z | OBJ_V_W); | ||
414 | +} | ||
415 | + | ||
416 | +OBJint rtsOBJ::objNormal3f(float i, float j, float k) | ||
417 | +{ | ||
418 | + return f_InsertNormalf(i, j, k, OBJ_VN_I | OBJ_VN_J | OBJ_VN_K); | ||
419 | +} | ||
420 | +OBJint rtsOBJ::objNormal2f(float i, float j) | ||
421 | +{ | ||
422 | + return f_InsertNormalf(i, j, 0.0, OBJ_VN_I | OBJ_VN_J); | ||
423 | +} | ||
424 | + | ||
425 | +OBJint rtsOBJ::objNormal1f(float i) | ||
426 | +{ | ||
427 | + return f_InsertNormalf(i, 0.0, 0.0, OBJ_VN_I); | ||
428 | +} | ||
429 | + | ||
430 | +OBJint rtsOBJ::f_InsertNormalf(float i, float j, float k, unsigned char mask) | ||
431 | +{ | ||
432 | + /*DEPRECATED | ||
433 | + //if the mode is not rendering faces, there is an error | ||
434 | + if(g_CurrentMode < OBJ_TRIANGLES) | ||
435 | + return OBJ_ERROR; | ||
436 | + //if the normal attribute flag is not set, set it (as long as a vertex hasn't been written) | ||
437 | + if(!(g_AttributeMask & OBJ_VN)) | ||
438 | + { | ||
439 | + //if a vertex has been rendered, then we can't change the attribute, so exit | ||
440 | + if(g_NumVertices > 0) | ||
441 | + return OBJ_ERROR; | ||
442 | + else | ||
443 | + //otherwise, just set the attribute flag | ||
444 | + g_AttributeMask = g_AttributeMask | OBJ_VN; | ||
445 | + } | ||
446 | + | ||
447 | + | ||
448 | + //insert the new normal into the normal list for the file | ||
449 | + vertex_normal new_vn; | ||
450 | + new_vn.i = i; new_vn.j = j; new_vn.k = k; | ||
451 | + new_vn.mask = mask; | ||
452 | + vn_list.push_back(new_vn); | ||
453 | + */ | ||
454 | + current_vn.i = i; //set the current texture state to the given coordinates | ||
455 | + current_vn.j = j; | ||
456 | + current_vn.k = k; | ||
457 | + current_vn.mask = mask; //set the mask as appropriate | ||
458 | + vn_changed = true; //the texture coordinate state has changed | ||
459 | + current_primitive_mask = current_primitive_mask | OBJ_VN; //the current primitive now uses texture coordinates (if it didn't previously) | ||
460 | + | ||
461 | + return OBJ_OK; | ||
462 | +} | ||
463 | + | ||
464 | +OBJint rtsOBJ::objTexCoord3f(float u, float v, float w) | ||
465 | +{ | ||
466 | + return f_InsertTexCoordf(u, v, w, OBJ_VT_U | OBJ_VT_V | OBJ_VT_W); | ||
467 | +} | ||
468 | + | ||
469 | +OBJint rtsOBJ::objTexCoord2f(float u, float v) | ||
470 | +{ | ||
471 | + return f_InsertTexCoordf(u, v, 0.0, OBJ_VT_U | OBJ_VT_V); | ||
472 | +} | ||
473 | + | ||
474 | +OBJint rtsOBJ::objTexCoord1f(float u) | ||
475 | +{ | ||
476 | + return f_InsertTexCoordf(u, 0.0, 0.0, OBJ_VT_U); | ||
477 | +} | ||
478 | + | ||
479 | +OBJint rtsOBJ::f_InsertTexCoordf(float u, float v, float w, unsigned char mask) | ||
480 | +{ | ||
481 | + /* | ||
482 | + DEPRECATED | ||
483 | + //if the normal attribute flag is not set, set it (as long as a vertex hasn't been written) | ||
484 | + if(!(g_AttributeMask & OBJ_VT)) | ||
485 | + { | ||
486 | + //if a vertex has been rendered, then we can't change the attribute, so exit | ||
487 | + if(g_NumVertices > 0) | ||
488 | + return OBJ_ERROR; | ||
489 | + else | ||
490 | + //otherwise, just set the attribute flag | ||
491 | + g_AttributeMask = g_AttributeMask | OBJ_VT; | ||
492 | + } | ||
493 | + | ||
494 | + //insert the new texture coordinate into the list for the file | ||
495 | + vertex_texture new_vt; | ||
496 | + new_vt.u = u; new_vt.v = v; new_vt.w = w; | ||
497 | + new_vt.mask = mask; | ||
498 | + vt_list.push_back(new_vt); | ||
499 | + */ | ||
500 | + current_vt.u = u; //set the current texture state to the given coordinates | ||
501 | + current_vt.v = v; | ||
502 | + current_vt.w = w; | ||
503 | + current_vt.mask = mask; //set the mask as appropriate | ||
504 | + vt_changed = true; //the texture coordinate state has changed | ||
505 | + current_primitive_mask = current_primitive_mask | OBJ_VT; //the current primitive now uses texture coordinates (if it didn't previously) | ||
506 | + | ||
507 | + return OBJ_OK; | ||
508 | +} | ||
509 | + | ||
510 | + | ||
511 | +void rtsOBJ::insertVertexPosition(float x, float y, float z, unsigned char mask) | ||
512 | +{ | ||
513 | + vertex_position v; | ||
514 | + v.x = x; | ||
515 | + v.y = y; | ||
516 | + v.z = z; | ||
517 | + v.mask = mask; | ||
518 | + | ||
519 | + v_list.push_back(v); | ||
520 | +} | ||
521 | + | ||
522 | +void rtsOBJ::insertLine(unsigned int num_points, unsigned int* pointlist, unsigned int* normallist, unsigned int* texturelist) | ||
523 | +{ | ||
524 | + //create the new primitive | ||
525 | + primitive line; | ||
526 | + line.type = OBJ_LINES; | ||
527 | + line.mask = 0; | ||
528 | + | ||
529 | + //set the mask based on the passed data | ||
530 | + if(pointlist != NULL) | ||
531 | + line.mask = line.mask | OBJ_V; | ||
532 | + if(normallist != NULL) | ||
533 | + line.mask = line.mask | OBJ_VN; | ||
534 | + if(texturelist != NULL) | ||
535 | + line.mask = line.mask | OBJ_VT; | ||
536 | + | ||
537 | + //insert the line | ||
538 | + int v; | ||
539 | + vertex new_vert; | ||
540 | + for(v=0; v<num_points; v++) | ||
541 | + { | ||
542 | + if(pointlist) | ||
543 | + new_vert.v = pointlist[v]; | ||
544 | + if(normallist) | ||
545 | + new_vert.vn = normallist[v]; | ||
546 | + if(texturelist) | ||
547 | + new_vert.vt = texturelist[v]; | ||
548 | + line.p.push_back(new_vert); | ||
549 | + } | ||
550 | + //insert the new primitive into the list | ||
551 | + primitives.push_back(line); | ||
552 | +} | ||
553 | +OBJint rtsOBJ::f_InsertPointVertex() | ||
554 | +{ | ||
555 | + //insert the most recent point into the most recent point list | ||
556 | + //if this is the first vertex, create the point list | ||
557 | + if(g_NumVertices == 1) | ||
558 | + { | ||
559 | + primitive new_p; //create the new point | ||
560 | + new_p.type = OBJ_POINTS; | ||
561 | + new_p.mask = current_primitive_mask; | ||
562 | + points.push_back(primitives.size()); //store the primitive id in the points list | ||
563 | + primitives.push_back(new_p); | ||
564 | + } | ||
565 | + | ||
566 | + //find the id of the most recent primitive | ||
567 | + unsigned int p_index = primitives.size() - 1; | ||
568 | + //find the index of the recent point | ||
569 | + vertex p; | ||
570 | + p.v = v_list.size() - 1; | ||
571 | + //insert the indices for texture coordinates and normal if necessary | ||
572 | + if(primitives[p_index].mask & OBJ_VT) | ||
573 | + p.vt = vt_list.size() - 1; | ||
574 | + if(primitives[p_index].mask & OBJ_VN) | ||
575 | + p.vn = vn_list.size() - 1; | ||
576 | + | ||
577 | + //insert the vertex index into the primitive's point list | ||
578 | + primitives[p_index].p.push_back(p); | ||
579 | + | ||
580 | + //push the point into the points list if it is not the only point in the primitive | ||
581 | + if(g_NumVertices > 1) | ||
582 | + points.push_back(p_index); | ||
583 | + | ||
584 | + return OBJ_OK; | ||
585 | +} | ||
586 | + | ||
587 | +OBJint rtsOBJ::f_InsertLineVertex() | ||
588 | +{ | ||
589 | + //if this is an odd vertex, create a new line | ||
590 | + if(g_NumVertices%2 == 1) | ||
591 | + { | ||
592 | + f_CreateNewLine(); | ||
593 | + } | ||
594 | + | ||
595 | + f_InsertNewLineVertex(); | ||
596 | + | ||
597 | + return OBJ_OK; | ||
598 | +} | ||
599 | +OBJint rtsOBJ::f_InsertLineLoopVertex() | ||
600 | +{ | ||
601 | + //technically, this is the same as inserting a line strip vertex | ||
602 | + f_InsertLineStripVertex(); | ||
603 | + return OBJ_OK; | ||
604 | +} | ||
605 | + | ||
606 | +OBJint rtsOBJ::f_InsertLineStripVertex() | ||
607 | +{ | ||
608 | + if(g_NumVertices == 1) | ||
609 | + { | ||
610 | + f_CreateNewLine(); | ||
611 | + } | ||
612 | + | ||
613 | + f_InsertNewLineVertex(); | ||
614 | + | ||
615 | + return OBJ_OK; | ||
616 | +} | ||
617 | + | ||
618 | +OBJint rtsOBJ::f_InsertTriangleVertex() | ||
619 | +{ | ||
620 | + //if this is the first vertex in a triangle, create a new triangle | ||
621 | + if(g_NumVertices%3 == 1) | ||
622 | + { | ||
623 | + f_CreateNewFace(); | ||
624 | + } | ||
625 | + | ||
626 | + | ||
627 | + f_InsertNewFaceVertex(); | ||
628 | + | ||
629 | + return OBJ_OK; | ||
630 | +} | ||
631 | +OBJint rtsOBJ::f_InsertTriangleStripVertex() | ||
632 | +{ | ||
633 | + //in the special case of the first three vertices, just create a triangle | ||
634 | + if(g_NumVertices <4) | ||
635 | + f_InsertTriangleVertex(); | ||
636 | + else | ||
637 | + { | ||
638 | + | ||
639 | + //create a new face for the new triangle | ||
640 | + f_CreateNewFace(); | ||
641 | + | ||
642 | + //insert the last two vertices from the previous triangle | ||
643 | + f_InsertPreviousFaceVertex(1); | ||
644 | + f_InsertPreviousFaceVertex(2); | ||
645 | + //insert the new vertex | ||
646 | + f_InsertNewFaceVertex(); | ||
647 | + } | ||
648 | + | ||
649 | + return OBJ_OK; | ||
650 | +} | ||
651 | +OBJint rtsOBJ::f_InsertTriangleFanVertex() | ||
652 | +{ | ||
653 | + //in the special case of the first three vertices, just create a triangle | ||
654 | + if(g_NumVertices <4) | ||
655 | + f_InsertTriangleVertex(); | ||
656 | + else | ||
657 | + { | ||
658 | + //create a new face for the new triangle | ||
659 | + f_CreateNewFace(); | ||
660 | + //add the previous vertices to the face | ||
661 | + f_InsertFirstFaceVertex(0); | ||
662 | + f_InsertPreviousFaceVertex(2); | ||
663 | + //insert the current vertex | ||
664 | + f_InsertNewFaceVertex(); | ||
665 | + } | ||
666 | + | ||
667 | + return OBJ_OK; | ||
668 | +} | ||
669 | +OBJint rtsOBJ::f_InsertQuadVertex() | ||
670 | +{ | ||
671 | + //if this is the first vertex in a quad, create a new quad | ||
672 | + if(g_NumVertices%4 == 1) | ||
673 | + { | ||
674 | + f_CreateNewFace(); | ||
675 | + } | ||
676 | + | ||
677 | + f_InsertNewFaceVertex(); | ||
678 | + | ||
679 | + return OBJ_OK; | ||
680 | +} | ||
681 | +OBJint rtsOBJ::f_InsertQuadStripVertex() | ||
682 | +{ | ||
683 | + //in the case of one of the first four vertices, just create a quad | ||
684 | + if(g_NumVertices < 5) | ||
685 | + f_InsertQuadVertex(); | ||
686 | + //if the vertex is odd (it will be the third vertex of a quad) | ||
687 | + else if(g_NumVertices%2 == 1) | ||
688 | + { | ||
689 | + //create a new face for the new quad | ||
690 | + f_CreateNewFace(); | ||
691 | + //add the previous two vertices | ||
692 | + f_InsertPreviousFaceVertex(2); | ||
693 | + f_InsertPreviousFaceVertex(3); | ||
694 | + //add the current vertex | ||
695 | + f_InsertNewFaceVertex(); | ||
696 | + } | ||
697 | + else | ||
698 | + { | ||
699 | + //if this is the last vertex of the quad, just add it | ||
700 | + f_InsertNewFaceVertex(); | ||
701 | + | ||
702 | + } | ||
703 | + return OBJ_OK; | ||
704 | +} | ||
705 | +OBJint rtsOBJ::f_InsertPolygonVertex() | ||
706 | +{ | ||
707 | + //if this is the first vertex, create the quad | ||
708 | + if(g_NumVertices == 1) | ||
709 | + { | ||
710 | + f_CreateNewFace(); | ||
711 | + } | ||
712 | + f_InsertNewFaceVertex(); | ||
713 | + | ||
714 | + return OBJ_OK; | ||
715 | +} | ||
716 | + | ||
717 | +OBJint rtsOBJ::f_InsertPreviousFaceVertex(unsigned int v_index) | ||
718 | +{ | ||
719 | + /*Finds the vertex used in the previous face with the given index and | ||
720 | + inserts it into the current face. This limits the redundancy in the file | ||
721 | + for re-used vertices (in strips and fans). This also transfers texture | ||
722 | + and normal information.*/ | ||
723 | + | ||
724 | + //find the index of the previous face | ||
725 | + unsigned int prev_f_index = primitives.size() - 2; | ||
726 | + //find the index of the current face | ||
727 | + unsigned int f_index = prev_f_index +1; | ||
728 | + //add the vertex information from the previous face to this face | ||
729 | + primitives[f_index].p.push_back(primitives[prev_f_index].p[v_index]); | ||
730 | + | ||
731 | + return OBJ_OK; | ||
732 | +} | ||
733 | + | ||
734 | +OBJint rtsOBJ::f_InsertFirstFaceVertex(unsigned int v_index) | ||
735 | +{ | ||
736 | + /*Finds the vertex used in the first face (since the last objBegin()) | ||
737 | + with the given index and inserts it at the end of the current face. | ||
738 | + This includes texture and normal information.*/ | ||
739 | + | ||
740 | + //The result depends on the type of face being rendered | ||
741 | + //So far, this function only applies to triangle fans | ||
742 | + if(g_CurrentMode != OBJ_TRIANGLE_FAN) | ||
743 | + return OBJ_ERROR; | ||
744 | + | ||
745 | + //calculate the number of faces that have been rendered | ||
746 | + unsigned int num_faces = g_NumVertices - 2; | ||
747 | + //find the index of the first face | ||
748 | + unsigned int first_f_index = primitives.size() - num_faces; | ||
749 | + //find the index of the current face | ||
750 | + unsigned int f_index = primitives.size() - 1; | ||
751 | + //transfer the vertex information from the first face to this one | ||
752 | + primitives[f_index].p.push_back(primitives[first_f_index].p[v_index]); | ||
753 | + | ||
754 | + | ||
755 | + return OBJ_OK; | ||
756 | +} | ||
757 | + | ||
758 | +OBJint rtsOBJ::f_InsertNewFaceVertex() | ||
759 | +{ | ||
760 | + /*This inserts information about the current vertex into the current face*/ | ||
761 | + //find the new vertex index | ||
762 | + vertex p; | ||
763 | + p.v = v_list.size() -1; | ||
764 | + p.vt = vt_list.size() - 1; | ||
765 | + p.vn = vn_list.size() -1; | ||
766 | + //find the face index | ||
767 | + unsigned int f_index = primitives.size() -1; | ||
768 | + //INSERT VERTEX AND ATTRIBUTE DATA | ||
769 | + //just add the vertex to the face | ||
770 | + primitives[f_index].p.push_back(p); | ||
771 | + | ||
772 | + return OBJ_OK; | ||
773 | +} | ||
774 | + | ||
775 | +OBJint rtsOBJ::f_InsertNewLineVertex() | ||
776 | +{ | ||
777 | + /*This inserts information about the current vertex into the current line*/ | ||
778 | + //find the new vertex index | ||
779 | + vertex p; | ||
780 | + p.v = v_list.size() -1; | ||
781 | + p.vt = vt_list.size() - 1; | ||
782 | + //find the line index | ||
783 | + unsigned int l_index = primitives.size() -1; | ||
784 | + | ||
785 | + //ADD VERTEX AND ATTRIBUTE INFORMATION | ||
786 | + //add the vertex to the line | ||
787 | + primitives[l_index].p.push_back(p); | ||
788 | + | ||
789 | + return OBJ_OK; | ||
790 | +} | ||
791 | + | ||
792 | +OBJint rtsOBJ::f_CreateNewFace() | ||
793 | +{ | ||
794 | + primitive new_f; | ||
795 | + new_f.type = OBJ_FACE; | ||
796 | + new_f.mask = g_AttributeMask; | ||
797 | + faces.push_back(primitives.size()); | ||
798 | + primitives.push_back(new_f); | ||
799 | + | ||
800 | + | ||
801 | + return OBJ_OK; | ||
802 | +} | ||
803 | + | ||
804 | +OBJint rtsOBJ::f_CreateNewLine() | ||
805 | +{ | ||
806 | + primitive new_l; | ||
807 | + new_l.type = OBJ_LINES; | ||
808 | + new_l.mask = g_AttributeMask; | ||
809 | + lines.push_back(primitives.size()); | ||
810 | + primitives.push_back(new_l); | ||
811 | + | ||
812 | + return OBJ_OK; | ||
813 | +} | ||
814 | + | ||
815 | + | ||
816 | +OBJint rtsOBJ::f_TerminateLineLoop() | ||
817 | +{ | ||
818 | + /*This function just terminates the line loop by setting the last vertex | ||
819 | + to the first vertex.*/ | ||
820 | + if(g_CurrentMode != OBJ_LINE_LOOP) | ||
821 | + return OBJ_ERROR; | ||
822 | + //find the index for the current line | ||
823 | + unsigned int l_index = lines.size() -1; | ||
824 | + //insert the first vertex as the last vertex | ||
825 | + primitives[l_index].p.push_back(primitives[l_index].p[0]); | ||
826 | + | ||
827 | + return OBJ_OK; | ||
828 | +} | ||
829 | + | ||
830 | +void rtsOBJ::f_OutputVertices() | ||
831 | +{ | ||
832 | + //get the number of vertices in the object | ||
833 | + unsigned int v_num = v_list.size(); | ||
834 | + for(unsigned int i=0; i<v_num; i++) | ||
835 | + { | ||
836 | + g_objFile<<"v"; | ||
837 | + if(v_list[i].mask & OBJ_V_X) | ||
838 | + g_objFile<<" "<<v_list[i].x; | ||
839 | + if(v_list[i].mask & OBJ_V_Y) | ||
840 | + g_objFile<<" "<<v_list[i].y; | ||
841 | + if(v_list[i].mask & OBJ_V_Z) | ||
842 | + g_objFile<<" "<<v_list[i].z; | ||
843 | + if(v_list[i].mask & OBJ_V_W) | ||
844 | + g_objFile<<" "<<v_list[i].w; | ||
845 | + g_objFile<<endl; | ||
846 | + } | ||
847 | + | ||
848 | +} | ||
849 | + | ||
850 | +void rtsOBJ::f_OutputVertexNormals() | ||
851 | +{ | ||
852 | + //get the number of normals in the object | ||
853 | + unsigned int vn_num = vn_list.size(); | ||
854 | + for(unsigned int i=0; i<vn_num; i++) | ||
855 | + { | ||
856 | + g_objFile<<"vn "; | ||
857 | + if(vn_list[i].mask & OBJ_VN_I) | ||
858 | + { | ||
859 | + g_objFile<<vn_list[i].i; | ||
860 | + if(vn_list[i].mask & OBJ_VN_J) | ||
861 | + { | ||
862 | + g_objFile<<" "<<vn_list[i].j; | ||
863 | + if(vn_list[i].mask & OBJ_VN_K) | ||
864 | + g_objFile<<" "<<vn_list[i].k; | ||
865 | + } | ||
866 | + } | ||
867 | + g_objFile<<endl; | ||
868 | + } | ||
869 | +} | ||
870 | + | ||
871 | +void rtsOBJ::f_OutputTextureCoordinates() | ||
872 | +{ | ||
873 | + //get the number of vertices in the object | ||
874 | + unsigned int vt_num = vt_list.size(); | ||
875 | + for(unsigned int i=0; i<vt_num; i++) | ||
876 | + { | ||
877 | + g_objFile<<"vt "; | ||
878 | + if(vt_list[i].mask & OBJ_VT_U) | ||
879 | + { | ||
880 | + g_objFile<<vt_list[i].u; | ||
881 | + if(vt_list[i].mask & OBJ_VT_V) | ||
882 | + { | ||
883 | + g_objFile<<" "<<vt_list[i].v; | ||
884 | + if(vt_list[i].mask & OBJ_VT_W) | ||
885 | + g_objFile<<" "<<vt_list[i].w; | ||
886 | + } | ||
887 | + } | ||
888 | + g_objFile<<endl; | ||
889 | + } | ||
890 | +} | ||
891 | + | ||
892 | +void rtsOBJ::f_OutputPoints() | ||
893 | +{ | ||
894 | + /* | ||
895 | + //get the number of point vectors | ||
896 | + unsigned int p_num = points.size(); | ||
897 | + | ||
898 | + //for each point vector, output the points | ||
899 | + for(unsigned int i=0; i<p_num; i++) | ||
900 | + { | ||
901 | + g_objFile<<"p"; | ||
902 | + unsigned int v_num = points[i].p.size(); | ||
903 | + for(unsigned int j=0; j<v_num; j++) | ||
904 | + { | ||
905 | + g_objFile<<" "<<points[i].p[j].v+1; | ||
906 | + } | ||
907 | + g_objFile<<endl; | ||
908 | + } | ||
909 | + */ | ||
910 | +} | ||
911 | + | ||
912 | +void rtsOBJ::f_OutputLines() | ||
913 | +{ | ||
914 | + /* | ||
915 | + //get the number of line vectors | ||
916 | + unsigned int l_num = lines.size(); | ||
917 | + | ||
918 | + //for each line vector, output the associated points | ||
919 | + for(unsigned int i=0; i<l_num; i++) | ||
920 | + { | ||
921 | + g_objFile<<"l"; | ||
922 | + unsigned int v_num = lines[i].p.size(); | ||
923 | + for(unsigned int j=0; j<v_num; j++) | ||
924 | + { | ||
925 | + g_objFile<<" "<<lines[i].p[j].v+1; | ||
926 | + //output texture coordinate if there are any | ||
927 | + if(lines[i].mask & OBJ_VT) | ||
928 | + g_objFile<<"/"<<lines[i].p[j].vt+1; | ||
929 | + } | ||
930 | + g_objFile<<endl; | ||
931 | + } | ||
932 | + */ | ||
933 | +} | ||
934 | + | ||
935 | +void rtsOBJ::f_OutputFaces() | ||
936 | +{ | ||
937 | + /* | ||
938 | + //get the number of faces | ||
939 | + unsigned int f_num = faces.size(); | ||
940 | + | ||
941 | + //for each face, output the associated points | ||
942 | + for(unsigned int i=0; i<f_num; i++) | ||
943 | + { | ||
944 | + g_objFile<<"f"; | ||
945 | + //get the number of face vertices | ||
946 | + unsigned int v_num = faces[i].p.size(); | ||
947 | + for(unsigned int j=0; j<v_num; j++) | ||
948 | + { | ||
949 | + g_objFile<<" "<<faces[i].p[j].v+1; | ||
950 | + //if there are texture coordinates | ||
951 | + if(faces[i].mask & OBJ_VT) | ||
952 | + g_objFile<<"/"<<faces[i].p[j].vt+1; | ||
953 | + //if there is a normal | ||
954 | + if(faces[i].mask & OBJ_VN) | ||
955 | + { | ||
956 | + //but no texture coordinates, put an extra slash | ||
957 | + if(!(faces[i].mask & OBJ_VT)) | ||
958 | + g_objFile<<"/"; | ||
959 | + g_objFile<<"/"<<faces[i].p[j].vn+1; | ||
960 | + } | ||
961 | + | ||
962 | + } | ||
963 | + g_objFile<<endl; | ||
964 | + } | ||
965 | + */ | ||
966 | +} | ||
967 | + | ||
968 | +void rtsOBJ::f_ClearAll() | ||
969 | +{ | ||
970 | + rtsOBJ(); | ||
971 | + //clear all data from the global obj function | ||
972 | + faces.clear(); | ||
973 | + lines.clear(); | ||
974 | + points.clear(); | ||
975 | + v_list.clear(); | ||
976 | + vn_list.clear(); | ||
977 | + vt_list.clear(); | ||
978 | + primitives.clear(); | ||
979 | +} | ||
980 | + | ||
981 | +/*GLOBAL FUNCTION DEFINITIONS*/ | ||
982 | +//initialize the OBJ file | ||
983 | +OBJint objOpen(char* filename) | ||
984 | +{ | ||
985 | + return g_OBJ.objOpen(filename); | ||
986 | +} | ||
987 | +//close the obj file | ||
988 | +OBJint objClose() | ||
989 | +{ | ||
990 | + return g_OBJ.objClose(); | ||
991 | +} | ||
992 | + | ||
993 | +//start rendering in a certain mode | ||
994 | +OBJint objBegin(OBJint mode) | ||
995 | +{ | ||
996 | + return g_OBJ.objBegin(mode); | ||
997 | +} | ||
998 | +//stop the current rendering sequence | ||
999 | +OBJint objEnd(void) | ||
1000 | +{ | ||
1001 | + return g_OBJ.objEnd(); | ||
1002 | +} | ||
1003 | +//render a vertex to the file | ||
1004 | +OBJint objVertex1f(float x) | ||
1005 | +{ | ||
1006 | + return g_OBJ.objVertex1f(x); | ||
1007 | +} | ||
1008 | + | ||
1009 | +OBJint objVertex2f(float x, float y) | ||
1010 | +{ | ||
1011 | + return g_OBJ.objVertex2f(x, y); | ||
1012 | +} | ||
1013 | + | ||
1014 | +OBJint objVertex3f(float x, float y, float z) | ||
1015 | +{ | ||
1016 | + return g_OBJ.objVertex3f(x, y, z); | ||
1017 | +} | ||
1018 | + | ||
1019 | +OBJint objVertex4f(float x, float y, float z, float w) | ||
1020 | +{ | ||
1021 | + return g_OBJ.objVertex4f(x, y, z, w); | ||
1022 | +} | ||
1023 | +//set a normal vector for a vertex | ||
1024 | +OBJint objNormal3f(float i, float j, float k) | ||
1025 | +{ | ||
1026 | + return g_OBJ.objNormal3f(i, j, k); | ||
1027 | +} | ||
1028 | +OBJint objNormal2f(float i, float j) | ||
1029 | +{ | ||
1030 | + return g_OBJ.objNormal2f(i, j); | ||
1031 | +} | ||
1032 | +OBJint objNormal1f(float i) | ||
1033 | +{ | ||
1034 | + return g_OBJ.objNormal1f(i); | ||
1035 | +} | ||
1036 | +//set a texture coordinate for a vertex | ||
1037 | +OBJint objTexCoord3f(float u, float v, float w) | ||
1038 | +{ | ||
1039 | + return g_OBJ.objTexCoord3f(u, v, w); | ||
1040 | +} | ||
1041 | + | ||
1042 | +OBJint objTexCoord2f(float u, float v) | ||
1043 | +{ | ||
1044 | + return g_OBJ.objTexCoord2f(u,v); | ||
1045 | +} | ||
1046 | + | ||
1047 | +OBJint objTexCoord1f(float u) | ||
1048 | +{ | ||
1049 | + return g_OBJ.objTexCoord1f(u); | ||
1050 | +} | ||
1051 | + | ||
1052 | +OBJint rtsOBJ::f_ReadPosition(ifstream &infile) | ||
1053 |