My favorites | Sign in
Project Logo
                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
/*
* TextureController.cpp
* DjinnEngine
*
* Created by Craig Giles on 7/5/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/

#include "TextureController.h"

#pragma mark
#pragma mark Constructor(s) / Destructor
#pragma mark ---------

TextureController* TextureController::instance = 0;

TextureController* TextureController::getInstance()
{
if (instance == 0)
instance = new TextureController();

return instance;
}

TextureController::TextureController()
{
beginCalled = false;
}

TextureController::~TextureController()
{
//clean up particle vert (now a map)delete [] particleVert;
vertices.clear();
}

#pragma mark
#pragma mark Texture Management
#pragma mark ---------

Texture2D* TextureController::getTexture( const std::string &asset )
{
// Look inside the texture map for the texture.. if it already
// exists, return it. If it can't find it, we'll have to create it.
textureMap::const_iterator it = textures.find( asset );
if (it != textures.end())
return it->second;

// create the texture, add it to the texture map, and return
// its reference.
Texture2D* newTexture = new Texture2D(asset);
textures[asset] = newTexture;
return newTexture;
}

bool TextureController::releaseTexture( const std::string &asset )
{
bool found = false;
textureMap::iterator it = textures.find(asset);

// if there are any vertices in the VertexMap currently using
// the deleted texture, we should remove them from the vertex map.
// NOTE:: this has not been tested
#warning test this
VertexMap::iterator vertIterator = vertices.begin();
for (/* */; vertIterator != vertices.end(); it++)
{
if(vertIterator->first == it->second->getId())
break;
}

if (vertIterator != vertices.end())
vertices.erase( vertIterator );

// if the texture was found, and is not NULL, delete it and
// erase it from the texture map.
if (it != textures.end())
{
found = true;
if (it->second)
delete it->second;
textures.erase(it);
}

return found;
}

void TextureController::flushTextures()
{
textureMap::iterator it = textures.begin();
for ( /*no init*/; it != textures.end(); it++)
{
if (it->second)
delete it->second;
textures.erase(it);
}

vertices.clear();
}

// Bind the given texture to OpenGL
void TextureController::bindTexture( const GLuint name )
{
if (name != getBoundTexture() )
{
currentTexture = name;
glBindTexture(GL_TEXTURE_2D, name);
}
}

#pragma mark
#pragma mark Begin / End functions (Un-Implemented)
#pragma mark ---------

void TextureController::begin( const bool blendAdditive )
{
this->blendAdditive = blendAdditive;
beginCalled = true;
}

void TextureController::end()
{
if (!beginCalled)
throw TextureControllerException("Begin must be called before end");

renderToScreen();
clearRenderState();
}

void TextureController::clearRenderState()
{
vertices.clear();
beginCalled = false;
}

void TextureController::renderToScreen()
{
glPushMatrix();
glMatrixMode(GL_MODELVIEW);

// Texture Blending fuctions
if ( blendAdditive )
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

// needed to draw textures using Texture2D
glEnable(GL_TEXTURE_2D);

// enables alpha for transparent textures
// I forget where I got these commands, iDevGames.net I think
glAlphaFunc(GL_GREATER, 0.1f);
glEnable(GL_ALPHA_TEST);

// Enable the various arrays used to draw texture to screen
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

glLoadIdentity();

// loop through all of the elements of the map and draw the vertices
VertexMap::iterator it = vertices.begin();
for (/* none */; it != vertices.end(); it++)
{
// easy access to our data
VertexInfo *vertexInfo = &it->second;
Vertex *vert = vertexInfo->vertex;

// bind the texture for the following vertices
bindTexture( (*it).first );

// throw everything to OpenGL
glVertexPointer(2, GL_SHORT, sizeof(Vertex), &vert->v);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &vert->uv);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &vert->color);
glDrawArrays(GL_TRIANGLES, 0, vertexInfo->_vertexCount);

// reset this batches vertex count
vertexInfo->_vertexCount = 0;
}

// disable all the stuff we enabled eariler
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisable( GL_BLEND );
glDisable( GL_TEXTURE_2D );
glDisable( GL_ALPHA_TEST );

glPopMatrix();
}

#pragma mark
#pragma mark Draw functions
#pragma mark ---------

void TextureController::draw( const Texture2D& texture, const Rectangle& destination )
{
draw( texture, destination, Rectangle::ZERO(), Color(1, 0, 0, 1), 1.0f);
}

void TextureController::draw( const Texture2D& texture, const Rectangle& destination,
const Color& color )
{
draw( texture, destination, Rectangle::ZERO(), color, 1.0f);
}
void TextureController::draw( const Texture2D& texture, const Rectangle& destination,
const Rectangle& source, const Color& color )
{
draw( texture, destination, source, color, 1.0f);
}
void TextureController::draw( const Texture2D& texture, const Rectangle& destination,
const Rectangle& source, const Color& color, const GLfloat depth )
{
//
// TODO:: need to implement depth somehow
//

GLuint glid = texture.getId();

// if we don't have any vertices with the texture being drawn, create a
// vertex map for it.
VertexMap::iterator it = vertices.find(glid);
if (it == vertices.end())
vertices[glid]._vertexCount = 0;

// find all of the vertices we'll need for this sprite
float topLeftX = destination.x;
float topLeftY = destination.y;
float topRightX = destination.x + destination.width;
float topRightY = destination.y;
float bottomLeftX = destination.x;
float bottomLeftY = destination.y + destination.height;
float bottomRightX = destination.x + destination.width;
float bottomRightY = destination.y + destination.height;

// Texture atlas
float minUV[2];
float maxUV[2];

// if the source rectangle of ZERO was passed in, it means the client want to just
// draw the texture as is.. otherwise, the client wishes to draw a portion of
// the rectangle
if (source == Rectangle::ZERO())
{
float maxS = texture.getMaxS();
float maxT = texture.getMaxT();
float minS = 0;
float minT = 0;

minUV[0] = minS;
minUV[1] = minT;
maxUV[0] = maxS;
maxUV[1] = maxT;
}
else
{
float minS = source.x / texture.getWidth();
float minT = source.y / texture.getHeight();
float maxS = source.width / texture.getWidth();
float maxT = source.height / texture.getHeight();

minUV[0] = minS;
minUV[1] = minT;
maxUV[0] = maxS;
maxUV[1] = maxT;
}

// Convert the colors into bytes
unsigned char red = color.red * 255.0f;
unsigned char green = color.green * 255.0f;
unsigned char blue = color.blue * 255.0f;
unsigned char shortAlpha = color.alpha * 255.0f;

// pack all of the color data bytes into an unsigned int
unsigned _color = (shortAlpha << 24) | (blue << 16) | (green << 8) | (red << 0);

// Triangle #1
addVertex(glid, topLeftX, topLeftY, minUV[0], minUV[1], _color);
addVertex(glid, topRightX, topRightY, maxUV[0], minUV[1], _color);
addVertex(glid, bottomLeftX, bottomLeftY, minUV[0], maxUV[1], _color);

// Triangle #2
addVertex(glid, topRightX, topRightY, maxUV[0], minUV[1], _color);
addVertex(glid, bottomLeftX, bottomLeftY, minUV[0], maxUV[1], _color);
addVertex(glid, bottomRightX, bottomRightY, maxUV[0], maxUV[1], _color);
}

void TextureController::addVertex(GLuint glid, float x, float y, float uvx, float uvy, unsigned color)
{
VertexInfo *vertexInfo = &vertices[glid];
Vertex *vert = &vertexInfo->vertex[vertexInfo->_vertexCount];
vert->v[0] = x;
vert->v[1] = y;
vert->uv[0] = uvx;
vert->uv[1] = uvy;
vert->color = color;
vertexInfo->_vertexCount++;
}

#pragma mark
#pragma mark DrawString functions (Un-Implemented)
#pragma mark ---------
//
//void TextureController::drawString( const std::string& text, const std::string& font,
// const Vector2& location, const Color& color,
// const GLfloat scale )
//{
// // bind the font bitmap
// // loop through the string for however long the string is
// // render the character to screen. Since the texture will be the same for
// // the entire screen, we only need to bind it once and jump around to
// // the position from the bitmap of the font.
// //
// // My guess is, the best way to do this is to have a map with the
// // unicode of the character to be drawn, and the vector2 offset where
// // it can be found on the bitmap.
//}
//









Show details Hide details

Change log

r23 by CraigGiles9 on Aug 02, 2009   Diff
Deleted all draw functions from the
Texture2D class. it is now more of a
"model" class like it should be. Changed
the TextureController to handle batch
rendering of all textures for sprites.
(excluding particle system for now)
Go to: 
Project members, sign in to write a code review

Older revisions

r11 by CraigGiles9 on Jul 11, 2009   Diff
Implemented the Texture2D reference
counting system and adjusted the
#pragma mark items on several classes.
r6 by CraigGiles9 on Jul 06, 2009   Diff
Added TextureController and removed
Apples Texture2D, replacing it with a
custom C++ class. Also had some other
minor construction changes..

...
All revisions of this file

File info

Size: 8789 bytes, 331 lines

File properties

svn:eol-style
native
Hosted by Google Code