Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/shadows/src/shadow.cc @ 3728

Last change on this file since 3728 was 3728, checked in by dave, 19 years ago

branches/shadows:code erweitert fuer terrain

File size: 8.8 KB
Line 
1
2/*
3
4    orxonox - the future of 3D-vertical scrollers
5   
6    Copyright (C) 2004 orx
7   
8    This program is free software; you can redistribute it and/or modify it
9    under the terms of the GNU General Public License as published by the Free
10    Software Foundation; either version 2, or (at your option) any later version.
11   
12    ### File Specific:
13    main-programmer: David Gruetter
14    co-programmer: ...
15   
16   
17    Created by Dave, in this file shadow will be implemented in a quite sexy and
18    fast way, with a lot of opengl-code, to keep it fast! The origin of the code
19    comes form an example at www.frustum.org, slitly different although, so that
20    it works with Orxonox:)
21   
22    */
23   
24#include "importer/material.h"
25#include "stdincl.h"
26#include <stdio.h>
27#include <stdarg.h>
28#include <malloc.h>
29#include <math.h>
30#include "shadow.h"
31#include "vector.h"
32
33
34#define SIZE    128
35#define GL_CLAMP_TO_EDGE_EXT 0x812F
36
37using namespace std;
38
39/**
40   \brief default Constructor
41*/
42
43Shadow::Shadow(OBJModel* player,Player* playerangle)
44{
45    this->player=player;
46    this->playerangle=playerangle;
47}
48
49
50/**
51    \brief default destructor
52*/
53
54Shadow::~Shadow()
55{
56}
57
58void Shadow::init()
59{
60   
61    float plane_s[] ={1.0f,0.0f,0.0f,0.0f};
62    float plane_t[] ={0.0f,1.0f,0.0f,0.0f};
63    float plane_r[] ={0.0f,0.0f,1.0f,0.0f};
64    float plane_q[] ={0.0f,0.0f,0.0f,1.0f};
65   
66    glClearDepth(1);
67    glDepthFunc(GL_LEQUAL);
68    glTexGenfv(GL_S,GL_EYE_PLANE,plane_s);
69    glTexGenfv(GL_T,GL_EYE_PLANE,plane_t);
70    glTexGenfv(GL_R,GL_EYE_PLANE,plane_r);
71    glTexGenfv(GL_Q,GL_EYE_PLANE,plane_q);
72    glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
73    glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
74    glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
75    glTexGeni(GL_Q,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
76   
77    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
78    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
79    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE_EXT);
80    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE_EXT);
81    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,SIZE,SIZE,0,GL_RGB,GL_UNSIGNED_BYTE,NULL);
82
83    this->ground_id=glGenLists(1);
84    glNewList(this->ground_id,GL_COMPILE);
85   
86    //blabla
87   
88    glEndList();
89   
90    this->player_id=glGenLists(1);
91    glNewList(this->player_id,GL_COMPILE);
92   
93    this->player->draw();
94   
95    glEndList();   
96   
97    this->image=(unsigned char*)malloc(SIZE*SIZE*4);
98   
99
100}
101
102
103void Shadow::createShadow()
104{
105    glViewport(0,0,SIZE,SIZE);
106    glScissor(0,0,SIZE,SIZE);
107    glEnable(GL_SCISSOR_TEST);
108    glBindTexture(GL_TEXTURE_2D,this->shadow_id);
109   
110    glClearColor(1,1,1,1);
111    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
112    glMatrixMode(GL_PROJECTION);
113    glLoadIdentity();
114    glOrtho(-4.2,4.2,-4.2,4.2,-100,100);
115    glMatrixMode(GL_MODELVIEW);
116    glLoadIdentity();
117   
118    gluLookAt(this->lightPos[0],this->lightPos[1],this->lightPos[2],this->playerPos[0],this->playerPos[1],this->playerPos[2],0,0,1);
119   
120    glColor3f(.1,.1,.1);
121    glTranslatef(this->playerPos[0],this->playerPos[1],this->playerPos[2]);
122    //die Variable angle ist im Player.h als public definiert!!! deshalb kann
123    //von hier aus darauf zugegriffen werden
124    glRotatef(this->playerangle->angle,1.0,0.0,0.0);
125   
126    //Lighting has to be disabled for the shadow to become nice black respectively grey (color(.1,.1,.1))
127    glDisable(GL_LIGHTING);
128    glCallList(this->player_id);
129    glEnable(GL_LIGHTING);
130   
131    glColor3f(1,1,1);
132    glReadPixels(0,0,SIZE,SIZE,GL_RGB,GL_UNSIGNED_BYTE,this->image);
133    blur(this->image,SIZE);
134    glTexSubImage2D(GL_TEXTURE_2D,0,0,0,SIZE,SIZE,GL_RGB,GL_UNSIGNED_BYTE,this->image);
135   
136    glDisable(GL_SCISSOR_TEST);
137    glViewport(0,0,400,300); //Achtung: hier Aufloesung von Orxonox einstellen!
138     
139   
140   
141}
142
143
144/**
145    brief updatePosition is used in the same kind as for skysphere, because
146    the light has got a static orientation(parallel light), we have to always
147    add the same relative coordinates being 0,10,19 to the players position
148    in order to receive the lightPosition. This is needed to calculate the Shadow!!
149
150*/
151
152void Shadow::updatePosition(float x,float y,float z)
153{
154    this->playerPos[0]=x;
155    this->playerPos[1]=y;
156    this->playerPos[2]=z;
157   
158    this->lightPos[0]=this->playerPos[0];
159    this->lightPos[1]=this->playerPos[1]+10;
160    this->lightPos[2]=this->playerPos[2]+19;
161
162   
163}
164
165/**
166    brief takes the ground data from the world.cc class and passes it to shadow.cc
167
168*/
169
170void Shadow::setGround()
171{
172    this->ground_id=glGenLists(1);
173    glNewList(this->ground_id,GL_COMPILE);
174    glBegin(GL_QUADS);
175    for(int i=0;i<100;i+=1)
176        for(int j=0;j<80;j+=1)
177            {
178            glNormal3f(normal_vectors[i][j].x,normal_vectors[i][j].y,normal_vectors[i][j].z);
179            glTexCoord2f(0.0f,0.0f);
180            glVertex3f(vertexes[0][i][j].x,vertexes[0][i][j].y,vertexes[0][i][j].z);
181            glNormal3f(normal_vectors[i+1][j].x,normal_vectors[i+1][j].y,normal_vectors[i+1][j].z);
182            glTexCoord2f(1.0f,0.0f);
183            glVertex3f(vertexes[1][i][j].x,vertexes[1][i][j].y,vertexes[1][i][j].z);
184            glNormal3f(normal_vectors[i+1][j+1].x,normal_vectors[i+1][j+1].y,normal_vectors[i+1][j+1].z);
185            glTexCoord2f(1.0f,1.0f);
186            glVertex3f(vertexes[2][i][j].x,vertexes[2][i][j].y,vertexes[2][i][j].z);
187            glNormal3f(normal_vectors[i][j+1].x,normal_vectors[i][j+1].y,normal_vectors[i][j+1].z);
188            glTexCoord2f(0.0f,1.0f);
189            glVertex3f(vertexes[3][i][j].x,vertexes[3][i][j].y,vertexes[3][i][j].z);
190            }
191    glEnd();
192    glEndList();   
193
194
195
196}
197
198void Shadow::setNormal(Vector a,int i,int j)
199{
200    normal_vectors[i][j]=a;
201
202}
203
204void Shadow::setVertexNum(Vector a,int i,int j,int num)
205{
206    vertexes[num][i][j]=a;
207
208}
209/**
210
211    brief m_inverse simply inverses the *m matrix and stores the result back
212    to *out. This is needed further down in the draw() method
213
214
215*/
216
217void Shadow::m_inverse(const float *m,float *out)
218{
219    float det;
220    det=  m[0]*m[5]*m[10];
221    det+= m[4]*m[9]*m[2];
222    det+= m[8]*m[1]*m[6];
223    det-= m[8]*m[5]*m[2];
224    det-= m[4]*m[1]*m[10];
225    det-= m[0]*m[9]*m[6];
226   
227    if(det!= 0.0)
228        det=1.0/det;
229    out[0]=  (m[5]*m[10]-m[9]*m[6])*det;
230    out[1]= -(m[1]*m[10]-m[9]*m[2])*det;
231    out[2]=  (m[1]*m[6]-m[5]*m[2])*det;
232    out[3]= 0.0;
233    out[4]= -(m[4]*m[10]-m[8]*m[6])*det;
234    out[5]=  (m[0]*m[10]-m[8]*m[2])*det;
235    out[6]= -(m[0]*m[6]-m[4]*m[2])*det;
236    out[7]= 0.0;
237    out[8]=  (m[4]*m[9]-m[8]*m[5])*det;
238    out[9]= -(m[0]*m[9]-m[8]*m[1])*det;
239    out[10]= (m[0]*m[5]-m[4]*m[1])*det;
240    out[11]= 0.0;
241    out[12]=- (m[12]*out[0]+m[13]*out[4]+m[14]*out[8]);
242    out[13]=- (m[12]*out[1]+m[13]*out[5]+m[14]*out[9]);
243    out[14]=- (m[12]*out[2]+m[13]*out[6]+m[14]*out[10]);
244    out[15]= 1.0;
245
246
247}
248
249/**
250    brief Method draw() is called after each tick() from the world.cc class
251*/
252
253void Shadow::draw()
254{
255    float m[16],im[16];
256    createShadow();
257   
258    //glClearColor(0,0,0,0);
259    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
260    //glMatrixMode(GL_PROJECTION);
261    //glLoadIdentity();
262    //gluPerspective(45,4.0/3.0,.5,100);
263    //glMatrixMode(GL_MODELVIEW);
264    //glLoadIdentity();
265   
266    //gluLookAt(this->cameraPos[0],this->cameraPos[1],this->cameraPos[2],this->playerPos[0],this->playerPos[1],this->playerPos[2],0,0,1);
267   
268    glEnable(GL_TEXTURE_GEN_S);
269    glEnable(GL_TEXTURE_GEN_T);
270    glEnable(GL_TEXTURE_GEN_R);
271    glEnable(GL_TEXTURE_GEN_Q);
272    glGetFloatv(GL_MODELVIEW_MATRIX,m);
273    m_inverse(m,im);
274    glMatrixMode(GL_TEXTURE);
275    glLoadIdentity();
276    glTranslatef(0.5,0.5,1.0);
277    glScalef(0.5,0.5,1.0);
278    glOrtho(-1,1,-1,1,-1,1);
279   
280    gluLookAt(this->lightPos[0],this->lightPos[1],this->lightPos[2],this->playerPos[0],this->playerPos[1],this->playerPos[2],0,0,1);
281   
282    glMultMatrixf(im);
283    glEnable(GL_TEXTURE_2D),
284    glBindTexture(GL_TEXTURE_2D,this->shadow_id);
285    glEnable(GL_BLEND);
286    glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
287    glCallList(this->ground_id);
288    glDisable(GL_BLEND);
289   
290    glLoadIdentity();
291    glMatrixMode(GL_MODELVIEW);
292    glDisable(GL_TEXTURE_GEN_S);
293    glDisable(GL_TEXTURE_GEN_T);
294    glDisable(GL_TEXTURE_GEN_R);
295    glDisable(GL_TEXTURE_GEN_Q);
296   
297   
298   
299}
300
301
302
303/**
304    \don't ask me how this works, but it adds a blur effect to the shadow
305    \for it doesn't look that edgy
306   
307*/
308void Shadow::blur(unsigned char *in,int size)
309{
310    int x,y,sum,size3=size*3;
311    unsigned char *out,*inp,*outp;
312    out = (unsigned char *)malloc(size * size * 3);
313    memset(out,255,size *size *3);
314   
315    inp=in+size3;
316    outp=out+size3;
317    for(y=1;y<size-1;y++){
318        inp+=3;
319        outp+=3;
320        for(x=1;x<size-1;x++){
321            sum=inp[-size3-3]+ inp[-size3] + inp[-size3+3]+
322            inp[-3]+inp[0]+inp[3]+
323            inp[size3-3]+inp[size3]+inp[size3+3];
324            sum/=9;
325            inp+=3;
326            *outp++ =sum;
327            *outp++ =sum;
328            *outp++ =sum;
329        }
330        inp+=3;
331        outp+=3;
332    }
333   
334    memcpy(in,out,size*size*3);
335    free(out);
336       
337           
338   
339
340
341}
342
343
Note: See TracBrowser for help on using the repository browser.