Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

branches/shadows: es geht voran

File size: 7.3 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,SIZE,SIZE);
104    glScissor(0,0,SIZE,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(-1,1,-1,1,-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(.4,.4,.4);
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   
125    glCallList(this->player_id);
126    glColor3f(1,1,1);
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
138
139/**
140    brief updatePosition is used in the same kind as for skysphere, because
141    the light has got a static orientation(parallel light), we have to always
142    add the same relative coordinates being 0,10,19 to the players position
143    in order to receive the lightPosition. This is needed to calculate the Shadow!!
144
145*/
146
147void Shadow::updatePosition(float x,float y,float z)
148{
149    this->playerPos[0]=x;
150    this->playerPos[1]=y;
151    this->playerPos[2]=z;
152   
153    this->lightPos[0]=this->playerPos[0];
154    this->lightPos[1]=this->playerPos[1]+10;
155    this->lightPos[2]=this->playerPos[2]+19;
156
157   
158}
159/**
160
161    brief m_inverse simply inverses the *m matrix and stores the result back
162    to *out. This is needed further down in the draw() method
163
164
165*/
166
167void Shadow::m_inverse(const float *m,float *out)
168{
169    float det;
170    det=  m[0]*m[5]*m[10];
171    det+= m[4]*m[9]*m[2];
172    det+= m[8]*m[1]*m[6];
173    det-= m[8]*m[5]*m[2];
174    det-= m[4]*m[1]*m[10];
175    det-= m[0]*m[9]*m[6];
176   
177    if(det!= 0.0)
178        det=1.0/det;
179    out[0]=  (m[5]*m[10]-m[9]*m[6])*det;
180    out[1]= -(m[1]*m[10]-m[9]*m[2])*det;
181    out[2]=  (m[1]*m[6]-m[5]*m[2])*det;
182    out[3]= 0.0;
183    out[4]= -(m[4]*m[10]-m[8]*m[6])*det;
184    out[5]=  (m[0]*m[10]-m[8]*m[2])*det;
185    out[6]= -(m[0]*m[6]-m[4]*m[2])*det;
186    out[7]= 0.0;
187    out[8]=  (m[4]*m[9]-m[8]*m[5])*det;
188    out[9]= -(m[0]*m[9]-m[8]*m[1])*det;
189    out[10]= (m[0]*m[5]-m[4]*m[1])*det;
190    out[11]= 0.0;
191    out[12]=- (m[12]*out[0]+m[13]*out[4]+m[14]*out[8]);
192    out[13]=- (m[12]*out[1]+m[13]*out[5]+m[14]*out[9]);
193    out[14]=- (m[12]*out[2]+m[13]*out[6]+m[14]*out[10]);
194    out[15]= 1.0;
195
196
197}
198
199/**
200    brief Method draw() is called after each tick() from the world.cc class
201*/
202
203void Shadow::draw()
204{
205    float m[16],im[16];
206    createShadow();
207   
208    /*glClearColor(0,0,0,0);
209    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
210    glMatrixMode(GL_PROJECTION);
211    glLoadIdentity();
212    gluPerspective(45,4.0/3.0,.5,100);
213    glMatrixMode(GL_MODELVIEW);
214    glLoadIdentity();
215   
216    gluLookAt(this->cameraPos[0],this->cameraPos[1],this->cameraPos[2],this->playerPos[0],this->playerPos[1],this->playerPos[2],0,0,1);
217    */
218    glEnable(GL_TEXTURE_GEN_S);
219    glEnable(GL_TEXTURE_GEN_T);
220    glEnable(GL_TEXTURE_GEN_R);
221    glEnable(GL_TEXTURE_GEN_Q);
222    glGetFloatv(GL_MODELVIEW_MATRIX,m);
223    m_inverse(m,im);
224    glMatrixMode(GL_TEXTURE);
225    glLoadIdentity();
226    glTranslatef(0.5,0.5,1.0);
227    glOrtho(-1,1,-1,1,-1,1);
228   
229    gluLookAt(this->lightPos[0],this->lightPos[1],this->lightPos[2],this->playerPos[0],this->playerPos[1],this->playerPos[2],0,0,1);
230   
231    glMultMatrixf(im);
232    glEnable(GL_TEXTURE_2D),
233    glBindTexture(GL_TEXTURE_2D,this->shadow_id);
234    glEnable(GL_BLEND);
235    glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
236    glCallList(ground_id);
237    glDisable(GL_BLEND);
238   
239    glLoadIdentity();
240    glMatrixMode(GL_MODELVIEW);
241    glDisable(GL_TEXTURE_GEN_S);
242    glDisable(GL_TEXTURE_GEN_T);
243    glDisable(GL_TEXTURE_GEN_R);
244    glDisable(GL_TEXTURE_GEN_Q);
245   
246   
247   
248}
249
250
251
252/**
253    \don't ask me how this works, but it adds a blur effect to the shadow
254    \for it doesn't look that edgy
255   
256*/
257void Shadow::blur(unsigned char *in,int size)
258{
259    int x,y,sum,size3=size*3;
260    unsigned char *out,*inp,*outp;
261    out = (unsigned char *)malloc(size * size * 3);
262    memset(out,255,size *size *3);
263   
264    inp=in+size3;
265    outp=out+size3;
266    for(y=1;y<size-1;y++){
267        inp+=3;
268        outp+=3;
269        for(x=1;x<size-1;x++){
270            sum=inp[-size3-3]+ inp[-size3] + inp[-size3+3]+
271            inp[-3]+inp[0]+inp[3]+
272            inp[size3-3]+inp[size3]+inp[size3+3];
273            sum/=9;
274            inp+=3;
275            *outp++ =sum;
276            *outp++ =sum;
277            *outp++ =sum;
278        }
279        inp+=3;
280        outp+=3;
281    }
282   
283    memcpy(in,out,size*size*3);
284    free(out);
285       
286           
287   
288
289
290}
291
292
Note: See TracBrowser for help on using the repository browser.