~swag/armagetronad/0.2.9-sty+ct+ap-fork

« back to all changes in this revision

Viewing changes to src/render/rModel.cpp

  • Committer: luke-jr
  • Date: 2006-05-29 01:55:42 UTC
  • Revision ID: svn-v3-list-QlpoOTFBWSZTWZvbKhsAAAdRgAAQABK6798QIABURMgAAaeoNT1TxT1DQbKaeobXKiyAmlWT7Y5MkdJOtXDtB7w7DOGFBHiOBxaUIu7HQyyQSvxdyRThQkJvbKhs:7d95bf1e-0414-0410-9756-b78462a59f44:armagetronad%2Fbranches%2F0.2.8%2Farmagetronad:4612
Unify tags/branches of modules released together

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
*************************************************************************
 
4
 
 
5
ArmageTron -- Just another Tron Lightcycle Game in 3D.
 
6
Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
 
7
 
 
8
**************************************************************************
 
9
 
 
10
This program is free software; you can redistribute it and/or
 
11
modify it under the terms of the GNU General Public License
 
12
as published by the Free Software Foundation; either version 2
 
13
of the License, or (at your option) any later version.
 
14
 
 
15
This program is distributed in the hope that it will be useful,
 
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
GNU General Public License for more details.
 
19
 
 
20
You should have received a copy of the GNU General Public License
 
21
along with this program; if not, write to the Free Software
 
22
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
23
  
 
24
***************************************************************************
 
25
 
 
26
*/
 
27
 
 
28
#include "rModel.h"
 
29
#include <string>
 
30
#include <fstream>
 
31
#include <stdlib.h>
 
32
#include "rScreen.h"
 
33
#include "tString.h"
 
34
#include "tDirectories.h"
 
35
#include "tConfiguration.h"
 
36
#include "tLocale.h"
 
37
#include "rGL.h"
 
38
 
 
39
 
 
40
static rModel *sr_ModelAnchor;
 
41
 
 
42
static tConfItem<bool> mod_udl("USE_DISPLAYLISTS", sr_useDisplayLists);
 
43
 
 
44
#ifndef DEDICATED
 
45
 
 
46
void Vec3::RenderVertex(){
 
47
    glVertex3f(x[0],x[1],x[2]);
 
48
}
 
49
 
 
50
void Vec3::RenderNormal(){
 
51
    glNormal3f(x[0],x[1],x[2]);
 
52
}
 
53
#endif
 
54
 
 
55
void rModel::Load(std::istream &in,const char *fileName){
 
56
 
 
57
#ifndef DEDICATED
 
58
    bool calc_normals=true;
 
59
 
 
60
    if (strstr(fileName,".mod")){ // old loader
 
61
        REAL xmax=-1E+32f, xmin=1E+32f;
 
62
        REAL zmax=-1E+32f, zmin=1E+32f;
 
63
 
 
64
        while (in && !in.eof()){
 
65
            char c;
 
66
 
 
67
            REAL x,y,z;
 
68
            int A,B,C;
 
69
            int num;
 
70
 
 
71
            in >> c;
 
72
            switch (c){
 
73
            case('v'):
 
74
                            in >> num >> x >> y >> z;
 
75
 
 
76
                if (x > xmax)
 
77
                    xmax = x;
 
78
                if (x < xmin)
 
79
                    xmin = x;
 
80
                if (z > zmax)
 
81
                    zmax = z;
 
82
                if (z < zmin)
 
83
                    zmin = z;
 
84
 
 
85
                vertices[num]=Vec3(x,y,z);
 
86
                normals[num]=Vec3(0,0,0);
 
87
                break;
 
88
 
 
89
            case('f'):
 
90
                            in >> A >> B >> C;
 
91
                modelFaces[modelFaces.Len()]=rModelFace(A,B,C);
 
92
                break;
 
93
 
 
94
            default:
 
95
                break;
 
96
            }
 
97
        }
 
98
 
 
99
        int i;
 
100
        for (i = vertices.Len()-1; i>=0; i--)
 
101
{
 
102
            Vec3 &v = vertices[i];
 
103
            texVert[i] = Vec3((v.x[0]-xmin)/(xmax-xmin), (zmax-v.x[2])/(zmax-zmin), 0);
 
104
        }
 
105
        for (i = modelFaces.Len()-1; i>=0; i--)
 
106
        {
 
107
            modelTexFaces[i] = modelFaces[i];
 
108
        }
 
109
 
 
110
    }
 
111
    else{ // new 3DSMax loader
 
112
        int offset=0;       //
 
113
        int current_vertex=0; //
 
114
 
 
115
#define MAXVERT 10000
 
116
 
 
117
        int   translate[MAXVERT];
 
118
 
 
119
        enum {VERTICES,FACES} status=VERTICES;
 
120
 
 
121
        int my_vert=1;
 
122
 
 
123
        while(in && !in.eof()){
 
124
            char c;
 
125
            char word[100];
 
126
            in >> c;
 
127
            if (c=='*'){
 
128
                in >> word;
 
129
                if (!strcmp(word,"MESH_TVERT")){
 
130
                    int n;
 
131
                    REAL x,y,z;
 
132
                    in >> n >> x >> y >> z;
 
133
                    texVert[n]=Vec3(x,1-y,z);
 
134
                }
 
135
 
 
136
                if (!strcmp(word,"MESH_TFACE")){
 
137
                    int n;
 
138
                    int a,b,c;
 
139
                    in >> n >> a >> b >> c;
 
140
                    modelTexFaces[n]=rModelFace(a,b,c);
 
141
                }
 
142
 
 
143
                if (!strcmp(word,"MESH_VERTEX")){
 
144
                    if (status==FACES){
 
145
                        status=VERTICES;
 
146
                        offset+=current_vertex+1;
 
147
                    }
 
148
 
 
149
                    float vec[3];
 
150
                    in >> current_vertex >> vec[0] >> vec[1] >> vec[2];
 
151
                    int realvert=current_vertex+offset;
 
152
 
 
153
                    translate[realvert]=-1;
 
154
                    /*
 
155
                      for(int i=realvert-1;i>0;i--){
 
156
                      float dist=0;
 
157
                      for(int j=2;j>=0;j--)
 
158
                      dist+= (vec[j]-vertices[i].x[j])*(vec[j]-vertices[i].x[j]);
 
159
                      if (dist<.1)
 
160
                      translate[realvert]=i;
 
161
                      }
 
162
                    */
 
163
                    if (translate[realvert]<0){
 
164
                        translate[realvert]=my_vert;
 
165
                        //std::cerr << "v " << my_vert;
 
166
                        for(int i=0;i<3;i++){
 
167
                            //std::cerr << '\t' << vec[i]*.025; // change inch to meters
 
168
                            vertices[my_vert].x[i]=vec[i]*.025;
 
169
                        }
 
170
                        //std::cerr << '\n';
 
171
                        my_vert++;
 
172
                    }
 
173
                }
 
174
                if (!strcmp(word,"MESH_FACE")){
 
175
                    status=FACES;
 
176
                    in >> word;
 
177
                    in >> word;
 
178
                    //std::cerr << "f ";
 
179
 
 
180
                    int face=modelFaces.Len();
 
181
 
 
182
                    if (strcmp(word,"A:")){
 
183
                        std::cerr << "wrong face format: expected A:, got " << word << '\n';
 
184
                        exit(-1);
 
185
                    }
 
186
                    int n;
 
187
                    in >> n;
 
188
                    modelFaces[face].A[0]=translate[n+offset];
 
189
                    //std::cerr << '\t' << translate[n+offset];
 
190
 
 
191
                    in >> word;
 
192
                    if (strcmp(word,"B:")){
 
193
                        std::cerr << "wrong face format: expected B:, got " << word << '\n';
 
194
                        exit(-1);
 
195
                    }
 
196
                    in >> n;
 
197
                    modelFaces[face].A[1]=translate[n+offset];
 
198
                    // std::cerr << '\t' << translate[n+offset];
 
199
 
 
200
                    in >> word;
 
201
                    if (strcmp(word,"C:")){
 
202
                        std::cerr << "wrong face format: expected C:, got " << word << '\n';
 
203
                        exit(-1);
 
204
                    }
 
205
                    in >> n;
 
206
                    modelFaces[face].A[2]=translate[n+offset];
 
207
                    // std::cerr << '\t' << translate[n+offset];
 
208
 
 
209
                    // std::cerr << '\n';
 
210
 
 
211
                    word[0]='\0';
 
212
                }
 
213
 
 
214
            }
 
215
        }
 
216
    }
 
217
 
 
218
    if (calc_normals)
 
219
        for(int i=modelFaces.Len()-1;i>=0;i--){
 
220
            Vec3 &A=vertices(modelFaces[i].A[0]);
 
221
            Vec3 &B=vertices(modelFaces[i].A[1]);
 
222
            Vec3 &C=vertices(modelFaces[i].A[2]);
 
223
            Vec3 X(B.x[0]-A.x[0],B.x[1]-A.x[1],B.x[2]-A.x[2]);
 
224
            Vec3 Y(C.x[0]-A.x[0],C.x[1]-A.x[1],C.x[2]-A.x[2]);
 
225
            Vec3 normal(X.x[1]*Y.x[2]-X.x[2]*Y.x[1],
 
226
                        X.x[2]*Y.x[0]-X.x[0]*Y.x[2],
 
227
                        X.x[0]*Y.x[1]-X.x[1]*Y.x[0]);
 
228
            normal=normal*(1/normal.Norm());
 
229
 
 
230
            for(int j=2;j>=0;j--)
 
231
                normals[modelFaces[i].A[j]]+=normal;
 
232
        }
 
233
    for(int i=normals.Len()-1;i>=0;i--){
 
234
        normals[i]=normals[i]*(1/normals[i].Norm());
 
235
    }
 
236
 
 
237
#endif
 
238
}
 
239
 
 
240
rModel::rModel(const char *fileName,const char *fileName_alt)
 
241
        :tListItem<rModel>(sr_ModelAnchor), displayList(0)
 
242
        // ,vertices(0),normals(0),modelFaces(0)
 
243
{
 
244
#ifndef DEDICATED
 
245
    //  tString s;
 
246
    //s << "models/";
 
247
    //  s << fileName;
 
248
 
 
249
    std::ifstream in;
 
250
 
 
251
    if ( !tDirectories::Data().Open( in, fileName ) )
 
252
    {
 
253
        if (fileName_alt){
 
254
            std::ifstream in2;
 
255
            tDirectories::Data().Open( in2, fileName_alt );
 
256
 
 
257
            if (!in2.good()){
 
258
                tERR_ERROR("\n\nModel file " << fileName_alt << " could not be found.\n" <<
 
259
                           "are you sure you are running " << tOutput("$program_name") << " in it's own directory?\n\n");
 
260
            }
 
261
            else
 
262
                Load(in2,fileName_alt);
 
263
        }
 
264
        else
 
265
            tERR_ERROR("\n\nModel file " << fileName << " could not be found.\n" <<
 
266
                       "are you sure you are running " << tOutput("$program_name") << " in it's own directory?\n\n");
 
267
 
 
268
    }
 
269
    else
 
270
        Load(in,fileName);
 
271
#endif
 
272
}
 
273
 
 
274
#ifndef DEDICATED
 
275
void rModel::Render(){
 
276
    if (!sr_glOut)
 
277
        return;
 
278
    if(displayList)
 
279
        glCallList(displayList);
 
280
    else
 
281
    {
 
282
        if (sr_useDisplayLists)
 
283
        {
 
284
            displayList=glGenLists(1);
 
285
            glNewList(displayList,GL_COMPILE_AND_EXECUTE);
 
286
        }
 
287
 
 
288
        if (normals.Len()>=vertices.Len()){
 
289
            glNormalPointer(GL_FLOAT,0,&normals[0]);
 
290
            glEnableClientState(GL_NORMAL_ARRAY);
 
291
        }
 
292
        glVertexPointer(3,GL_FLOAT,0,&vertices[0]);
 
293
        glEnableClientState(GL_VERTEX_ARRAY);
 
294
 
 
295
 
 
296
        bool texcoord=true;
 
297
        if (texVert.Len()<0)
 
298
            texcoord=false;
 
299
        if (modelTexFaces.Len()!=modelFaces.Len())
 
300
            texcoord=false;
 
301
 
 
302
 
 
303
        glEnable(GL_CULL_FACE);
 
304
 
 
305
        if (texcoord){
 
306
            glBegin(GL_TRIANGLES);
 
307
            for(int i=modelFaces.Len()-1;i>=0;i--){
 
308
                for(int j=0;j<=2;j++){
 
309
                    glTexCoord3fv(reinterpret_cast<REAL *>(&(texVert(modelTexFaces(i).A[j]))));
 
310
                    glArrayElement(modelFaces(i).A[j]);
 
311
                }
 
312
            }
 
313
 
 
314
            glEnd();
 
315
        }
 
316
        else
 
317
            glDrawElements(GL_TRIANGLES,
 
318
                           modelFaces.Len()*3,
 
319
                           GL_UNSIGNED_INT,
 
320
                           &modelFaces(0));
 
321
 
 
322
 
 
323
        glDisableClientState(GL_VERTEX_ARRAY);
 
324
        glDisableClientState(GL_NORMAL_ARRAY);
 
325
 
 
326
        glDisable(GL_CULL_FACE);
 
327
 
 
328
        if (sr_useDisplayLists)
 
329
        {
 
330
            glEndList();
 
331
        }
 
332
    }
 
333
}
 
334
#endif
 
335
 
 
336
rModel::~rModel(){
 
337
#ifndef DEDICATED
 
338
    if (displayList) glDeleteLists(displayList,1);
 
339
#endif
 
340
    tCHECK_DEST;
 
341
}
 
342
 
 
343
 
 
344
void rModel::UnloadAllDisplayLists()
 
345
{
 
346
#ifndef DEDICATED
 
347
    rModel *run = sr_ModelAnchor;
 
348
    while (run)
 
349
    {
 
350
        if (run->displayList && sr_glOut)
 
351
        {
 
352
            glDeleteLists(run->displayList, 1);
 
353
            run->displayList = 0;
 
354
        }
 
355
        run = run->Next();
 
356
    }
 
357
#endif
 
358
}
 
359
 
 
360
 
 
361
static rCallbackBeforeScreenModeChange unload(&rModel::UnloadAllDisplayLists);
 
362