Here's some code
Sprite::Sprite()
: ISprite(), mVbo(0) {
mDiffuse = ResourceCache::getSingleton().getTexture("Texture_NOTFOUND");
createVbo();
}
Sprite::Sprite(ITexture *diffuse, FloatRect textureBounds)
: ISprite(), mVbo(0) {
mDiffuse = diffuse;
if(textureBounds.x == 0 && textureBounds.y == 0) {
mTextureBounds = diffuse->getBounds();
} else {
mTextureBounds = textureBounds;
}
createVbo();
}
Sprite::~Sprite() {
glDeleteBuffers(1, &mVbo);
}
void Sprite::draw(IRenderTarget *target, RenderState *state) const {
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, mVbo);
switch(state->getRenderMode()) {
default:
case RenderState::DIFFUSE:
mDiffuse->bindTexture();
break;
case RenderState::NORMAL_MAP:
mNormalMap->bindTexture();
break;
case RenderState::HEIGHT_MAP:
mHeightMap->bindTexture();
break;
};
glPushMatrix();
glTranslatef(mPosition.x, mPosition.y, mPosition.z);
glColor4f(mColor.r, mColor.g, mColor.b, mColor.a);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, x));
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, tx));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glPopMatrix();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
void Sprite::createVbo() {
if(mVbo != 0) {
glDeleteBuffers(1, &mVbo);
}
// Generate the VBO
glGenBuffers(1, &mVbo);
Vector2f size = getSize();
float texW = mDiffuse->getWidth();
float texH = mDiffuse->getHeight();
float srcW = size.x / texW;
float srcH = size.y / texH;
// Calculate the vertices
Vertex verts[] = {{0.f, 0.f, 0.f, mTextureBounds.x / texW, mTextureBounds.y / texH},
{size.x, 0.f, 0.f, (mTextureBounds.x / texW) + srcW, mTextureBounds.y / texH},
{0.f, size.y, 0.f, mTextureBounds.x / texW, (mTextureBounds.y / texH ) + srcH},
{size.x, size.y, 0.f, (mTextureBounds.x / texW) + srcW, (mTextureBounds.y / texH) + srcH}};
int vertSize = sizeof(verts);
// Bind the VBO
glBindBuffer(GL_ARRAY_BUFFER, mVbo);
// Submit the vertex data to the GPU
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * 4, &verts[0].x, GL_STATIC_DRAW_ARB);
// Unbind the VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
Repeating Sprite
RepeatingSprite::RepeatingSprite(Texture *diffuseTexture, FloatRect spriteBounds, int xRepeat, int yRepeat)
: ISprite(), mXRepeat(xRepeat), mYRepeat(yRepeat) {
mVbo = 0;
mDiffuse = diffuseTexture;
mTextureBounds = spriteBounds;
createVbo();
}
RepeatingSprite::~RepeatingSprite() {
glDeleteBuffers(1, &mVbo);
}
void RepeatingSprite::draw(IRenderTarget *target, RenderState *state) const {
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, mVbo);
switch(state->getRenderMode()) {
default:
case RenderState::DIFFUSE:
mDiffuse->bindTexture();
break;
case RenderState::NORMAL_MAP:
mNormalMap->bindTexture();
break;
case RenderState::HEIGHT_MAP:
mHeightMap->bindTexture();
break;
};
glPushMatrix();
glTranslatef(mPosition.x, mPosition.y, mPosition.z);
glColor4f(mColor.r, mColor.g, mColor.b, mColor.a);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, x));
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, tx));
glDrawArrays(GL_QUADS, 0, (mXRepeat * mYRepeat) * 4);
glPopMatrix();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
void RepeatingSprite::createVbo() {
int totalRepeats = mXRepeat * mYRepeat;
float textureWidth = mDiffuse->getWidth();
float textureHeight = mDiffuse->getHeight();
Vertex *vertices = new Vertex[totalRepeats*4];
int counter = 0;
// For each sprite count, create a quad
for(float y = 0; y < mYRepeat; y++) {
for(float x = 0; x < mXRepeat; x++) {
Vertex v1 = {x * mTextureBounds.w,
y * mTextureBounds.h, 0.f,
mTextureBounds.x / textureWidth,
mTextureBounds.y / textureHeight};
Vertex v2 = {x * mTextureBounds.w + mTextureBounds.w,
y * mTextureBounds.h, 0.f,
(mTextureBounds.x / textureWidth) + (mTextureBounds.w / textureWidth),
mTextureBounds.y / textureHeight};
Vertex v3 = {x * mTextureBounds.w,
y * mTextureBounds.h + mTextureBounds.h, 0.f,
mTextureBounds.x / textureWidth,
(mTextureBounds.y / textureHeight) + (mTextureBounds.h / textureHeight)};
Vertex v4 = {x * mTextureBounds.w + mTextureBounds.w,
y * mTextureBounds.h + mTextureBounds.h, 0.f,
(mTextureBounds.x / textureWidth) + (mTextureBounds.w / textureWidth),
(mTextureBounds.y / textureHeight) + (mTextureBounds.h / textureHeight)};
vertices[counter] = v1;
counter++;
vertices[counter] = v2;
counter++;
vertices[counter] = v4;
counter++;
vertices[counter] = v3;
counter++;
}
}
glGenBuffers(1, &mVbo);
glBindBuffer(GL_ARRAY_BUFFER, mVbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * (totalRepeats*4), &vertices[0].x, GL_STATIC_DRAW_ARB);
glBindBuffer(GL_ARRAY_BUFFER, 0);
delete[] vertices;
}
Render Texture
RenderTexture::RenderTexture(float width, float height) {
mWidth = width;
mHeight = height;
// Create the color buffer
glGenTextures(1, &mId);
glBindTexture(GL_TEXTURE_2D, mId);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)mWidth, (int)mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
// Create the framebuffer
glGenFramebuffers(1, &mFbo);
glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mId, 0);
GLenum err = glCheckFramebufferStatus(GL_FRAMEBUFFER);
assert(err == GL_FRAMEBUFFER_COMPLETE); // Make sure texture is valid
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
RenderTexture::~RenderTexture() {
glDeleteBuffers(1, &mFbo);
glDeleteTextures(1, &mId);
mFbo = 0;
}
void RenderTexture::preDraw() {
// store the glViewport and glEnable states
glPushAttrib(GL_VIEWPORT_BIT);
// Bind the frame buffer
//glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
// Save the current matrix
glPushMatrix();
glLoadIdentity();
// Setup the projection matrix for the render target
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glViewport(0, 0, (int)mWidth, (int)mHeight);
glOrtho(0, mWidth, 0.f, mHeight, 0.f, 100.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
}
void RenderTexture::postDraw() {
// Pop the render target's projection matrix off the stack
glPopMatrix();
// Restore previouse projection matrix
glPopMatrix();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Restore the previous viewport settings
glPopAttrib();
}
String Sprite
StringSprite::StringSprite(const std::string &string, Font *font)
: mString(string), mFont(font) {
// Calling this forces the string to be rendered
mDiffuse = NULL;
mVbo = 0;
renderText();
}
StringSprite::~StringSprite() {
delete mDiffuse;
}
void StringSprite::setText(const std::string &str) {
mString = str;
renderText();
}
void StringSprite::draw(IRenderTarget *target, RenderState *state) const {
/*std::stringstream vbo;
vbo << mVbo;
Log::getSingleton().writeLine("Drawing StringSprite \"" + mString + "\" with Vbo ID " + vbo.str() + " Size: " + mDiffuse->getBounds().toString());*/
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, mVbo);
mDiffuse->bindTexture();
glPushMatrix();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glTranslatef(mPosition.x, mPosition.y, mPosition.z);
glColor4f(mColor.r, mColor.g, mColor.b, mColor.a);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, x));
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, tx));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisable(GL_BLEND);
glPopMatrix();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
void StringSprite::renderText() {
if(mDiffuse)
delete mDiffuse;
mDiffuse = mFont->renderString(mString);
mTextureBounds = mDiffuse->getBounds();
createVbo();
}
void StringSprite::createVbo() {
if(mVbo != 0) {
glDeleteBuffers(1, &mVbo);
mVbo = 0;
}
// Generate the VBO
glGenBuffers(1, &mVbo);
float texW = (float)mDiffuse->getWidth();
float texH = (float)mDiffuse->getHeight();
float srcW = 1;
float srcH = 1;
// Calculate the verticies
Vertex verts[] = {{0, 0, 0, 0, 0},
{texW, 0, 0, srcW, 0},
{0, texH, 0, 0, srcH},
{texW, texH, 0, srcW, srcH}};
int vertSize = sizeof(verts);
// Bind the VBO
glBindBuffer(GL_ARRAY_BUFFER_ARB, mVbo);
// Submit the vertex data to the GPU
glBufferData(GL_ARRAY_BUFFER_ARB, sizeof(Vertex) * 4, &verts[0].x, GL_STATIC_DRAW_ARB);
// Unbind the VBO
glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
}
Edited by CirdanValen, 15 May 2012 - 04:16 PM.