[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / visualizations / Vortex / VortexVis / Effects / Map.cpp
1 /*
2  *  Copyright © 2010-2013 Team XBMC
3  *  http://xbmc.org
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19
20 #include "map.h"
21 #include "angelscript.h"
22
23 #include "Shader.h"
24
25 #define GRID_WIDTH (32)
26 #define GRID_HEIGHT (24)
27
28 #define NUM_INDICES (1584)
29
30 #define TEX_WIDTH ( 1024 )
31 #define TEX_HEIGHT ( 512 )
32
33 Map::Map()
34 {
35         m_iCurrentTexture = 0;
36         m_timed = false;
37         m_tex1 = Renderer::CreateTexture(TEX_WIDTH, TEX_HEIGHT);
38         m_tex2 = Renderer::CreateTexture(TEX_WIDTH, TEX_HEIGHT);
39
40         m_texture = m_tex1;
41
42         m_vertices = NULL;
43
44         Renderer::GetDevice()->CreateIndexBuffer( NUM_INDICES * 2, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_iBuffer, NULL );
45         Renderer::GetDevice()->CreateVertexBuffer( GRID_WIDTH * GRID_HEIGHT * sizeof( PosColNormalUVVertex ),
46                                                                                            D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT,
47                                                                                            &m_vBuffer, NULL );
48
49         PosColNormalUVVertex* v;
50         m_vBuffer->Lock( 0, 0, (void**)&v, 0 );
51
52         for (int y = 0; y < GRID_HEIGHT; y++)
53         {
54                 for (int x = 0; x < GRID_WIDTH; x ++)
55                 {
56                         //      0-(32 / 2) / (32 / 2) = -1
57                         //      15-(32 / 2) / (32 / 2) = -1
58                         v->Coord.x = ((float)x - ((GRID_WIDTH -1 ) / 2.0f)) / ((GRID_WIDTH -1 ) / 2.0f);
59                         v->Coord.y = -(((float)y - ((GRID_HEIGHT -1 ) / 2.0f)) / ((GRID_HEIGHT -1 ) / 2.0f));
60 //                      v->Diffuse= 0xffffffff;
61                         v->FDiffuse.x = 1.0f;
62                         v->FDiffuse.y = 1.0f;
63                         v->FDiffuse.z = 1.0f;
64                         v->FDiffuse.w = 1.0f;
65                         //                      v->coord. = 1.0f;
66                         v->Coord.z = 0.0f;
67                         //                      v->u = ((((float)x - ((GRID_WIDTH -1 ) / 2.0f)) / ((GRID_WIDTH -1 ) / 2.0f) * 256 + 256) * (1.0f / 512)) + (0.5f / 512);
68                         //                      v->v = ((((float)y - ((GRID_HEIGHT -1 ) / 2.0f)) / ((GRID_HEIGHT -1 ) / 2.0f) * 256 + 256) * (1.0f / 512)) + (0.5f / 512);
69                         v->u = ((float)x / (GRID_WIDTH -1));// + (0.5f / TEX_SIZE);
70                         v->v = ((float)y / (GRID_HEIGHT -1));// + (0.5f / TEX_SIZE) ;//+ (5 / 512.0f);
71                         v++;
72                 }
73         }
74         m_vBuffer->Unlock();
75
76
77         //---------------------------------------------------------------------------
78         // Build indices
79         unsigned short* pIndices;
80         m_iBuffer->Lock( 0, 0, (void**)&pIndices, 0 );
81         int numIndices = 0;
82         unsigned short iIndex = 0;
83
84         for (int a = 0; a < GRID_HEIGHT; ++a)
85         {
86                 for (int i = 0; i < GRID_WIDTH; ++i, pIndices += 2, ++iIndex )
87                 {
88                         pIndices[ 0 ] = iIndex + GRID_WIDTH;
89                         pIndices[ 1 ] = iIndex;
90                         numIndices+=2;
91                 }
92
93                 // connect two strips by inserting two degenerate triangles 
94                 if (GRID_WIDTH - 2 > a)
95                 {
96                         pIndices[0] = iIndex - 1;
97                         pIndices[1] = iIndex + GRID_WIDTH;
98
99                         pIndices += 2;
100                         numIndices += 2;
101                 }
102         }
103
104         m_numIndices = numIndices - 2;
105
106         m_iBuffer->Unlock();
107 }
108
109 Map::~Map()
110 {
111         if ( m_vertices != NULL )
112         {
113                 m_vBuffer->Unlock();
114                 m_vertices = NULL;
115         }
116         m_vBuffer->Release();
117         m_iBuffer->Release();
118         m_tex1->Release();
119         m_tex2->Release();
120 }
121
122 __inline float MapCol( float a )
123 {
124         //      static float speed = 1.02f;
125         float res = powf(1.02f, a);
126         if (res < 0)
127                 res = 0;
128         else if (res > 1)
129                 res = 1.0f;
130         return res;
131 }
132
133 __inline float Clamp( float a )
134 {
135         if (a < 0)
136                 a = 0;
137         else if (a > 1)
138                 a = 1.0f;
139         return a;
140 }
141
142 void Map::SetTimed()
143 {
144         m_timed = true;
145 }
146
147 void Map::SetValues(unsigned int x, unsigned int y, float uOffset, float vOffset, float r, float g, float b)
148 {
149         int index = ((y )* GRID_WIDTH) + x;
150         if( index >= GRID_HEIGHT * GRID_WIDTH )
151         {
152                 return;
153         }
154
155         if( m_vertices == NULL )
156         {
157                 m_vBuffer->Lock( 0, 0, (void**)&m_vertices, 0 );
158         }
159
160         PosColNormalUVVertex* v = &m_vertices[ index ];
161
162         static const float invWidth = 1.0f / ( GRID_WIDTH - 1 );
163         static const float invHeight = 1.0f / ( GRID_HEIGHT - 1 );
164
165         if( m_timed )
166         {
167                 v->u = ((float)x * invWidth ) + (0.5f / TEX_WIDTH)  + ( ( uOffset ) * invWidth );
168                 v->v = ((float)y * invHeight ) + (0.5f / TEX_HEIGHT) + ( ( vOffset ) * invHeight );
169 /*              unsigned char* col = (unsigned char*)&v->Diffuse;
170                 col[3] = 0xff;
171                 col[2] = int(MapCol(r) * 255);
172                 col[1] = int(MapCol(g) * 255);
173                 col[0] = int(MapCol(b) * 255);
174 */
175                 v->FDiffuse.x = MapCol(r);
176                 v->FDiffuse.y = MapCol(g);
177                 v->FDiffuse.z = MapCol(b);
178                 v->FDiffuse.w = 1.0f;
179         }
180         else
181         {
182                 v->u = ((float)x * invWidth ) + (0.5f / TEX_WIDTH)  + ((uOffset));
183                 v->v = ((float)y * invHeight ) + (0.5f / TEX_HEIGHT) + ((vOffset));
184 //              unsigned char* col = (unsigned char*)&v->Diffuse;
185 //              col[3] = 0xff;
186 //              col[2] = int(Clamp(r) * 255);
187 //              col[1] = int(Clamp(g) * 255);
188 //              col[0] = int(Clamp(b) * 255);
189                 v->FDiffuse.x = r;
190                 v->FDiffuse.y = g;
191                 v->FDiffuse.z = b;
192                 v->FDiffuse.w = 1;
193         }
194 }
195
196 void Map::Render()
197 {
198         if ( m_vertices != NULL )
199         {
200                 m_vBuffer->Unlock();
201                 m_vertices = NULL;
202         }
203
204         if ( m_iCurrentTexture == 0 )
205         {
206                 Renderer::SetRenderTarget(m_tex1);
207                 Renderer::SetTexture(m_tex2);
208                 m_texture = m_tex1;
209         }
210         else
211         {
212                 Renderer::SetRenderTarget(m_tex2);
213                 Renderer::SetTexture(m_tex1);
214                 m_texture = m_tex2;
215         }
216
217         Renderer::PushMatrix();
218         Renderer::SetIdentity();
219         float oldAspect = Renderer::GetAspect();
220         Renderer::SetAspect(0);
221         Renderer::Translate(0, 0, 2.414f);
222
223         DiffuseUVVertexShader* pShader = &DiffuseUVVertexShader::StaticType;
224         Renderer::CommitTransforms( pShader );
225         Renderer::CommitTextureState();
226         Renderer::GetDevice()->SetVertexShader( pShader->GetVertexShader() );
227         Renderer::GetDevice()->SetVertexDeclaration( g_pPosColUVDeclaration );
228
229         Renderer::GetDevice()->SetStreamSource( 0,
230                                                                                         m_vBuffer,
231                                                                                         0,
232                                                                                         sizeof( PosColNormalUVVertex ) );
233
234         Renderer::GetDevice()->SetIndices( m_iBuffer );
235
236         Renderer::GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, 0, GRID_WIDTH * GRID_HEIGHT, 0, 1514 );
237
238         Renderer::GetDevice()->SetStreamSource( 0,
239                                                                                         NULL,
240                                                                                         0,
241                                                                                         0 );
242
243         Renderer::GetDevice()->SetIndices( NULL );
244
245         Renderer::SetTexture(NULL);
246         Renderer::PopMatrix();
247         Renderer::SetAspect(oldAspect);
248
249         m_iCurrentTexture = 1 - m_iCurrentTexture;
250
251 } // Render
252
253 //-----------------------------------------------------------------------------
254 // Script interface
255
256 Map* Map_Factory()
257 {
258         /* The class constructor is initializing the reference counter to 1*/
259         return new Map();
260 }
261
262 void Map::RegisterScriptInterface( asIScriptEngine* pScriptEngine )
263 {
264 #ifndef assert
265 #define assert
266 #endif
267         int r;
268
269         // Registering the reference type
270         r = pScriptEngine->RegisterObjectType("Map", 0, asOBJ_REF);      assert(r >= 0);
271
272         // Registering the factory behaviour
273         r = pScriptEngine->RegisterObjectBehaviour("Map", asBEHAVE_FACTORY, "Map@ f()", asFUNCTION(Map_Factory), asCALL_CDECL); assert( r >= 0 );
274
275         // Registering the addref/release behaviours
276         r = pScriptEngine->RegisterObjectBehaviour("Map", asBEHAVE_ADDREF, "void f()", asMETHOD(Map, AddRef), asCALL_THISCALL); assert(r >= 0);
277         r = pScriptEngine->RegisterObjectBehaviour("Map", asBEHAVE_RELEASE, "void f()", asMETHOD(Map, Release), asCALL_THISCALL); assert(r >= 0);
278         r = pScriptEngine->RegisterObjectMethod("Map", "void Render()", asMETHOD(Map, Render), asCALL_THISCALL); assert(r >= 0);
279         r = pScriptEngine->RegisterObjectMethod("Map", "void SetValues(int, int, float, float, float, float, float)", asMETHOD(Map, SetValues), asCALL_THISCALL); assert(r >= 0);
280         r = pScriptEngine->RegisterObjectMethod("Map", "void SetTimed()", asMETHOD(Map, SetTimed), asCALL_THISCALL); assert(r >= 0);
281
282         r = pScriptEngine->RegisterObjectBehaviour("Map", asBEHAVE_IMPLICIT_REF_CAST, "EffectBase@ f()", asFUNCTION((refCast<Map,EffectBase>)), asCALL_CDECL_OBJLAST); assert( r >= 0 );
283 }