NEW AND IMPROVED! OLD AND TERRIBLE D:
void drawBillboardedSprite (struct display *d, float x, float y, float z, \ struct spritesheet *sprite, int spriteOffset, unsigned char flipX, unsigned \ char flipY) { float spriteWidth = sprite->sprites[spriteOffset]->w, spriteHeight = sprite->sprites[spriteOffset]->h; float vertOffset = sprite->sprites[spriteOffset]->g, horizOffset = -sprite->sprites[spriteOffset]->f, texX = (float)sprite->sprites[spriteOffset]->x / sprite->raw->Width, texY = (float)sprite->sprites[spriteOffset]->y / sprite->raw->Height, texW = texX + ((float)sprite->sprites[spriteOffset]->w / sprite->raw->Width), texH = texY + ((float)sprite->sprites[spriteOffset]->h / sprite->raw->Height), temp = 0, realX = x, realY = y, realZ = z; float cameraMatrix[16]; if (flipX) { temp = texW; texW = texX; texX = temp; } if (flipY) { temp = texY; texY = texH; texH = temp; } glGetFloatv (GL_MODELVIEW_MATRIX, cameraMatrix); realX = x * cameraMatrix[0] + y * cameraMatrix[4] + (z - d->camera.position.z) * cameraMatrix[8]; realY = x * cameraMatrix[1] + y * cameraMatrix[5] + (z - d->camera.position.z) * cameraMatrix[9]; realZ = x * cameraMatrix[2] + y * cameraMatrix[6] + (z - d->camera.position.z) * cameraMatrix[10]; beginBillboard (); glColor3f (1.0, 1.0, 1.0); glBindTexture (GL_TEXTURE_2D, sprite->sheet->id); glBegin (GL_QUADS); glTexCoord2f (texW, texY); glVertex3f ( realX + horizOffset + spriteWidth, realY + vertOffset, realZ); glTexCoord2f (texX, texY); glVertex3f ( realX + horizOffset, realY + vertOffset, realZ); glTexCoord2f (texX, texH); glVertex3f ( realX + horizOffset, realY + vertOffset - spriteHeight, realZ); glTexCoord2f (texW, texH); glVertex3f ( realX + horizOffset + spriteWidth, realY + vertOffset - spriteHeight, realZ); glEnd (); glBindTexture (GL_TEXTURE_2D, 0); endBillboard (); } // TODO: this shouldn't draw the sprite w/ bottom at given z and centered, it \ should obey the sprite centering guidelines. For X/Y this means changing the \ 0.5 to... something else (possibly requiring four values, with the values \ being .g * width * f/w or w-f/f), and for Z... something more complex, in \ part because a polyBaseRotX/Y is required... I think? void drawBillboardedSprite (struct display *d, float x, float y, float z, \ struct spritesheet *sprite, int spriteOffset, unsigned char flipX, unsigned \ char flipY) { float realWidth = sprite->sprites[spriteOffset]->w, realHeight = sprite->sprites[spriteOffset]->h; float polyWidthX = d->camera.line.g * realWidth * 0.5, polyWidthY = d->camera.line.f * realWidth * 0.5, polyTopRot = sin (M_PI / 180.0 * (d->camera.rotation.x+90)), polyTopX = realHeight * (d->camera.line.f * polyTopRot), polyTopY = realHeight * (d->camera.line.g * polyTopRot), polyTopZ = realHeight * cos (M_PI / 180.0 * (d->camera.rotation.x+90)), texX = (float)sprite->sprites[spriteOffset]->x / sprite->raw->Width, texY = (float)sprite->sprites[spriteOffset]->y / sprite->raw->Height, texW = texX + ((float)sprite->sprites[spriteOffset]->w / sprite->raw->Width), texH = texY + ((float)sprite->sprites[spriteOffset]->h / sprite->raw->Height); float temp = 0; if (flipX) { temp = texW; texW = texX; texX = temp; } if (flipY) { temp = texY; texY = texH; texH = temp; } glColor3f (1.0, 1.0, 1.0); glBindTexture (GL_TEXTURE_2D, sprite->sheet->id); glBegin (GL_QUADS); glTexCoord2f (texW, texY); glVertex3f ( x + polyWidthX + polyTopX, y - polyWidthY + polyTopY, z + polyTopZ - d->camera.position.z); glTexCoord2f (texX, texY); glVertex3f ( x - polyWidthX + polyTopX, y + polyWidthY + polyTopY, z + polyTopZ - d->camera.position.z); glTexCoord2f (texX, texH); glVertex3f ( x - polyWidthX, y + polyWidthY, z - d->camera.position.z); glTexCoord2f (texW, texH); glVertex3f ( x + polyWidthX, y - polyWidthY, z - d->camera.position.z); glEnd (); glBindTexture (GL_TEXTURE_2D, 0); }