Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

branches/shadows/src:Aufruf von createShadow() jetzt von einem anderen Ort, aber immer noch Problem dass Schatten noch nicht sichtbar, jedoch vorhanden

File size: 7.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(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_REPEAT);
85    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
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    this->player->draw();
93    glEndList();   
94   
95    this->image=(unsigned char*)malloc(SIZE*SIZE*4);
96    this->ground_id=ground_id_imported;
97
98}
99
100
101void Shadow::createShadow()
102{   
103    glViewport(0,0,SIZE,SIZE);
104    glScissor(0,0,SIZE,SIZE);
105    glEnable(GL_SCISSOR_TEST);
106    glBindTexture(GL_TEXTURE_2D,this->shadow_id);
107   
108   
109    float m[16],m2[16]; 
110    glClearColor(1,1,1,1);
111    //glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
112   
113    glMatrixMode(GL_PROJECTION);
114    glGetFloatv(GL_PROJECTION_MATRIX,m);
115    glLoadIdentity();
116    glOrtho(-4.2,4.2,-4.2,4.2,-100,100);
117    glMatrixMode(GL_MODELVIEW);
118    glGetFloatv(GL_MODELVIEW_MATRIX,m2);
119    glLoadIdentity();
120   
121    gluLookAt(this->lightPos[0],this->lightPos[1],this->lightPos[2],this->playerPos[0],this->playerPos[1],this->playerPos[2],0,0,1);
122   
123    glColor3f(.1,.1,.1);
124    glTranslatef(this->playerPos[0],this->playerPos[1],this->playerPos[2]);
125    //die Variable angle ist im Player.h als public definiert!!! deshalb kann
126    //von hier aus darauf zugegriffen werden
127    glRotatef(this->playerangle->angle,1.0,0.0,0.0);
128   
129    //Lighting has to be disabled for the shadow to become nice black respectively grey (color(.1,.1,.1))
130    glDisable(GL_LIGHTING);
131    glCallList(this->player_id);
132    glEnable(GL_LIGHTING);
133    glColor3f(1,1,1);
134   
135   
136   
137    glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,SIZE,SIZE);
138    //glReadPixels(0,0,SIZE,SIZE,GL_RGB,GL_UNSIGNED_BYTE,this->image);
139    //blur(this->image,SIZE);
140    //glTexSubImage2D(GL_TEXTURE_2D,30,30,30,SIZE,SIZE,GL_RGB,GL_UNSIGNED_BYTE,this->image);
141   
142    glDisable(GL_SCISSOR_TEST);
143    glViewport(0,0,400,300); //Achtung: hier Aufloesung von Orxonox einstellen!
144   
145    //Die oben veraenderten und zwischengespeicherten werte wieder herstellen!
146    glMatrixMode(GL_PROJECTION);
147    glLoadIdentity();
148    glMultMatrixf(m);
149    glMatrixMode(GL_MODELVIEW);
150    glLoadIdentity();
151    glMultMatrixf(m2); 
152 
153}
154
155void Shadow::draw()
156{
157    float m[16],im[16];
158   
159    //createShadow();
160 
161       
162    glDisable(GL_COLOR_MATERIAL);
163    this->mat->select();
164    glCallList(this->ground_id);
165   
166   
167       
168    /*shadow*/
169    glEnable(GL_TEXTURE_GEN_S);
170    glEnable(GL_TEXTURE_GEN_T);
171    glEnable(GL_TEXTURE_GEN_R);
172    glEnable(GL_TEXTURE_GEN_Q);
173    glGetFloatv(GL_MODELVIEW_MATRIX,m);
174    m_inverse(m,im);
175    glMatrixMode(GL_TEXTURE);
176    glLoadIdentity();
177    glTranslatef(1.5,.5,0);
178    glScalef(.5f,1.0,.5f);
179    glOrtho(-1,1,-1,1,-100,100);
180   
181    gluLookAt(this->lightPos[0],this->lightPos[1],this->lightPos[2],this->playerPos[0],this->playerPos[1],this->playerPos[2],0,0,1);
182   
183    glMultMatrixf(im);
184    //glEnable(GL_TEXTURE_2D);
185    //glBindTexture(GL_TEXTURE_2D,this->shadow_id);
186    glEnable(GL_BLEND);
187    glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
188    //glCallList(this->ground_id);
189    glDisable(GL_BLEND);
190   
191   
192    glLoadIdentity();
193    glMatrixMode(GL_MODELVIEW);
194    glDisable(GL_TEXTURE_GEN_S);
195    glDisable(GL_TEXTURE_GEN_T);
196    glDisable(GL_TEXTURE_GEN_R);
197    glDisable(GL_TEXTURE_GEN_Q);
198   
199
200   
201   
202   
203}
204
205/**
206    brief updatePosition is used in the same kind as for skysphere, because
207    the light has got a static orientation(parallel light), we have to always
208    add the same relative coordinates being 0,10,19 to the players position
209    in order to receive the lightPosition. This is needed to calculate the Shadow!!
210
211*/
212
213void Shadow::updatePosition(float x,float y,float z)
214{
215    this->playerPos[0]=x;
216    this->playerPos[1]=y;
217    this->playerPos[2]=z;
218   
219    this->lightPos[0]=this->playerPos[0];
220    this->lightPos[1]=this->playerPos[1]+10;
221    this->lightPos[2]=this->playerPos[2]+19;
222
223   
224}
225
226
227
228
229
230/**
231
232    brief m_inverse simply inverses the *m matrix and stores the result back
233    to *out. This is needed further down in the draw() method
234
235
236*/
237
238void Shadow::m_inverse(const float *m,float *out)
239{
240    float det;
241    det=  m[0]*m[5]*m[10];
242    det+= m[4]*m[9]*m[2];
243    det+= m[8]*m[1]*m[6];
244    det-= m[8]*m[5]*m[2];
245    det-= m[4]*m[1]*m[10];
246    det-= m[0]*m[9]*m[6];
247   
248    if(det!= 0.0)
249        det=1.0/det;
250    out[0]=  (m[5]*m[10]-m[9]*m[6])*det;
251    out[1]= -(m[1]*m[10]-m[9]*m[2])*det;
252    out[2]=  (m[1]*m[6]-m[5]*m[2])*det;
253    out[3]= 0.0;
254    out[4]= -(m[4]*m[10]-m[8]*m[6])*det;
255    out[5]=  (m[0]*m[10]-m[8]*m[2])*det;
256    out[6]= -(m[0]*m[6]-m[4]*m[2])*det;
257    out[7]= 0.0;
258    out[8]=  (m[4]*m[9]-m[8]*m[5])*det;
259    out[9]= -(m[0]*m[9]-m[8]*m[1])*det;
260    out[10]= (m[0]*m[5]-m[4]*m[1])*det;
261    out[11]= 0.0;
262    out[12]=- (m[12]*out[0]+m[13]*out[4]+m[14]*out[8]);
263    out[13]=- (m[12]*out[1]+m[13]*out[5]+m[14]*out[9]);
264    out[14]=- (m[12]*out[2]+m[13]*out[6]+m[14]*out[10]);
265    out[15]= 1.0;
266
267
268}
269
270/**
271    brief Method draw() is called after each tick() from the world.cc class
272*/
273
274
275
276
277/**
278    \don't ask me how this works, but it adds a blur effect to the shadow
279    \for it doesn't look that edgy
280   
281*/
282void Shadow::blur(unsigned char *in,int size)
283{
284    int x,y,sum,size3=size*3;
285    unsigned char *out,*inp,*outp;
286    out = (unsigned char *)malloc(size * size * 3);
287    memset(out,255,size *size *3);
288   
289    inp=in+size3;
290    outp=out+size3;
291    for(y=1;y<size-1;y++){
292        inp+=3;
293        outp+=3;
294        for(x=1;x<size-1;x++){
295            sum=inp[-size3-3]+ inp[-size3] + inp[-size3+3]+
296            inp[-3]+inp[0]+inp[3]+
297            inp[size3-3]+inp[size3]+inp[size3+3];
298            sum/=9;
299            inp+=3;
300            *outp++ =sum;
301            *outp++ =sum;
302            *outp++ =sum;
303        }
304        inp+=3;
305        outp+=3;
306    }
307   
308    memcpy(in,out,size*size*3);
309    free(out);
310       
311           
312   
313
314
315}
316
317
Note: See TracBrowser for help on using the repository browser.