Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3839 was 3839, checked in by dave, 20 years ago

Hab wieder mal nichts kapiert, aber beim Schatten hat sich trotzdem viel getan:)

File size: 7.5 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(GLuint ground_id_imported)
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   
67    this->mat=new Material("Ground");
68    this->mat->setDiffuseMap("../data/pictures/ground.tga");
69    this->mat->setIllum(3);
70   
71    glClearDepth(1);
72    glDepthFunc(GL_LEQUAL);
73    glTexGenfv(GL_S,GL_EYE_PLANE,plane_s);
74    glTexGenfv(GL_T,GL_EYE_PLANE,plane_t);
75    glTexGenfv(GL_R,GL_EYE_PLANE,plane_r);
76    glTexGenfv(GL_Q,GL_EYE_PLANE,plane_q);
77    glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
78    glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
79    glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
80    glTexGeni(GL_Q,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
81   
82    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
83    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
84    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE_EXT);
85    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE_EXT);
86    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,SIZE,SIZE,0,GL_RGB,GL_UNSIGNED_BYTE,NULL);
87
88   
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    this->ground_id=ground_id_imported;
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   
111    gluLookAt(this->lightPos[0],this->lightPos[1],this->lightPos[2],this->playerPos[0],this->playerPos[1],this->playerPos[2],0,0,1);
112   
113    glColor3f(.1,.1,.1);
114    glTranslatef(this->playerPos[0],this->playerPos[1],this->playerPos[2]);
115    //die Variable angle ist im Player.h als public definiert!!! deshalb kann
116    //von hier aus darauf zugegriffen werden
117    glRotatef(this->playerangle->angle,1.0,0.0,0.0);
118   
119    //Lighting has to be disabled for the shadow to become nice black respectively grey (color(.1,.1,.1))
120    glDisable(GL_LIGHTING);
121    glCallList(this->player_id);
122    glEnable(GL_LIGHTING);
123   
124   
125   
126    //glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,SIZE,SIZE);
127    glReadPixels(0,0,SIZE,SIZE,GL_RGB,GL_UNSIGNED_BYTE,this->image);
128    blur(this->image,SIZE);
129    glTexSubImage2D(GL_TEXTURE_2D,0,0,0,SIZE,SIZE,GL_RGB,GL_UNSIGNED_BYTE,this->image);
130   
131    glDisable(GL_SCISSOR_TEST);
132    glViewport(0,0,1024,768); //Achtung: hier Aufloesung von Orxonox einstellen!
133     
134   
135   
136}
137
138void Shadow::draw()
139{
140    float m[16],im[16];
141   
142    createShadow();
143    //glClearColor(0,0,0,1);
144    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
145    //glMatrixMode(GL_PROJECTION);
146    //glLoadIdentity();
147    //gluPerspective(45,4.0/3.0,.5,100);
148    //glMatrixMode(GL_MODELVIEW);
149    //glLoadIdentity();
150       
151    this->mat->select();
152    glCallList(this->ground_id);
153   
154    //glDisable(GL_TEXTURE_2D);
155       
156    glEnable(GL_TEXTURE_GEN_S);
157    glEnable(GL_TEXTURE_GEN_T);
158    glEnable(GL_TEXTURE_GEN_R);
159    glEnable(GL_TEXTURE_GEN_Q);
160    glGetFloatv(GL_MODELVIEW_MATRIX,m);
161    m_inverse(m,im);
162    glMatrixMode(GL_TEXTURE);
163    glLoadIdentity();
164    //glTranslatef(.5,.5,0);
165    //glScalef(.5,.5,1.0);
166    //glOrtho(-1,1,-1,1,-1,1);
167   
168    gluLookAt(this->lightPos[0],this->lightPos[1],this->lightPos[2],this->playerPos[0],this->playerPos[1],this->playerPos[2],0,0,1);
169   
170    glMultMatrixf(im);
171    glEnable(GL_TEXTURE_2D),
172    glBindTexture(GL_TEXTURE_2D,this->shadow_id);
173    glEnable(GL_BLEND);
174    glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
175    //glCallList(this->ground_id);
176    glDisable(GL_BLEND);
177    glDisable(GL_TEXTURE_2D);
178   
179    glLoadIdentity();
180    glMatrixMode(GL_MODELVIEW);
181    glDisable(GL_TEXTURE_GEN_S);
182    glDisable(GL_TEXTURE_GEN_T);
183    glDisable(GL_TEXTURE_GEN_R);
184    glDisable(GL_TEXTURE_GEN_Q);
185   
186   
187   
188   
189   
190}
191
192/**
193    brief updatePosition is used in the same kind as for skysphere, because
194    the light has got a static orientation(parallel light), we have to always
195    add the same relative coordinates being 0,10,19 to the players position
196    in order to receive the lightPosition. This is needed to calculate the Shadow!!
197
198*/
199
200void Shadow::updatePosition(float x,float y,float z)
201{
202    this->playerPos[0]=x;
203    this->playerPos[1]=y;
204    this->playerPos[2]=z;
205   
206    this->lightPos[0]=this->playerPos[0];
207    this->lightPos[1]=this->playerPos[1]+10;
208    this->lightPos[2]=this->playerPos[2]+19;
209
210   
211}
212
213
214
215
216
217/**
218
219    brief m_inverse simply inverses the *m matrix and stores the result back
220    to *out. This is needed further down in the draw() method
221
222
223*/
224
225void Shadow::m_inverse(const float *m,float *out)
226{
227    float det;
228    det=  m[0]*m[5]*m[10];
229    det+= m[4]*m[9]*m[2];
230    det+= m[8]*m[1]*m[6];
231    det-= m[8]*m[5]*m[2];
232    det-= m[4]*m[1]*m[10];
233    det-= m[0]*m[9]*m[6];
234   
235    if(det!= 0.0)
236        det=1.0/det;
237    out[0]=  (m[5]*m[10]-m[9]*m[6])*det;
238    out[1]= -(m[1]*m[10]-m[9]*m[2])*det;
239    out[2]=  (m[1]*m[6]-m[5]*m[2])*det;
240    out[3]= 0.0;
241    out[4]= -(m[4]*m[10]-m[8]*m[6])*det;
242    out[5]=  (m[0]*m[10]-m[8]*m[2])*det;
243    out[6]= -(m[0]*m[6]-m[4]*m[2])*det;
244    out[7]= 0.0;
245    out[8]=  (m[4]*m[9]-m[8]*m[5])*det;
246    out[9]= -(m[0]*m[9]-m[8]*m[1])*det;
247    out[10]= (m[0]*m[5]-m[4]*m[1])*det;
248    out[11]= 0.0;
249    out[12]=- (m[12]*out[0]+m[13]*out[4]+m[14]*out[8]);
250    out[13]=- (m[12]*out[1]+m[13]*out[5]+m[14]*out[9]);
251    out[14]=- (m[12]*out[2]+m[13]*out[6]+m[14]*out[10]);
252    out[15]= 1.0;
253
254
255}
256
257/**
258    brief Method draw() is called after each tick() from the world.cc class
259*/
260
261
262
263
264/**
265    \don't ask me how this works, but it adds a blur effect to the shadow
266    \for it doesn't look that edgy
267   
268*/
269void Shadow::blur(unsigned char *in,int size)
270{
271    int x,y,sum,size3=size*3;
272    unsigned char *out,*inp,*outp;
273    out = (unsigned char *)malloc(size * size * 3);
274    memset(out,255,size *size *3);
275   
276    inp=in+size3;
277    outp=out+size3;
278    for(y=1;y<size-1;y++){
279        inp+=3;
280        outp+=3;
281        for(x=1;x<size-1;x++){
282            sum=inp[-size3-3]+ inp[-size3] + inp[-size3+3]+
283            inp[-3]+inp[0]+inp[3]+
284            inp[size3-3]+inp[size3]+inp[size3+3];
285            sum/=9;
286            inp+=3;
287            *outp++ =sum;
288            *outp++ =sum;
289            *outp++ =sum;
290        }
291        inp+=3;
292        outp+=3;
293    }
294   
295    memcpy(in,out,size*size*3);
296    free(out);
297       
298           
299   
300
301
302}
303
304
Note: See TracBrowser for help on using the repository browser.