• R/O
  • SSH
  • HTTPS

marathon: Commit


Commit MetaInfo

Revision529 (tree)
Time2012-06-02 14:43:39
Authorookawa_mi

Log Message

改行コード修正

Change Summary

Incremental Difference

--- marathon/trunk/Source_Files/ModelView/MV_Shell.cpp (nonexistent)
+++ marathon/trunk/Source_Files/ModelView/MV_Shell.cpp (revision 529)
@@ -0,0 +1,1063 @@
1+/*
2+
3+ Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc.
4+ and the "Aleph One" developers.
5+
6+ This program is free software; you can redistribute it and/or modify
7+ it under the terms of the GNU General Public License as published by
8+ the Free Software Foundation; either version 3 of the License, or
9+ (at your option) any later version.
10+
11+ This program is distributed in the hope that it will be useful,
12+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ GNU General Public License for more details.
15+
16+ This license is contained in the file "COPYING",
17+ which is included with this source code; it is available online at
18+ http://www.gnu.org/licenses/gpl.html
19+
20+ Model-Viewer Test Shell, by Loren Petrich, June 10, 2001
21+ This uses GLUT to create an OpenGL context for displaying a 3D model,
22+ in order to test model-reading code
23+*/
24+
25+#include <math.h>
26+#include <string.h>
27+#include <ctype.h>
28+#if defined (__APPLE__) && defined (__MACH__)
29+# include <OpenGL/gl.h>
30+# include <OpenGL/glu.h>
31+# include <OpenGL/glut.h>
32+# include <Movies.h>
33+#elif defined mac
34+# include <gl.h>
35+# include <glu.h>
36+# include <glut.h>
37+# include <Movies.h>
38+#else
39+# include <GL/gl.h>
40+# include <GL/glu.h>
41+# include <GL/glut.h>
42+#endif
43+#include "cseries.h"
44+#include "FileHandler.h"
45+#include "ImageLoader.h"
46+#include "ModelRenderer.h"
47+#include "Dim3_Loader.h"
48+#include "QD3D_Loader.h"
49+#include "StudioLoader.h"
50+#include "WavefrontLoader.h"
51+
52+
53+// Test for Macintosh-specific stuff: Quicktime (for loading images)
54+// and Navigation Services (fancy dialog boxes)
55+
56+bool HasQuicktime = false;
57+bool HasNavServices = false;
58+void InitMacServices()
59+{
60+ // Cribbed from shell_macintosh.cpp
61+ long response;
62+ OSErr error;
63+
64+ error= Gestalt(gestaltQuickTime, &response);
65+ if(!error)
66+ {
67+ /* No error finding QuickTime. Check for ICM so we can use Standard Preview */
68+ error= Gestalt(gestaltCompressionMgr, &response);
69+ if(!error)
70+ {
71+ // Now initialize Quicktime's Movie Toolbox,
72+ // since the soundtrack player will need it
73+ error = EnterMovies();
74+ if (!error) {
75+ HasQuicktime = true;
76+ }
77+ }
78+ }
79+
80+ if ((void*)NavLoad != (void*)kUnresolvedCFragSymbolAddress)
81+ {
82+ NavLoad();
83+ HasNavServices = true;
84+ }
85+}
86+
87+bool machine_has_quicktime()
88+{
89+ return HasQuicktime;
90+}
91+
92+bool machine_has_nav_services()
93+{
94+ return HasNavServices;
95+}
96+
97+void global_idle_proc() {} // Do nothing
98+
99+// GLUT window ID in case there is more than one GLUT window;
100+// however, Apple GLUT does not like more than one such window,
101+// so this program will be one-window-only for now.
102+int MainWindowID;
103+
104+void ResizeMainWindow(int _Width, int _Height);
105+
106+
107+// Model and skin objects;
108+// a model is saved in case it is edited, as when vertices are split
109+Model3D Model, SavedModel;
110+ImageDescriptor Image;
111+bool ImageSemitransparent = false;
112+ModelRenderer Renderer;
113+ModelRenderShader Shaders[2];
114+
115+// For loading models and skins
116+enum {
117+ ModelWavefront = 1,
118+ ModelStudio,
119+ Model_QD3D,
120+ Model_Dim3_First,
121+ Model_Dim3_Rest
122+};
123+const int LoadSkinItem = 1;
124+
125+// When the model or the skin is changed, then do this
126+void InvalidateTexture();
127+
128+void LoadModelAction(int ModelType)
129+{
130+ // Get the model file
131+ FileSpecifier File;
132+ bool Success = false;
133+
134+ // Specialize the dialog for what kind of model file
135+ switch(ModelType)
136+ {
137+ case ModelWavefront:
138+ set_typecode(_typecode_patch,'TEXT');
139+ if (File.ReadDialog(_typecode_patch,"Model Type: Alias|Wavefront"))
140+ Success = LoadModel_Wavefront(File, Model);
141+ break;
142+ case ModelStudio:
143+ // No canonical MacOS assignment of this model type
144+ if (File.ReadDialog(_typecode_unknown,"Model Type: 3D Studio Max"))
145+ Success = LoadModel_Studio(File, Model);
146+ break;
147+ case Model_QD3D:
148+ set_typecode(_typecode_patch,'3DMF');
149+ if (File.ReadDialog(_typecode_patch,"Model Type: QuickDraw 3D"))
150+ Success = LoadModel_QD3D(File, Model);
151+ break;
152+ case Model_Dim3_First:
153+ set_typecode(_typecode_patch,'TEXT');
154+ if (File.ReadDialog(_typecode_patch,"Model Type: Dim3 (First Part)"))
155+ Success = LoadModel_Dim3(File, Model, LoadModelDim3_First);
156+ break;
157+ case Model_Dim3_Rest:
158+ set_typecode(_typecode_patch,'TEXT');
159+ if (File.ReadDialog(_typecode_patch,"Model Type: Dim3 (Later Parts)"))
160+ Success = LoadModel_Dim3(File, Model,LoadModelDim3_Rest);
161+ break;
162+ }
163+
164+ if (!Success) Model.Clear();
165+
166+ glutSetWindow(MainWindowID);
167+ char Name[256];
168+ File.GetName(Name);
169+ glutSetWindowTitle(Name);
170+
171+ // Neutral positions will always be initially present.
172+ // Assume that a boned model already has a bounding box;
173+ // most boneless (static) models do not have such bounding boxes.
174+ if (Model.Bones.empty())
175+ Model.FindBoundingBox();
176+
177+ // Just in case they are off...
178+ Model.NormalizeNormals();
179+
180+ ResizeMainWindow(glutGet(GLUT_WINDOW_WIDTH),glutGet(GLUT_WINDOW_HEIGHT));
181+
182+ // Dump stats
183+ printf("Vertex Positions: %d\n",Model.Positions.size()/3);
184+ printf("Txtr Coords: %d\n",Model.TxtrCoords.size()/2);
185+ printf("Normals: %d\n",Model.Normals.size()/3);
186+ printf("Colors: %d\n",Model.Colors.size()/3);
187+ printf("Triangles: %d\n",Model.VertIndices.size()/3);
188+ printf("Bounding Box\n");
189+ for (int c=0; c<3; c++)
190+ printf("%9f %9f\n",Model.BoundingBox[0][c],Model.BoundingBox[1][c]);
191+
192+ SavedModel = Model;
193+
194+ // Invalidate the current texture, so it will be reloaded for the model
195+ InvalidateTexture();
196+}
197+
198+// Z-Buffering
199+bool Use_Z_Buffer = true;
200+
201+// Bounding box?
202+bool Show_Bounding_Box = false;
203+
204+// Texture management
205+bool TxtrIsPresent = false;
206+GLuint TxtrID;
207+
208+// External lighting?
209+bool Use_Light = false;
210+
211+// Model overall transform?
212+bool Use_Model_Transform = false;
213+
214+// How many rendering passes
215+int NumRenderPasses = 1;
216+
217+// What to render: neutral, frames, or sequences? And which of each?
218+enum {
219+ ShowAnim_Neutral,
220+ ShowAnim_Frames,
221+ ShowAnim_Sequences
222+} ShowAnim = ShowAnim_Neutral;
223+
224+int ThisFrame = 0;
225+int ThisSeq = 0;
226+
227+// Also the mixture between the current and next frames
228+float MixFrac = 0;
229+
230+
231+void InvalidateTexture()
232+{
233+ if (TxtrIsPresent)
234+ {
235+ glDeleteTextures(1,&TxtrID);
236+ TxtrIsPresent = false;
237+ }
238+}
239+
240+
241+void LoadSkinAction(int SkinType)
242+{
243+ // Get the skin file
244+ FileSpecifier File;
245+
246+ bool Success = false;
247+ if (File.ReadDialog(_typecode_unknown,"Skin Image"))
248+ Success = LoadImageFromFile(Image,File,SkinType);
249+ if (!Success) return;
250+
251+ const int BufferSize = 256;
252+ char Buffer[BufferSize];
253+ File.GetName(Buffer);
254+ printf("Read skin file %s\n",Buffer);
255+ switch(SkinType)
256+ {
257+ case ImageLoader_Colors:
258+ ImageSemitransparent = false; // Initially, no nonzero transparency
259+ printf("For colors\n");
260+ break;
261+
262+ case ImageLoader_Opacity:
263+ ImageSemitransparent = true; // Nonzero transparency
264+ printf("For opacity\n");
265+ break;
266+ }
267+
268+ // Invalidate the current texture
269+ InvalidateTexture();
270+
271+ glutPostRedisplay();
272+}
273+
274+
275+float VertexSplitThreshold = 0;
276+
277+
278+void NormalTypeAction(int NormAction)
279+{
280+ Model = SavedModel;
281+ Model.AdjustNormals(NormAction,VertexSplitThreshold);
282+ glutPostRedisplay();
283+}
284+
285+
286+void ShaderCallback(void *Data)
287+{
288+ (void)(Data);
289+ if (!Image.IsPresent()) return;
290+
291+ // Setting up the textures each time
292+ if (TxtrIsPresent)
293+ glBindTexture(GL_TEXTURE_2D,TxtrID);
294+ else
295+ {
296+ // Load the texture
297+ glGenTextures(1,&TxtrID);
298+ glBindTexture(GL_TEXTURE_2D,TxtrID);
299+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
300+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
301+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
302+ gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA8,
303+ Image.GetWidth(), Image.GetHeight(),
304+ GL_RGBA, GL_UNSIGNED_BYTE,
305+ Image.GetPixelBasePtr());
306+ TxtrIsPresent = true;
307+ }
308+}
309+
310+
311+// Needed for external lighting;
312+// the first index is the color channel,
313+// while the second index is in two parts,
314+// the first three (0-2) multipled by the normal vector in dot-product fasion
315+// and the fourth (3) added
316+
317+GLfloat ExternalLight[3][4];
318+
319+
320+void LightingCallback(void *Data, unsigned long NumVerts, GLfloat *Normals, GLfloat *Positions, GLfloat *Colors)
321+{
322+ (void)(Data);
323+
324+// Attempting to keep CB's code on hand
325+#if 0
326+
327+ // Register usage:
328+ // mm0/mm1: ExternalLight[0] (4 components)
329+ // mm2/mm3: ExternalLight[1] (4 components)
330+ // mm4/mm5: ExternalLight[2] (4 components)
331+ // mm6: Normal[0]/Normal[1]
332+ // mm7: Normal[2]/1.0
333+
334+ GLfloat tmp[2] = {0.0, 1.0};
335+ __asm__ __volatile__("
336+ femms\n
337+ movq 0x00(%3),%%mm0\n
338+ movq 0x08(%3),%%mm1\n
339+ movq 0x10(%3),%%mm2\n
340+ movq 0x18(%3),%%mm3\n
341+ movq 0x20(%3),%%mm4\n
342+ movq 0x28(%3),%%mm5\n
343+ movl 8(%0),%%eax\n
344+ movl %%eax,(%4)\n
345+ 0:\n
346+ prefetch 192(%0)\n
347+ movq (%0),%%mm6\n
348+ movq (%4),%%mm7\n
349+ pfmul %%mm0,%%mm6\n
350+ pfmul %%mm1,%%mm7\n
351+ pfacc %%mm6,%%mm7\n
352+ pfacc %%mm6,%%mm7\n
353+ movd %%mm7,(%1)\n
354+ movq (%0),%%mm6\n
355+ movq (%4),%%mm7\n
356+ pfmul %%mm2,%%mm6\n
357+ pfmul %%mm3,%%mm7\n
358+ pfacc %%mm6,%%mm7\n
359+ pfacc %%mm6,%%mm7\n
360+ movd %%mm7,4(%1)\n
361+ movq (%0),%%mm6\n
362+ movq (%4),%%mm7\n
363+ pfmul %%mm4,%%mm6\n
364+ pfmul %%mm5,%%mm7\n
365+ pfacc %%mm6,%%mm7\n
366+ pfacc %%mm6,%%mm7\n
367+ movd %%mm7,8(%1)\n
368+ \n
369+ add $0x0c,%0\n
370+ movl 8(%0),%%eax\n
371+ movl %%eax,(%4)\n
372+ add $0x0c,%1\n
373+ dec %2\n
374+ jne 0b\n
375+ femms\n"
376+ :
377+ : "g" (Normals), "g" (ColorPtr), "g" (NumVerts), "g" (ExternalLight), "g" (&tmp)
378+ : "eax", "memory"
379+ );
380+
381+#else
382+
383+ GLfloat *el0 = ExternalLight[0], *el1 = ExternalLight[1], *el2 = ExternalLight[2];
384+ for (int k=0; k<NumVerts; k++)
385+ {
386+ GLfloat N0 = *(Normals++);
387+ GLfloat N1 = *(Normals++);
388+ GLfloat N2 = *(Normals++);
389+ *(Colors++) =
390+ el0[0]*N0 +
391+ el0[1]*N1 +
392+ el0[2]*N2 +
393+ el0[3];
394+ *(Colors++) =
395+ el1[0]*N0 +
396+ el1[1]*N1 +
397+ el1[2]*N2 +
398+ el1[3];
399+ *(Colors++) =
400+ el2[0]*N0 +
401+ el2[1]*N1 +
402+ el2[2]*N2 +
403+ el2[3];
404+ }
405+
406+#endif
407+}
408+
409+
410+// Callback for drawing that window
411+void DrawMainWindow()
412+{
413+ // No smearing allowed!
414+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
415+
416+ // Render the model
417+ if (!Model.Positions.empty())
418+ {
419+ // In the absence of a skin...
420+ const GLfloat FalseColors[12][3] =
421+ {
422+ { 1, 0, 0},
423+ { 1, 0.5, 0},
424+ { 1, 1, 0},
425+
426+ {0.5, 1, 0},
427+ { 0, 1, 0},
428+ { 0, 1, 0.5},
429+
430+ { 0, 1, 1},
431+ { 0, 0.5, 1},
432+ { 0, 0, 1},
433+
434+ {0.5, 0, 1},
435+ { 1, 0, 1},
436+ { 1, 0, 0.5}
437+ };
438+
439+ // Replace the colors if there isn't an already-present color array
440+ int NumColors = Model.Positions.size()/3;
441+ if (Model.Colors.size() != 3*NumColors)
442+ {
443+ Model.Colors.resize(3*NumColors);
444+ for (int k=0; k<NumColors; k++)
445+ {
446+ const GLfloat *FalseColor = FalseColors[k%12];
447+ GLfloat *Color = &Model.Colors[3*k];
448+ for (int c=0; c<3; c++)
449+ Color[c] = FalseColor[c];
450+ }
451+ }
452+
453+ // Extract the view direction from the matrix
454+ // Since it is pure rotation, transpose = inverse
455+ GLfloat ModelViewMatrix[16];
456+ glGetFloatv(GL_MODELVIEW_MATRIX,ModelViewMatrix);
457+ for (int k=0; k<3; k++)
458+ Renderer.ViewDirection[k] = - ModelViewMatrix[4*k + 2];
459+
460+ // Compose a set of external lights:
461+ for (int c=0; c<3; c++)
462+ {
463+ for (int k=0; k<3; k++)
464+ ExternalLight[c][k] = 0.5*ModelViewMatrix[4*k + c];
465+ ExternalLight[c][3] = 0;
466+ }
467+
468+ if (Use_Z_Buffer)
469+ glEnable(GL_DEPTH_TEST);
470+ else
471+ glDisable(GL_DEPTH_TEST);
472+ glDepthFunc(GL_LEQUAL);
473+ // glEnable(GL_CULL_FACE);
474+ // glCullFace(GL_BACK);
475+ // glFrontFace(GL_CW);
476+
477+ int NextFrame = 0;
478+ switch(ShowAnim)
479+ {
480+ case ShowAnim_Neutral:
481+ Model.FindPositions_Neutral(Use_Model_Transform);
482+ break;
483+
484+ case ShowAnim_Frames:
485+ if (MixFrac != 0)
486+ {
487+ if ((NextFrame = ThisFrame + 1) >= Model.TrueNumFrames())
488+ NextFrame = 0;
489+ }
490+ Model.FindPositions_Frame(Use_Model_Transform,ThisFrame,MixFrac,NextFrame);
491+ break;
492+
493+ case ShowAnim_Sequences:
494+ if (MixFrac != 0)
495+ {
496+ if ((NextFrame = ThisFrame + 1) >= Model.NumSeqFrames(ThisSeq))
497+ NextFrame = 0;
498+ }
499+ Model.FindPositions_Sequence(Use_Model_Transform,ThisSeq,ThisFrame,MixFrac,NextFrame);
500+ break;
501+ }
502+
503+ // Draw the bounding box
504+ const GLfloat EdgeColor[3] = {1,1,0};
505+ const GLfloat DiagColor[3] = {0,1,1};
506+ if (Show_Bounding_Box) Model.RenderBoundingBox(EdgeColor,DiagColor);
507+ glColor3f(1,1,1);
508+
509+ glEnable(GL_BLEND);
510+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
511+ unsigned int Flags = 0;
512+ SET_FLAG(Flags,ModelRenderer::Textured,TxtrIsPresent);
513+ SET_FLAG(Flags,ModelRenderer::Colored,!TxtrIsPresent);
514+ SET_FLAG(Flags,ModelRenderer::ExtLight,Use_Light);
515+ Shaders[1].Flags = Shaders[0].Flags = Flags;
516+ int NumOpaqueRenderPasses = ImageSemitransparent ? NumRenderPasses : 0;
517+ Renderer.Render(Model,Shaders,NumRenderPasses,NumOpaqueRenderPasses,Use_Z_Buffer);
518+ }
519+
520+ // All done -- ready to show
521+ glutSwapBuffers();
522+}
523+
524+
525+void ResizeMainWindow(int _Width, int _Height)
526+{
527+ if (!Model.Positions.empty())
528+ {
529+ // For getting the aspect ratio straight
530+ int MinDim = MAX(MIN(_Width,_Height),1);
531+
532+ // Bounding-box "radius"
533+ GLfloat BBRadius = 0;
534+ for (int m=0; m<3; m++)
535+ {
536+
537+ GLfloat Dist = MAX(-Model.BoundingBox[0][m],Model.BoundingBox[1][m]);
538+ BBRadius += Dist*Dist;
539+ }
540+ BBRadius = sqrt(BBRadius);
541+
542+ GLfloat XDim = BBRadius*_Width/MinDim;
543+ GLfloat YDim = BBRadius*_Height/MinDim;
544+ GLfloat ZDim = 2*BBRadius;
545+
546+ glMatrixMode(GL_PROJECTION);
547+ glLoadIdentity();
548+ glOrtho(-XDim,XDim,-YDim,YDim,-ZDim,ZDim);
549+ glutPostRedisplay();
550+ // glTranslatef(0.6*BBRadius,0.3*BBRadius,0);
551+ }
552+}
553+
554+// Perform a "view side" rotate of the modelview matrix;
555+// rotations are normally applied to the matrix's "model side"
556+static void ViewSideRotate(GLfloat Angle, GLfloat X, GLfloat Y, GLfloat Z)
557+{
558+ GLfloat Matrix[16];
559+ glMatrixMode(GL_MODELVIEW);
560+ glGetFloatv(GL_MODELVIEW_MATRIX,Matrix);
561+ glLoadIdentity();
562+ glRotatef(Angle,X,Y,Z);
563+ glMultMatrixf(Matrix);
564+}
565+
566+// Convenient standard value: 1/4 of a right angel
567+const GLfloat RotationAngle = 22.5;
568+
569+const char ESCAPE = 0x1b;
570+
571+void KeyInMainWindow(unsigned char key, int x, int y)
572+{
573+
574+ key = toupper(key);
575+
576+ switch(key)
577+ {
578+ case '6':
579+ ViewSideRotate(RotationAngle,0,1,0);
580+ glutPostRedisplay();
581+ break;
582+
583+ case '4':
584+ ViewSideRotate(-RotationAngle,0,1,0);
585+ glutPostRedisplay();
586+ break;
587+
588+ case '8':
589+ ViewSideRotate(RotationAngle,1,0,0);
590+ glutPostRedisplay();
591+ break;
592+
593+ case '2':
594+ ViewSideRotate(-RotationAngle,1,0,0);
595+ glutPostRedisplay();
596+ break;
597+
598+ case '9':
599+ ViewSideRotate(RotationAngle,0,0,-1);
600+ glutPostRedisplay();
601+ break;
602+
603+ case '7':
604+ ViewSideRotate(-RotationAngle,0,0,-1);
605+ glutPostRedisplay();
606+ break;
607+
608+ case '0':
609+ glMatrixMode(GL_MODELVIEW);
610+ glLoadIdentity();
611+ glutPostRedisplay();
612+ break;
613+
614+ case 'Z':
615+ Use_Z_Buffer = !Use_Z_Buffer;
616+ if (Use_Z_Buffer)
617+ printf("Z-Buffer On\n");
618+ else
619+ printf("Z-Buffer Off\n");
620+ glutPostRedisplay();
621+ break;
622+
623+ case 'B':
624+ Show_Bounding_Box = !Show_Bounding_Box;
625+ if (Show_Bounding_Box)
626+ printf("Bounding Box On\n");
627+ else
628+ printf("Bounding Box Off\n");
629+ glutPostRedisplay();
630+ break;
631+
632+ case 'S':
633+ if (NumRenderPasses == 1)
634+ NumRenderPasses = 2;
635+ else
636+ NumRenderPasses = 1;
637+ printf("Render passes: %d\n",NumRenderPasses);
638+ glutPostRedisplay();
639+ break;
640+
641+ case 'L':
642+ Use_Light = !Use_Light;
643+ if (Use_Light)
644+ printf("Light On\n");
645+ else
646+ printf("Light Off\n");
647+ glutPostRedisplay();
648+ break;
649+
650+ case 'T':
651+ Use_Model_Transform = !Use_Model_Transform;
652+ if (Use_Model_Transform)
653+ printf("Model Transform On\n");
654+ else
655+ printf("Model Transform Off\n");
656+ glutPostRedisplay();
657+ break;
658+
659+ case 'P':
660+ switch(ShowAnim)
661+ {
662+ case ShowAnim_Neutral:
663+ ShowAnim = ShowAnim_Frames;
664+ if (Model.Frames.empty())
665+ ShowAnim = ShowAnim_Neutral;
666+ break;
667+
668+ case ShowAnim_Frames:
669+ ShowAnim = ShowAnim_Sequences;
670+ if (Model.Frames.empty())
671+ ShowAnim = ShowAnim_Neutral;
672+ else if (Model.SeqFrames.empty())
673+ ShowAnim = ShowAnim_Neutral;
674+ break;
675+
676+ case ShowAnim_Sequences:
677+ ShowAnim = ShowAnim_Neutral;
678+ break;
679+ }
680+
681+ switch(ShowAnim)
682+ {
683+ case ShowAnim_Neutral:
684+ printf("Neutral\n");
685+ break;
686+ case ShowAnim_Frames:
687+ ThisFrame = 0;
688+ printf("Frame %d\n",ThisFrame);
689+ break;
690+ case ShowAnim_Sequences:
691+ ThisSeq = 0;
692+ ThisFrame = 0;
693+ printf("Sequence %d %d\n",ThisSeq,ThisFrame);
694+ break;
695+ }
696+
697+ glutPostRedisplay();
698+ break;
699+
700+ case 'M':
701+ if ((MixFrac += 0.25) > 1) MixFrac = 0;
702+ break;
703+
704+ case '[':
705+ case '{':
706+ if (--ThisSeq < 0)
707+ ThisSeq = Model.TrueNumSeqs() - 1;
708+ ThisFrame = 0;
709+ printf("Sequence %d %d\n",ThisSeq,ThisFrame);
710+ glutPostRedisplay();
711+ break;
712+
713+ case ']':
714+ case '}':
715+ if (++ThisSeq >= Model.TrueNumSeqs())
716+ ThisSeq = 0;
717+ ThisFrame = 0;
718+ printf("Sequence %d %d\n",ThisSeq,ThisFrame);
719+ glutPostRedisplay();
720+ break;
721+
722+ case '-':
723+ case '_':
724+ switch(ShowAnim)
725+ {
726+ case ShowAnim_Frames:
727+ if (--ThisFrame < 0)
728+ ThisFrame = Model.TrueNumFrames()-1;
729+ printf("Frame %d\n",ThisFrame);
730+ break;
731+
732+ case ShowAnim_Sequences:
733+ if (--ThisFrame < 0)
734+ ThisFrame = Model.NumSeqFrames(ThisSeq)-1;
735+ printf("Sequence %d %d\n",ThisSeq,ThisFrame);
736+ break;
737+ }
738+
739+ glutPostRedisplay();
740+ break;
741+
742+ case '=':
743+ case '+':
744+ switch(ShowAnim)
745+ {
746+ case ShowAnim_Frames:
747+ if (++ThisFrame >= Model.TrueNumFrames())
748+ ThisFrame = 0;
749+ printf("Frame %d\n",ThisFrame);
750+ break;
751+
752+ case ShowAnim_Sequences:
753+ if (++ThisFrame >= Model.NumSeqFrames(ThisSeq))
754+ ThisFrame = 0;
755+ printf("Sequence %d %d\n",ThisSeq,ThisFrame);
756+ break;
757+ }
758+
759+ glutPostRedisplay();
760+ break;
761+ }
762+}
763+
764+void SpecialInMainWindow(int key, int x, int y)
765+{
766+ switch(key)
767+ {
768+ case GLUT_KEY_RIGHT:
769+ ViewSideRotate(RotationAngle,0,1,0);
770+ glutPostRedisplay();
771+ break;
772+
773+ case GLUT_KEY_LEFT:
774+ ViewSideRotate(-RotationAngle,0,1,0);
775+ glutPostRedisplay();
776+ break;
777+
778+ case GLUT_KEY_UP:
779+ ViewSideRotate(RotationAngle,1,0,0);
780+ glutPostRedisplay();
781+ break;
782+
783+ case GLUT_KEY_DOWN:
784+ ViewSideRotate(-RotationAngle,1,0,0);
785+ glutPostRedisplay();
786+ break;
787+ }
788+}
789+
790+
791+// Create checked/unchecked menu item
792+char *CheckedText = "*";
793+char *UncheckedText = "_";
794+
795+void DoMenuItemChecking(int MenuItem, char *ItemText, int Selector, int Value) {
796+ char TextBuffer[256];
797+ if (Selector == Value)
798+ strcpy(TextBuffer,CheckedText);
799+ else
800+ strcpy(TextBuffer,UncheckedText);
801+ strcat(TextBuffer," ");
802+ strcat(TextBuffer,ItemText);
803+ glutChangeToMenuEntry(MenuItem,TextBuffer,Value);
804+}
805+
806+// Separate from NormalTypeAction to be below the checking/unchecking mechanism
807+
808+enum
809+{
810+ VS_00,
811+ VS_01,
812+ VS_03,
813+ VS_10,
814+ VS_30
815+};
816+
817+int VertexSplitThresholdIndex = VS_00;
818+
819+int VertexSplitMenu;
820+
821+void UpdateVertexSplitMenu()
822+{
823+ glutSetMenu(VertexSplitMenu);
824+ int Indx = 1;
825+ DoMenuItemChecking(Indx++,"0",VertexSplitThresholdIndex,VS_00);
826+ DoMenuItemChecking(Indx++,"0.1",VertexSplitThresholdIndex,VS_01);
827+ DoMenuItemChecking(Indx++,"0.3",VertexSplitThresholdIndex,VS_03);
828+ DoMenuItemChecking(Indx++,"1.0",VertexSplitThresholdIndex,VS_10);
829+ DoMenuItemChecking(Indx++,"3.0",VertexSplitThresholdIndex,VS_30);
830+
831+ switch(VertexSplitThresholdIndex)
832+ {
833+ case VS_00:
834+ VertexSplitThreshold = 0.0;
835+ break;
836+ case VS_01:
837+ VertexSplitThreshold = 0.1;
838+ break;
839+ case VS_03:
840+ VertexSplitThreshold = 0.3;
841+ break;
842+ case VS_10:
843+ VertexSplitThreshold = 1.0;
844+ break;
845+ case VS_30:
846+ VertexSplitThreshold = 3.0;
847+ break;
848+ }
849+}
850+
851+
852+void VertexSplitAction(int c)
853+{
854+ VertexSplitThresholdIndex = c;
855+ UpdateVertexSplitMenu();
856+}
857+
858+
859+
860+// Background-color stuff: designed for use with GLUT color picker
861+int RedIndx = 0, GreenIndx = 0, BlueIndx = 0;
862+const int CIndxRange = 5;
863+const float CVals[CIndxRange] = {0, 0.25, 0.5, 0.75, 1};
864+
865+void SetBackgroundColor()
866+{
867+ // static GLfloat Red = CVals[RedIndx];
868+ // static GLfloat Green = CVals[GreenIndx];
869+ // static GLfloat Blue = CVals[BlueIndx];
870+ // static GLfloat Alpha = 1;
871+ // glClearColor(Red,Green,Blue,Alpha);
872+ // glClearColor(CVals[RedIndx],CVals[GreenIndx],CVals[BlueIndx],1);
873+}
874+
875+// Update the color-selection menus
876+
877+void UpdateColorMenu(int ColorIndx) {
878+ int Indx = 1;
879+ DoMenuItemChecking(Indx++,"0",ColorIndx,0);
880+ DoMenuItemChecking(Indx++,"0.25",ColorIndx,1);
881+ DoMenuItemChecking(Indx++,"0.5",ColorIndx,2);
882+ DoMenuItemChecking(Indx++,"0.75",ColorIndx,3);
883+ DoMenuItemChecking(Indx++,"1",ColorIndx,4);
884+}
885+
886+int RedMenu;
887+
888+void UpdateRedMenu() {
889+ glutSetMenu(RedMenu);
890+ UpdateColorMenu(RedIndx);
891+}
892+
893+int GreenMenu;
894+
895+void UpdateGreenMenu() {
896+ glutSetMenu(GreenMenu);
897+ UpdateColorMenu(GreenIndx);
898+}
899+
900+int BlueMenu;
901+
902+void UpdateBlueMenu() {
903+ glutSetMenu(BlueMenu);
904+ UpdateColorMenu(BlueIndx);
905+}
906+
907+// Sets the window's background color
908+
909+void SetRedSelection(int c) {
910+ RedIndx = c;
911+ UpdateRedMenu();
912+ SetBackgroundColor();
913+ glutPostRedisplay();
914+}
915+
916+void SetGreenSelection(int c) {
917+ GreenIndx = c;
918+ UpdateGreenMenu();
919+ SetBackgroundColor();
920+ glutPostRedisplay();
921+}
922+
923+void SetBlueSelection(int c) {
924+ BlueIndx = c;
925+ UpdateBlueMenu();
926+ SetBackgroundColor();
927+ glutPostRedisplay();
928+}
929+
930+void SetColorSelection(int c) {
931+ // Nothing
932+ (void)(c);
933+}
934+
935+// Top-level action function
936+
937+void RightButtonAction(int c) {}
938+
939+// Preset display-window side:
940+const int MainWindowWidth = 512, MainWindowHeight = 512;
941+
942+int main(int argc, char **argv)
943+{
944+ // Setting up for using frames and sequences
945+ Model3D::BuildTrigTables();
946+
947+ // For debugging of use of overall model transforms: inverts the model
948+ for (int k=0; k<3; k++)
949+ Model.TransformPos.M[k][k] = Model.TransformNorm.M[k][k] = -1;
950+
951+ // Must be up here
952+ glutInit(&argc, argv);
953+
954+ // See if QT and NavSvcs (MacOS) are present
955+ InitMacServices();
956+
957+ // Direct debug output to the console:
958+ SetDebugOutput_Wavefront(stdout);
959+ SetDebugOutput_Studio(stdout);
960+ SetDebugOutput_QD3D(stdout);
961+ SetDebugOutput_Dim3(stdout);
962+
963+ // Set up shader object
964+ Shaders[0].Flags = 0;
965+ Shaders[0].TextureCallback = ShaderCallback;
966+ Shaders[0].LightingCallback = LightingCallback;
967+ Shaders[1].Flags = 0;
968+ Shaders[1].TextureCallback = ShaderCallback;
969+ Shaders[1].LightingCallback = LightingCallback;
970+
971+ // Set up for creating the main window
972+ glutInitWindowSize(MainWindowWidth,MainWindowHeight);
973+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
974+ SetBackgroundColor();
975+
976+ // Actually create that window
977+ MainWindowID = glutCreateWindow("Pfhormz");
978+
979+ // Set its main callbacks
980+ glutDisplayFunc(DrawMainWindow);
981+ glutReshapeFunc(ResizeMainWindow);
982+ glutKeyboardFunc(KeyInMainWindow);
983+ glutSpecialFunc(SpecialInMainWindow);
984+
985+ // Create model and skin menu items
986+ int ModelMenu = glutCreateMenu(LoadModelAction);
987+ glutAddMenuEntry("Alias-Wavefront...",ModelWavefront);
988+ glutAddMenuEntry("3D Studio Max...",ModelStudio);
989+ glutAddMenuEntry("QuickDraw 3D...",Model_QD3D);
990+ glutAddMenuEntry("Dim3 [First]...",Model_Dim3_First);
991+ glutAddMenuEntry("Dim3 [Rest]...",Model_Dim3_Rest);
992+
993+ int SkinMenu = glutCreateMenu(LoadSkinAction);
994+ glutAddMenuEntry("Colors...",ImageLoader_Colors);
995+ glutAddMenuEntry("Opacity...",ImageLoader_Opacity);
996+
997+ // Create normal-modification menu items
998+ int NormalTypeMenu = glutCreateMenu(NormalTypeAction);
999+ glutAddMenuEntry("None",Model3D::None);
1000+ glutAddMenuEntry("Originals",Model3D::Original);
1001+ glutAddMenuEntry("Reversed Originals",Model3D::Reversed);
1002+ glutAddMenuEntry("Clockwise Sides",Model3D::ClockwiseSide);
1003+ glutAddMenuEntry("Counterclockwise Sides",Model3D::CounterclockwiseSide);
1004+
1005+ // Create a vertex-splitting-threshold menu item
1006+ VertexSplitMenu = glutCreateMenu(VertexSplitAction);
1007+ glutAddMenuEntry("0.0",VS_00);
1008+ glutAddMenuEntry("0.1",VS_01);
1009+ glutAddMenuEntry("0.3",VS_03);
1010+ glutAddMenuEntry("1.0",VS_10);
1011+ glutAddMenuEntry("3.0",VS_30);
1012+ UpdateVertexSplitMenu();
1013+
1014+ // Create a GLUT Color Picker
1015+ // LP: suppressed because glClearColor() is broken
1016+ #ifdef USE_BACKGROUND_COLOR
1017+ // Create color-component submenus
1018+ RedMenu = glutCreateMenu(SetRedSelection);
1019+ glutAddMenuEntry("0",0);
1020+ glutAddMenuEntry("0.25",1);
1021+ glutAddMenuEntry("0.5",2);
1022+ glutAddMenuEntry("0.75",3);
1023+ glutAddMenuEntry("1",4);
1024+ UpdateRedMenu();
1025+
1026+ GreenMenu = glutCreateMenu(SetGreenSelection);
1027+ glutAddMenuEntry("0",0);
1028+ glutAddMenuEntry("0.25",1);
1029+ glutAddMenuEntry("0.5",2);
1030+ glutAddMenuEntry("0.75",3);
1031+ glutAddMenuEntry("1",4);
1032+ UpdateGreenMenu();
1033+
1034+ BlueMenu = glutCreateMenu(SetBlueSelection);
1035+ glutAddMenuEntry("0",0);
1036+ glutAddMenuEntry("0.25",1);
1037+ glutAddMenuEntry("0.5",2);
1038+ glutAddMenuEntry("0.75",3);
1039+ glutAddMenuEntry("1",4);
1040+ UpdateBlueMenu();
1041+
1042+ // Create background-color submenu
1043+ int ColorMenu = glutCreateMenu(SetColorSelection);
1044+ glutAddSubMenu("Red", RedMenu);
1045+ glutAddSubMenu("Green", GreenMenu);
1046+ glutAddSubMenu("Blue", BlueMenu);
1047+ #endif
1048+
1049+ // Create right-button menu:
1050+ int RightButtonMenu = glutCreateMenu(RightButtonAction);
1051+ glutAddSubMenu("Load Model...", ModelMenu);
1052+ glutAddSubMenu("Load Skin...", SkinMenu);
1053+ glutAddSubMenu("Normal Type", NormalTypeMenu);
1054+ glutAddSubMenu("Vertex-Split Threshold", VertexSplitMenu);
1055+ #ifdef USE_BACKGROUND_COLOR
1056+ glutAddSubMenu("Background Color", ColorMenu);
1057+ #endif
1058+ glutAttachMenu(GLUT_RIGHT_BUTTON);
1059+
1060+ glutMainLoop();
1061+
1062+ return 0;
1063+}
Show on old repository browser