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);
}
|