I got this code for billboarding I created (With the help of others, and a nehe tutorial), but it seems that when I move my sprites from 0,0,0 it stops working correctly, for example the closer I get to a sprite that’s at 50,0,50 the more sideways it gets.
Any idea how to make the sprites billboard properly when not on 0,0,0?
Here is the code:
public void drawBillBoardSprite(Texture texture, Vector3f sprPos, float r, float g, float b, int sprWidth, int sprHeight){
// store the current model matrix
GL11.glPushMatrix();
// bind to the appropriate texture for this sprite
texture.bind();
Vector3f look = new Vector3f(0,0,0);
Vector3f.sub(player.pos, sprPos, look);
look.normalise();
Vector3f right = new Vector3f(0,0,0);
Vector3f.cross(new Vector3f(0,1,0) /* <-- default up vector */, look, right);
right.normalise();
Vector3f up = new Vector3f(0,0,0);
Vector3f.cross(look, right, up);
up.normalise();
Matrix4f m = new Matrix4f();
m.m00 = right.x;
m.m01 = right.y;
m.m02 = right.z;
m.m03 = 0;
m.m10 = up.x;
m.m11 = up.y;
m.m12 = up.z;
m.m13 = 0;
m.m20 = look.x;
m.m21 = look.y;
m.m22 = look.z;
m.m23 = 0;
m.m30 = sprPos.x;
m.m31 = sprPos.y;
m.m32 = sprPos.z;
m.m33 = 1;
java.nio.FloatBuffer fb = BufferUtils.createFloatBuffer(32);
m.store(fb);
fb.flip();
GL11.glMultMatrix(fb);
// draw a quad textured to match the sprite
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0,0); GL11.glVertex3f( - (sprWidth/2), (sprHeight/2), 0); // Top left Of The Quad (Left)
GL11.glTexCoord2f(texture.getWidth(), 0); GL11.glVertex3f( + (sprWidth/2), (sprHeight/2), 0); // Top right Of The Quad (Left)
GL11.glTexCoord2f(texture.getWidth(), texture.getHeight()); GL11.glVertex3f( + (sprWidth/2), -(sprHeight/2), 0); // Bottom right Of The Quad (Left)
GL11.glTexCoord2f(0, texture.getHeight()); GL11.glVertex3f( - (sprWidth/2), -(sprHeight/2), 0); // Bottom left Of The Quad (Left)
GL11.glEnd();
// restore the model view matrix to prevent contamination
GL11.glPopMatrix();
}
Edit: tried this code based on Knetic’s answer, but it didn’t even rotate the sprites towards the camera. Here is the code I used:
public void drawBillBoardSprite(Texture texture, Vector3f sprPos, float r, float g, float b, int sprWidth, int sprHeight){
// store the current model matrix
GL11.glPushMatrix();
FloatBuffer tempViewBuf = BufferUtils.createFloatBuffer(16);
GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, tempViewBuf);
float[] tempView = new float[16];
for(int i = 0; i < 16; i++){
tempView[i] = tempViewBuf.get(i);
}
float[] modelView = new float[6];
modelView[0] = tempView[0] - tempView[1];
modelView[1] = tempView[0] + tempView[1];
modelView[2] = tempView[4] - tempView[5];
modelView[3] = tempView[4] + tempView[5];
modelView[4] = tempView[8] - tempView[9];
modelView[5] = tempView[8] + tempView[9];
// bind to the appropriate texture for this sprite
texture.bind();
// draw a quad textured to match the sprite
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0,0); GL11.glVertex3f( - (sprWidth/2) + modelView[1], (sprHeight/2) + modelView[3], 0 + modelView[5]); // Top left Of The Quad (Left)
GL11.glTexCoord2f(texture.getWidth(), 0); GL11.glVertex3f( + (sprWidth/2) + modelView[0], (sprHeight/2) + modelView[2], 0 + modelView[4]); // Top right Of The Quad (Left)
GL11.glTexCoord2f(texture.getWidth(), texture.getHeight()); GL11.glVertex3f( + (sprWidth/2) + modelView[1], -(sprHeight/2)+ modelView[3], 0 + modelView[5]); // Bottom right Of The Quad (Left)
GL11.glTexCoord2f(0, texture.getHeight()); GL11.glVertex3f( - (sprWidth/2) + modelView[0], -(sprHeight/2)+ modelView[2], 0 + modelView[4]); // Bottom left Of The Quad (Left)
GL11.glEnd();
// restore the model view matrix to prevent contamination
GL11.glPopMatrix();
}
Just had to use a different way of billboarding: