source: GTP/trunk/App/Demos/Illum/Standalone/StochasticIteration [DirectX]/object.cpp @ 1808

Revision 1808, 11.7 KB checked in by szirmay, 18 years ago (diff)
Line 
1#pragma once
2
3
4#include "dxstdafx.h"
5#include "d3ddefs.h"
6#include <cstdio>
7#include <ctime>
8#include <ostream>
9#include <cstdlib>
10#include "vector4d.h"
11#include "color.h"
12#include "object.h"
13
14
15ObjectModel::ObjectModel() {
16        this->offset=0;
17        nvertices = ntexcoords = ntriangles = 0;
18        device=NULL;
19        loaded=false;
20        vertexRotationClockwise=true;
21        vertexDeclarationCreated=false;
22        modelVertices=NULL;
23        vertexBuffer=NULL;
24        logFile=NULL;
25        decl=NULL;
26        D3DXMatrixIdentity(&transformMatrix);
27}
28
29ObjectModel::ObjectModel(int offset) {
30        this->offset=offset;
31        nvertices = ntexcoords = ntriangles = 0;
32        device=NULL;
33        vertexBuffer=NULL;
34        loaded=false;
35        modelVertices=NULL;
36        logFile=NULL;
37        decl=NULL;
38        D3DXMatrixIdentity(&transformMatrix);
39}
40
41ObjectModel::~ObjectModel( ) {
42        SAFE_RELEASE(decl);
43        SAFE_RELEASE(vertexBuffer)
44        if(modelVertices!=NULL){
45                GlobalFree((HGLOBAL)modelVertices);
46        }
47        SAFE_DELETE(logFile);
48}
49
50HRESULT ObjectModel::Render(bool renderToAtlas){
51        HRESULT hr;
52        if(!isLoaded()){
53                return E_FAIL;
54        }
55        V_RETURN(device->SetVertexDeclaration(this->decl))
56        if(renderToAtlas){
57                if(this->isVertexRotationClockwise()){
58                        V_RETURN(device->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE))
59                }
60                else{
61                        V_RETURN(device->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE))
62                }
63        }
64        else{
65                V_RETURN(device->SetRenderState(D3DRS_CULLMODE,D3DCULL_CW))
66        }
67        V_RETURN(this->device->SetStreamSource(0,vertexBuffer,0,sizeof(D3DVERTEX_MODEL)))
68        V_RETURN(this->device->DrawPrimitive(D3DPT_TRIANGLELIST,0,ntriangles))
69        return hr;
70}
71
72HRESULT ObjectModel::RenderWithFX(LPD3DXEFFECT m_pEffect,bool renderToAtlas,D3DXMATRIX modelview,D3DXMATRIX modelviewproj){
73        HRESULT hr;
74        if(m_pEffect==NULL){
75                return E_POINTER;
76        }
77        if(!isLoaded()){
78                return E_FAIL;
79        }
80        V_RETURN(device->SetVertexDeclaration(this->decl))
81        if(renderToAtlas){
82                if(this->isVertexRotationClockwise()){
83                        V_RETURN(device->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW))
84                }
85                else{
86                        V_RETURN(device->SetRenderState(D3DRS_CULLMODE,D3DCULL_CW))
87                }
88        }
89        else{
90                V_RETURN(device->SetRenderState(D3DRS_CULLMODE,D3DCULL_CW))
91        }
92        D3DXMATRIX mw;
93        D3DXMATRIX mwp;
94        D3DXMATRIX inverseWorldMatrix;
95        D3DXMatrixIdentity(&mw);
96        D3DXMatrixIdentity(&mwp);
97        D3DXMatrixIdentity(&inverseWorldMatrix);
98        D3DXMatrixMultiply(&mw,&transformMatrix,&modelview);
99        D3DXMatrixMultiply(&mwp,&transformMatrix,&modelviewproj);
100        D3DXMatrixInverse(&inverseWorldMatrix,NULL,&mw);
101        V_RETURN(m_pEffect->SetMatrix("modelview",&mw))
102        V_RETURN(m_pEffect->SetMatrix("modelviewproj",&mwp))
103        V_RETURN(m_pEffect->SetMatrixTranspose("modelviewIT",&inverseWorldMatrix))
104        V_RETURN(this->device->SetStreamSource(0,vertexBuffer,0,sizeof(D3DVERTEX_MODEL)))
105        V_RETURN(m_pEffect->CommitChanges())
106        V_RETURN(this->device->DrawPrimitive(D3DPT_TRIANGLELIST,0,ntriangles))
107        return S_OK;
108}
109
110void ObjectModel::AddVertex( float x, float y, float z ) { vertices[nvertices++] = Vector(x, y, z); }
111void ObjectModel::AddTexCoord( float u, float v ) { texcoords[ntexcoords++] = Vector(u, v, 0); }
112void ObjectModel::AddTriangle( int i1, int t1, int i2, int t2, int i3, int t3 ) {
113        triangles[ntriangles++] = Triangle(i1, t1, i2, t2, i3, t3);
114}
115
116HRESULT ObjectModel::initDeviceObjects(LPDIRECT3DDEVICE9 device){
117        HRESULT hr;
118        if(!isLoaded()){
119                return E_FAIL;
120        }
121        this->device=device;
122        D3DVERTEXELEMENT9 _decl[]=
123        {
124                {0,0,D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,0 },
125                {0,16,D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,0 },
126                {0,32,D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,0 },
127                {0,40,D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,1 },
128                {0,52,D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,2 },
129                {0,68,D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,0 },
130                D3DDECL_END()
131        };
132        hr=device->CreateVertexDeclaration(_decl,&decl);
133        this->CreateD3DVertices();
134        V_RETURN(device->CreateVertexBuffer(sizeof(D3DVERTEX_MODEL)*ntriangles*3,D3DUSAGE_WRITEONLY,D3DFVF_CUSTOMVERTEX_MODEL,D3DPOOL_MANAGED,&vertexBuffer,NULL));
135        void* pData;
136        vertexBuffer->Lock(0,sizeof(pData),(void**)&pData,0);
137        memcpy(pData,getModelVertices(),sizeof(D3DVERTEX_MODEL)*ntriangles*3);
138        vertexBuffer->Unlock();
139        return hr;
140}
141       
142HRESULT ObjectModel::resetDeviceObjects(LPDIRECT3DDEVICE9 device){
143        HRESULT hr;
144        if(!isLoaded()){
145                return E_FAIL;
146        }
147        SAFE_RELEASE(vertexBuffer);
148        SAFE_RELEASE(decl);
149        this->device=device;
150        V_RETURN(device->CreateVertexBuffer(sizeof(D3DVERTEX_MODEL)*ntriangles*3,D3DUSAGE_WRITEONLY,D3DFVF_CUSTOMVERTEX_MODEL,D3DPOOL_MANAGED,&vertexBuffer,NULL));
151        void* pData;
152        vertexBuffer->Lock(0,sizeof(pData),(void**)&pData,0);
153        memcpy(pData,getModelVertices(),sizeof(D3DVERTEX_MODEL)*ntriangles*3);
154        vertexBuffer->Unlock();
155        return hr;
156}
157
158
159D3DVERTEX_MODEL* ObjectModel::getModelVertices(){
160        return(modelVertices);
161}
162
163bool ObjectModel::isVertexRotationClockwise(){
164        return this->vertexRotationClockwise;
165}
166
167bool ObjectModel::isLoaded(){
168        return loaded;
169}
170
171void ObjectModel::CreateD3DVertices(){
172        if(loaded){
173                modelVertices=(D3DVERTEX_MODEL*)GlobalAlloc(GPTR,ntriangles*3*sizeof(D3DVERTEX_MODEL));
174                for(int i = 0; i < ntriangles; i++) {
175                        for(int j = 0; j < 3; j++) {
176                                if(j==0){       //Vertex v0 is passed to D3D vertex v0.
177                                        modelVertices[i*3+j].fX=vertices[triangles[i].v[j]].x;
178                                        modelVertices[i*3+j].fY=vertices[triangles[i].v[j]].y;
179                                        modelVertices[i*3+j].fZ=vertices[triangles[i].v[j]].z;
180                                        modelVertices[i*3+j].u1=texcoords[triangles[i].t[j]].x;
181                                        modelVertices[i*3+j].v1=texcoords[triangles[i].t[j]].y;
182                                }
183                                if(j==1){       //Vertex v2 is passed to D3D vertex v1.
184                                        modelVertices[i*3+j].fX=vertices[triangles[i].v[j+1]].x;
185                                        modelVertices[i*3+j].fY=vertices[triangles[i].v[j+1]].y;
186                                        modelVertices[i*3+j].fZ=vertices[triangles[i].v[j+1]].z;
187                                        modelVertices[i*3+j].u1=texcoords[triangles[i].t[j+1]].x;
188                                        modelVertices[i*3+j].v1=texcoords[triangles[i].t[j+1]].y;
189                                }
190                                if(j==2){ //Vertex v1 is passed to D3D vertex v2.
191                                        modelVertices[i*3+j].fX=vertices[triangles[i].v[j-1]].x;
192                                        modelVertices[i*3+j].fY=vertices[triangles[i].v[j-1]].y;
193                                        modelVertices[i*3+j].fZ=vertices[triangles[i].v[j-1]].z;
194                                        modelVertices[i*3+j].u1=texcoords[triangles[i].t[j-1]].x;
195                                        modelVertices[i*3+j].v1=texcoords[triangles[i].t[j-1]].y;
196                                }
197                                modelVertices[i*3+j].fW=1.0f;
198                                /*
199                                modelVertices[i*3+j].colorRGBr=(float)RED(i+offset)/255.0f;
200                                modelVertices[i*3+j].colorRGBg=(float)GREEN(i+offset)/255.0f;
201                                modelVertices[i*3+j].colorRGBb=(float)BLUE(i+offset)/255.0f;
202                                */
203                                modelVertices[i*3+j].colorRGBr=(float)i+offset;
204                                modelVertices[i*3+j].colorRGBa=0.0f;
205                                modelVertices[i*3+j].nX=triangles[i].normal.x;
206                                modelVertices[i*3+j].nY=triangles[i].normal.y;
207                                modelVertices[i*3+j].nZ=triangles[i].normal.z;
208                                modelVertices[i*3+j].nW=1.0f;
209                                modelVertices[i*3+j].u2=triangles[i].BRDF.R;
210                                modelVertices[i*3+j].v2=triangles[i].BRDF.G;
211                                modelVertices[i*3+j].w2=triangles[i].BRDF.B;
212                                modelVertices[i*3+j].u3=triangles[i].emission.R;
213                                modelVertices[i*3+j].v3=triangles[i].emission.G;
214                                modelVertices[i*3+j].w3=triangles[i].emission.B;
215                                modelVertices[i*3+j].a3=triangles[i].area/triangles[i].texarea;
216                        }
217                }
218                this->vertexDeclarationCreated=true;
219        }
220}
221
222void ObjectModel::Load( char * fname, bool ccw, bool cw, bool islight, float su, float sv, float ou, float ov ) {
223        this->vertexRotationClockwise=cw;
224        FILE * ifile = fopen(fname, "r");
225        if ( !ifile ) return;
226        char buffer[80];
227        if (!fgets(buffer, 80, ifile)) return;
228       
229        int match;
230        int i=0;
231        for( ; ; ) {
232                char tempc=0;
233                if(sscanf(buffer,"%c",&tempc)){
234                        while((tempc!='v')&&(tempc!='f')){
235                                if (!fgets(buffer, 80, ifile)) return;
236                                sscanf(buffer,"%c",&tempc);
237                        }
238                }
239               
240                float x, y, z;
241                match = sscanf(buffer, "v %f %f %f\n", &x, &y, &z);
242                if (match != 3)
243                        break;
244                AddVertex(x, y, z);
245                if (!fgets(buffer, 80, ifile)) return;
246                i++;
247        }
248        float maxu = -1, maxv = -1, minu = 1, minv = 1;
249        for( ; ; ) {
250                char tempc=0;
251                if(sscanf(buffer,"%c",&tempc)){
252                        while((tempc!='v')&&(tempc!='f')){
253                                if (!fgets(buffer, 80, ifile)) return;
254                                sscanf(buffer,"%c",&tempc);
255                        }
256                }
257                float u, v, w;
258                        match = sscanf(buffer, "vt %f %f %f\n", &u, &v, &w);
259                        if (match != 3){
260                                match = sscanf(buffer, "vt %f %f\n", &u, &v);
261                                if (match != 2)
262                                        break;
263                        }
264               
265                if (maxu < u) maxu = u;
266                if (maxv < v) maxv = v;
267                if (minu > u) minu = u;
268                if (minv > v) minv = v;
269                AddTexCoord(u, v);
270                if (!fgets(buffer, 80, ifile))
271                        return;
272        }
273        for(int i = 0; i < ntexcoords; i++) {
274                texcoords[i].x = (texcoords[i].x - minu)/(maxu - minu) * su + ou;
275                texcoords[i].y = (texcoords[i].y - minv)/(maxv - minv) * sv + ov;
276        }
277        int c=0;
278        for( ; ; ) {
279                int i1, t1, i2, t2, i3, t3;
280                char tempc=0;
281                if(sscanf(buffer,"%c",&tempc)){
282                        while((tempc!='v')&&(tempc!='f')){
283                                if (!fgets(buffer, 80, ifile)) return;
284                                sscanf(buffer,"%c",&tempc);
285                        }
286                }
287                match = sscanf(buffer, "f %i/%i %i/%i %i/%i\n", &i1, &t1, &i2, &t2, &i3, &t3);
288                if (match != 6)
289                        break;
290                AddTriangle(i1-1, t1-1, i2-1, t2-1, i3-1, t3-1);
291                Triangle& triang = triangles[ntriangles-1];
292                Vector& v1 = vertices[ triang.v[0] ],
293                                v2 = vertices[ triang.v[1] ],
294                                v3 = vertices[ triang.v[2] ];
295                triang.center = (v1 + v2 + v3)/3;
296                triang.normal = (ccw) ? (v2 - v1) % (v3 - v1) : (v3 - v1) % (v2 - v1);
297                triang.area = triang.normal.Length()/2;
298                triang.normal.Normalize();
299                triang.up = (v3 - v1) % triang.normal;
300
301                Vector& tp1 = texcoords[ triang.t[0] ],
302                                tp2 = texcoords[ triang.t[1] ],
303                                tp3 = texcoords[ triang.t[2] ];
304                Vector tnormal = (tp2 - tp1) % (tp3 - tp1);
305                triang.texarea = tnormal.Length()/2;
306               
307                triang.BRDF = Color(0.74f/M_PI, 0.73f/M_PI, 0.34f/M_PI);
308                triang.emission = Color(0.0f, 0.0f, 0.0f);
309               
310                if(strcmp("boxl6.obj",fname)==0){
311                        if(triang.normal.x>0.9){
312                                triang.BRDF = Color(0.64f/M_PI, 0.06f/M_PI, 0.04f/M_PI);
313                        }
314                        if(triang.normal.x<-0.9){
315                                triang.BRDF = Color(0.34f/M_PI, 0.57f/M_PI, 0.69f/M_PI);
316                        }
317                       
318                }
319               
320                /*
321                if(strcmp("boxl6.obj",fname)==0){
322                        triang.BRDF=Color(0.9f/M_PI,0.9f/M_PI,0.9f/M_PI);
323                        triang.emission = Color(0.1f, 0.1f, 0.1f);
324                }
325                */
326                if(strcmp("kiskocka6.obj",fname)==0){
327                        triang.BRDF = Color(0.74f/M_PI, 0.73f/M_PI, 0.34f/M_PI);
328                }
329                if(strcmp("light.obj",fname)==0){
330                        triang.BRDF = Color(0.74f/M_PI, 0.73f/M_PI, 0.34f/M_PI);
331                        if(triang.normal.y<-0.9){
332                                triang.emission = Color(20.0f, 20.0f, 20.0f);
333                        }
334                }
335               
336               
337                /*
338                if (islight && (ntriangles == 2291) ){ //1500
339                        triang.emission = Color(250,250,250);
340                }
341                if (islight && (ntriangles == 2292) ){ //1500
342                        triang.emission = Color(250,250,250);
343                }
344                */
345                /*
346                if (islight && (ntriangles == 509) ){ //1500
347                        triang.emission = Color(250,250,250);
348                }
349               
350                if (islight && (ntriangles == 510) ){ //1500
351                        triang.emission = Color(250,250,250);
352                }
353
354                if (islight && (ntriangles == 2399) ){ //1500
355                        triang.emission = Color(250,250,250);
356                }
357                if (islight && (ntriangles == 2400) ){ //1500
358                        triang.emission = Color(250,250,250);
359                }
360                */
361
362                if (!fgets(buffer, 80, ifile))
363                        break;
364        }
365        surface_area = texsurface_area = 0;
366        for(int i = 0; i < ntriangles; i++) {
367                surface_area += triangles[i].area;
368                texsurface_area += triangles[i].texarea;
369        }
370       
371        loaded=true;
372}
373
374
375
376void ObjectModel::GetCenterTriangle( int i, Vector& center, Vector& normal, Vector& up ) {
377        if(i>=ntriangles||i>=MAXTRIANGLES||i<0){
378                return;
379        }
380        /*
381        logFile=fopen("log2.txt","a+" );
382        fprintf(logFile,"Shooter triangle index: %i \n Ntriangles %i\n",i,ntriangles);
383        fclose(logFile);
384        */
385        center = triangles[i].center;
386        normal = triangles[i].normal;
387        up = triangles[i].up;
388}
Note: See TracBrowser for help on using the repository browser.