Advertisement

gluLookAt

Started by July 12, 2004 05:39 AM
5 comments, last by dawidjoubert 20 years, 4 months ago
I Use gluLookAt for all camera stuff but how can i reverse that as to be able to create a quad that is always front facing. i want for example to use sprites as to animate an explosion but ofcourse it must face the camera, or for example the bullets the plasma gun in q3 shoots
----------------------------

http://djoubert.co.uk
take center of your quad, camera 'up' vector and camera 'right/side' vector

then your quds is

vertex0 = center - x*right - y*up
vertex1 = center - x*right + y*up
vertex2 = center + x*right + y*up
vertex3 = center + x*right - y*up

x,y - "halfsizes" of you quad

remember of quad facing - you my need to reverse vert order


EDIT: today's hardware is able to render 'point sprites' - points with size and texture mapped ot it - you pass only one vertex per quad and hardware do the rest
www.tmreality.com
Advertisement
You can try looking up billboarding. Usually this involves manipulating the current model view matrix. IIRC, Beginning OpenGL Game Programming has a good explanation. But there are plenty of tutorial on the net.
EDIT: today's hardware is able to render 'point sprites' - points with size and texture mapped ot it - you pass only one vertex per quad and hardware do the rest

yes thats what i want - point sprites
----------------------------

http://djoubert.co.uk
Be aware of the clipping problem with point sprites. Because only the centre coordinate of the sprite is considered when clipping against the frustrum your billboarded objects will disappear too early:
     +----- ....|.. .   | . .  x| . .   | . ....|..


In this image the lines represent the boundaries of the frustrum, the dots the boundaries of the sprite and the 'x' the point used to render the sprite. In this case the sprite will not be rendered because the point lies outside of the frustrum, even though some of the fragments from the sprite would be visible if it was rendered.

For some applications (i.e. particle engines) this does not really matter but if you are billboarding larger objects it will be very noticeable when they disappear.

A couple of other ways of billboarding are to rebuild the modelview matrix to eliminate the rotation component or to use the rotation component of the modelview matrix as the axes for your billboarded object:
// messy billboarding example code#include <cstdlib>#include <ctime>#include <GL/glut.h>GLfloat alpha = 0;GLfloat beta = 0;GLfloat gamma = 0;GLfloat dAlpha = 0;GLfloat dBeta = 0;GLfloat dGamma = 0;GLfloat switchTime;GLfloat x = 0;GLfloat y = 0;GLfloat z = 0;GLfloat dx = 0;GLfloat dy = 0;GLfloat dz = 0;GLboolean useBillboardMethod1 = GL_TRUE;class Vector{	public:		Vector(GLfloat* components);		Vector(GLfloat vectorX, GLfloat vectorY, GLfloat vectorZ);		GLfloat dot(const Vector& vector) const;	private:		GLfloat x;		GLfloat y;		GLfloat z;};Vector::Vector(GLfloat* components){	x = components[0];	y = components[1];	z = components[2];}Vector::Vector(GLfloat vectorX, GLfloat vectorY, GLfloat vectorZ){	x = vectorX;	y = vectorY;	z = vectorZ;}GLfloat Vector::dot(const Vector& vector) const{	return (x * vector.x) + (y * vector.y) + (z * vector.z);}void reseedRotations(){	dAlpha = ((std::rand() / 3276.8f) - 5) * 1;	dBeta = ((std::rand() / 3276.8f) - 5) * 5;	dGamma = ((std::rand() / 3276.8f) - 5) * 0.3;	dx = ((std::rand() / 32768.0f) * 0.5) - 0.25;	dy = ((std::rand() / 32768.0f) * 0.5) - 0.25;	dz = ((std::rand() / 32768.0f) * 0.5) - 0.25;	useBillboardMethod1 = std::rand() < 16384;}void reshape(int width, int height){	glViewport(0, 0, width, height);	glMatrixMode(GL_PROJECTION);	glLoadIdentity();	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,50.0f);	glMatrixMode(GL_MODELVIEW);}void billboard1(){	glPushMatrix();	GLfloat matrix[16];	glGetFloatv(GL_MODELVIEW_MATRIX, matrix);	matrix[0] = 1;	matrix[1] = 0;	matrix[2] = 0;	matrix[4] = 0;	matrix[5] = 1;	matrix[6] = 0;	matrix[8] = 0;	matrix[9] = 0;	matrix[10] = 1;	glLoadMatrixf(matrix);	glBegin(GL_TRIANGLE_STRIP);		glColor3f(1, 0, 0);		glVertex3f(-5, -5, 0);		glColor3f(0, 1, 0);		glVertex3f(5, -5, 0);		glColor3f(0, 0, 1);		glVertex3f(-5, 5, 0);		glColor3f(1, 1, 1);		glVertex3f(5, 5, 0);	glEnd();	glPopMatrix();}void billboard2(){	GLfloat matrix[16];	glGetFloatv(GL_MODELVIEW_MATRIX, matrix);	Vector xAxis(matrix);	Vector yAxis(matrix + 4);	Vector zAxis(matrix + 8);	glBegin(GL_TRIANGLE_STRIP);		glColor3f(0.5, 0, 0);		Vector vertex(-5, -5, 0);		glVertex3f(vertex.dot(xAxis), vertex.dot(yAxis), vertex.dot(zAxis));		glColor3f(0, 0.5, 0);		vertex = Vector(5, -5, 0);		glVertex3f(vertex.dot(xAxis), vertex.dot(yAxis), vertex.dot(zAxis));		glColor3f(0, 0, 0.5);		vertex = Vector(-5, 5, 0);		glVertex3f(vertex.dot(xAxis), vertex.dot(yAxis), vertex.dot(zAxis));		glColor3f(0.5, 0.5, 0.5);		vertex = Vector(5, 5, 0);		glVertex3f(vertex.dot(xAxis), vertex.dot(yAxis), vertex.dot(zAxis));	glEnd();}GLfloat clamp(GLfloat v, GLfloat min, GLfloat max){	if (v < min)	{		return min;	}	if (v > max)	{		return max;	}	return v;}void render(){	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	glLoadIdentity();	gluLookAt(x, y, z, 0, 0, 0, alpha, beta, gamma);	glBegin(GL_TRIANGLE_STRIP);		glColor3f(1, 0, 0);		glVertex3f(-5, -5, 0);		glColor3f(0, 1, 0);		glVertex3f(5, -5, 0);		glColor3f(0, 0, 1);		glVertex3f(-5, 5, 0);		glColor3f(1, 1, 1);		glVertex3f(5, 5, 0);	glEnd();	if (useBillboardMethod1)	{		billboard1();	}	else	{		billboard2();	}	glutSwapBuffers();	if (std::clock() - switchTime > 3000)	{		reseedRotations();		switchTime = std::clock();	}	alpha += dAlpha;	beta += dBeta;	gamma += dGamma;	x += dx;	y += dy;	z += dz;	x = clamp(x, -20, 20);	y = clamp(y, -20, 20);	z = clamp(z, -20, 20);}int main(int argc, char** argv){	glutInit(&argc, argv);	glutInitWindowPosition(0, 0);	glutInitWindowSize(800, 600);	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);	glutCreateWindow("Billboard Test");	glutDisplayFunc(render);	glutIdleFunc(render);	glutReshapeFunc(reshape);	glEnable(GL_DEPTH_TEST);	glDepthFunc(GL_LEQUAL);	switchTime = std::clock() - 3000;	glutMainLoop();}


Enigma
There are also bunch of other "isues" with point sprites. Like bunch of bugs with ATI drivers (I hope last verison fixed most), very small max size on nVidia HW, unability to rotate them,..

But there are other ways to speedup billboarding. Things like Enigma gave same code to (but converted to use VA/VBO), or even better, pushing most of calculation in VP if possible.
You should never let your fears become the boundaries of your dreams.
Advertisement
thanks for the frustum explination code:
So what your saying for tiny particles(Point Sprites are only ment for say small ammount of pixels) point sprites if perfect & Fast but i should consider the quad method..

Thanks for the glulookat math stuff

Dawid
----------------------------

http://djoubert.co.uk

This topic is closed to new replies.

Advertisement