Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

branches/shadows: Ok, das Abbild vom Raumschiff funktioniert schon mal, sieht recht cool aus:)

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