Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

branches/shadows: ganzes Raumschiff sichtbar, und Schatten schwarz gemacht:)

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