/*
* Sprite.cpp
* iphone-gl-app
*
* Created by John Ryland on 8/06/09.
* Copyright 2009 InvertedLogic. All rights reserved.
*
*/
#include "Debug.h"
#include <math.h>
#include <OpenGLES/ES1/gl.h>
#include <OpenGLES/ES1/glext.h>
#include "Sprite.h"
#include "PointArray.h"
class SpritePrivate
{
public:
PointArray initVerts;
PointArray vertices;
float alpha;
int frame, frameCount;
Texture *frames;
int x, y, x1, y1, w, h, xAdv, yAdv;
};
Sprite::Sprite(const float verts[4], Texture *tex, int _x, int _y, int _w, int _h, int _xAdv, int _yAdv, int _frames)
{
SpritePrivate *d = new SpritePrivate;
dptr = (void *)d;
d->alpha = 1.0f;
d->frame = 0;
d->frames = tex;
d->initVerts += PointF(verts[0], verts[1]);
d->initVerts += PointF(verts[2], verts[1]);
d->initVerts += PointF(verts[0], verts[3]);
d->initVerts += PointF(verts[2], verts[3]);
reset();
d->x1 = d->x = _x;
d->y1 = d->y = _y;
d->w = _w;
d->h = _h;
d->xAdv = _xAdv;
d->yAdv = _yAdv;
d->frameCount = _frames;
if ( _frames != -1 )
setTextureRect(_x, _y, _w, _h);
}
Sprite::~Sprite()
{
delete (SpritePrivate *)dptr;
}
void Sprite::reset()
{
SpritePrivate *d = (SpritePrivate *)dptr;
d->vertices = d->initVerts;
}
void Sprite::translate(float x, float y)
{
((SpritePrivate *)dptr)->vertices.translate(x, y);
}
void Sprite::rotate(float r)
{
((SpritePrivate *)dptr)->vertices.rotate(r);
/*
SpritePrivate *d = (SpritePrivate *)dptr;
float s = ::sin(r);
float c = ::cos(r);
for (int i = 0; i < 4; i++) {
float x = d->vertices[i].x;
float y = d->vertices[i].y;
d->vertices[i].x = (x * c) - (y * s);
d->vertices[i].y = (x * s) + (y * c);
}
*/
/*
for (int i = 0; i < 4; i++)
d->vertices[i].rotate(r);
*/
}
void Sprite::scale(float s)
{
((SpritePrivate *)dptr)->vertices.scale(s, s);
/*
SpritePrivate *d = (SpritePrivate *)dptr;
for (int i = 0; i < 4; i++)
d->vertices[i].scale(s);
*/
}
void Sprite::scale(float x, float y)
{
((SpritePrivate *)dptr)->vertices.scale(x, y);
}
void Sprite::advance(int f)
{
SpritePrivate *d = (SpritePrivate *)dptr;
setFrame(d->frame + f);
draw();
}
void Sprite::setFrame(int f)
{
SpritePrivate *d = (SpritePrivate *)dptr;
d->frame = f;
if ( d->frameCount != -1 ) {
d->x = d->x1 + (d->frame % d->frameCount) * d->xAdv;
d->y = d->y1 + (d->frame % d->frameCount) * d->yAdv;
}
}
void Sprite::setAlpha(float a)
{
SpritePrivate *d = (SpritePrivate *)dptr;
d->alpha = a;
}
void Sprite::setTextureRect(int x, int y, int w, int h)
{
SpritePrivate *d = (SpritePrivate *)dptr;
if (d->frames)
d->frames->setExtents(x, y, w, h);
}
void Sprite::draw()
{
SpritePrivate *d = (SpritePrivate *)dptr;
if (d->frames)
d->frames->bind();
setTextureRect(d->x, d->y, d->w, d->h);
float alpha = d->alpha;
if ( alpha != 1.0f ) {
glColor4f(alpha, alpha, alpha, alpha);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); // GL_ADD);
// GLfloat blendColor[4] = {0.0, 0.0, 0.0, 0.0};//alpha};
// glColor4f(1.0, 1.0, 1.0, 0.5);//alpha);
// glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, blendColor);
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ALPHA);
// glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
// glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
// glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
// glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
// glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_ALPHA);
// glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0);
// glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT);
} else {
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glColor4f(alpha, alpha, alpha, alpha);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); // GL_ADD);
}
glVertexPointer(2, GL_FLOAT, 0, (float *)(const PointF *)d->vertices);
glEnableClientState(GL_VERTEX_ARRAY);
// glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glBlendFunc(GL_ONE, GL_ALPHA);
glEnable(GL_BLEND);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}