Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

P-Worm

macrumors 68020
Original poster
Jul 16, 2002
2,045
1
Salt Lake City, UT
Warning, noobie question ahead

Just this last week, I've decided to pick up C++ and OpenGL. I am now printing out some different colored teapots in 3D space and I can fly around the scene using mouse and keyboard. I am now trying my hand at "billboarding" where you replace the teapots with a picture of a teapot that always has its normal facing the camera. I know that billboarding won't work right for a teapot because it is symmetric, but I just want to try and get this concept working before I attempt to load a .obj file of a tree or something.

In order to get billboarding to work right, I need to do some vector operations to find normals and then do things like dot products, vector products, etc.

I have been hunting around for the last while and found this which looks like what I want. However, I can't get XCode to compile it. Partly, it says that <iostream.h> is not found. I thought this was a standard library?

Anyway, could a kind soul point me to a vector operations library that will work in XCode 3 or tell me how to modify this one?

P-Worm
 
I've used the following with OpenGL/C++ for vectors:

I believe it works correctly, but I also never fully explored it before.

Just create a new header and make it "vector.h" or something and include in your project.

Code:
/*
   Copyright (C) 2000 Nate Miller nkmiller@calpoly.edu

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 2
   of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

   See gpl.txt for more information regarding the GNU General Public License.
*/

#ifndef __VEC3T__
#define __VEC3T__

#include <iostream>
using namespace std;
#include <math.h>

#ifndef __VEC_T__
#define __VEC_T_
typedef float vec_t;
#endif

struct vec3_t
{
   vec3_t() {v[0] = v[1] = v[2] = 0;}
   vec3_t(vec_t px, vec_t py, vec_t pz) {v[0] = px; v[1] = py; v[2] = pz;}
   vec3_t(vec3_t &pVec) {v[0] = pVec.v[0]; v[1] = pVec.v[1]; v[2] = pVec.v[2];}
   vec3_t(vec_t *pVec) {v[0] = pVec[0]; v[1] = pVec[1]; v[2] = pVec[2];}

   vec3_t operator=(vec3_t &pVec)
    {return vec3_t(v[0] = pVec.v[0], v[1] = pVec.v[1], v[2] = pVec.v[2]);}
   vec3_t operator=(vec_t *ptr)
    {return vec3_t(v[0] = ptr[0], v[1] = ptr[1], v[2] = ptr[2]);}
   int operator==(vec3_t &pVec)
    {return (v[0] == pVec.v[0] && v[1] == pVec.v[1] && v[2] == pVec.v[2]);}
   int operator==(float *pVec)
    {return (v[0] == pVec[0] && v[1] == pVec[1] && v[2] == pVec[2]);}
   inline int operator!=(vec3_t &pVec)
    {return !(pVec == (*this));}
   inline int operator!=(float *pVec)
    {return !(pVec == (*this));}

   vec3_t operator+=(vec3_t &pVec);  
   vec3_t operator-=(vec3_t &pVec);
   vec3_t operator*=(vec3_t &pVec);
   vec3_t operator*=(vec_t val);  
   vec3_t operator/=(vec3_t &pVec);
   vec3_t operator/=(vec_t val);

   vec3_t operator+(vec3_t &pVec)
    {return vec3_t(v[0] + pVec.v[0], v[1] + pVec.v[1], v[2] + pVec.v[2]);}
   vec3_t operator-(vec3_t &pVec)
    {return vec3_t(v[0] - pVec.v[0], v[1] - pVec.v[1], v[2] - pVec.v[2]);}
   vec3_t operator*(vec3_t &pVec)
    {return vec3_t(v[0] * pVec.v[0], v[1] * pVec.v[1], v[2] * pVec.v[2]);}
   vec3_t operator*(vec_t val)
    {return vec3_t(v[0] * val, v[1] * val, v[2] * val);}
   vec3_t operator/(vec3_t &pVec)  
    {return vec3_t(v[0] / pVec.v[0], v[1] / pVec.v[1], v[2] / pVec.v[2]);}
   vec3_t operator/(vec_t val)
    {return vec3_t(v[0] / val, v[1] / val, v[2] / val);}

   void Clear(void) {v[0] = v[1] = v[2] = 0;}
   void Normalize(void);
   vec_t Length(void);
   vec_t Dot(vec3_t &pVec) {return v[0] * pVec.v[0] + v[1] * pVec.v[1] + v[2] * pVec.v[2];}
   void Cross(vec3_t &p, vec3_t &q);

   void Set(float x, float y, float z) {v[0] = x; v[1] = y; v[2] = z;}
   
   vec_t X(void) {return v[0];}
   vec_t Y(void) {return v[1];}
   vec_t Z(void) {return v[2];}
   void X(vec_t nx) {v[0] = nx;}
   void Y(vec_t ny) {v[1] = ny;}
   void Z(vec_t nz) {v[2] = nz;}

   const vec_t &operator[](int ndx) const {return v[ndx];}
   vec_t &operator[](int ndx) {return v[ndx];}
   operator vec_t*(void) {return v;}

   void Clamp(int min, int max);

   void RotateX(float amnt);
   void RotateY(float amnt);
   void RotateZ(float amnt);

   friend ostream &operator<<(ostream &os, vec3_t &vec)
    {os << vec.v[0] << " " << vec.v[1] << " " << vec.v[2]; return os;}
   
protected:
   vec_t v[3];
};

inline vec3_t vec3_t::operator+=(vec3_t &pVec)
{
   vec3_t ret;

   ret = *this = *this + pVec;

   return ret;
}

inline vec3_t vec3_t::operator-=(vec3_t &pVec)
{
   vec3_t ret;

   ret = *this = *this - pVec;

   return ret;
}

inline vec3_t vec3_t::operator*=(vec3_t &pVec)
{
   vec3_t ret;

   ret = *this = *this * pVec;

   return ret;
}

inline vec3_t vec3_t::operator*=(vec_t val)
{
   vec3_t ret;

   ret = *this = *this * val;

   return ret;
}

inline vec3_t vec3_t::operator/=(vec3_t &pVec)
{
   vec3_t ret;

   ret = *this = *this / pVec;

   return ret;
}

inline vec3_t vec3_t::operator/=(vec_t val)
{
   vec3_t ret;

   ret = *this = *this / val;

   return ret;
}

inline void vec3_t::Normalize(void) 
{
	vec_t length, len = 0;

	length = Length();

	if (length == 0)
		return;

	len = 1.0f / length;

	v[0] *= len;
	v[1] *= len;
	v[2] *= len;
}

inline float vec3_t::Length(void) 
{
   double length = 0;
	
   length = (v[0] * v[0]) + (v[1] * v[1]) + (v[2] * v[2]);
	
	return (vec_t) sqrt(length);
}

inline void vec3_t::Cross(vec3_t &p, vec3_t &q)
{
	v[0] = p.v[1] * q.v[2] - p.v[2] * q.v[1];
	v[1] = p.v[2] * q.v[0] - p.v[0] * q.v[2];
	v[2] = p.v[0] * q.v[1] - p.v[1] * q.v[0];
}

inline void vec3_t::Clamp(int min, int max)
{
   if (v[0] > max || v[0] < min)
      v[0] = 0;

   if (v[1] > max || v[1] < min)
      v[1] = 0;

   if (v[2] > max || v[2] < min)
      v[2] = 0;   
}

inline void vec3_t::RotateX(float amnt)
{
  float s = sin(amnt);
  float c = cos(amnt);
  float y = v[1];
  float z = v[2];
  
  v[1] = (y * c) - (z * s);
  v[2] = (y * s) + (z * c);
}

inline void vec3_t::RotateY(float amnt)
{
  float s = sin(amnt);
  float c = cos(amnt);
  float x = v[0];
  float z = v[2];
  
  v[0] = (x * c) + (z * s);
  v[2] = (z * c) - (x * s);
}

inline void vec3_t::RotateZ(float amnt)
{
  float s = sin(amnt);
  float c = cos(amnt);
  float x = v[0];
  float y = v[1];
  
  v[0] = (x * c) - (y * s);
  v[1] = (y * c) + (x * s);
}
#endif
 
Thanks for the response guys, I've got it working now. There's so much stuff to wrap my head around. :eek:

P-Worm

Some unsolicited advice from someone with experience with OpenGL for someone first learning the API:

Be really careful of using google to find tutorials and information about OpenGL. It's a really old API and a lot of its functions are deprecated. Most tutorials out there will teach you things that are already obsolete (immediate mode, the matrix stack, fixed functionality lighting, etc).

The most modern way to do billboards is with the geometry shader. If the tutorial you're following uses the OpenGL matrix stack (GL_MODELVIEW_MATRIX, etc) then it's teaching you deprecated techniques that are going away, and are not present in the embedded version of OpenGL. So be careful, and make an effort to make sure all of your information is up to date and follows best practices.
 
Some unsolicited advice from someone with experience with OpenGL for someone first learning the API:

Be really careful of using google to find tutorials and information about OpenGL. It's a really old API and a lot of its functions are deprecated. Most tutorials out there will teach you things that are already obsolete (immediate mode, the matrix stack, fixed functionality lighting, etc).

The best place to look for tutorials and documentation is probably these two.

http://www.khronos.org/opengl/
http://developer.apple.com/graphicsimaging/opengl/
 
Some unsolicited advice from someone with experience with OpenGL for someone first learning the API:

Be really careful of using google to find tutorials and information about OpenGL. It's a really old API and a lot of its functions are deprecated. Most tutorials out there will teach you things that are already obsolete (immediate mode, the matrix stack, fixed functionality lighting, etc).

The most modern way to do billboards is with the geometry shader. If the tutorial you're following uses the OpenGL matrix stack (GL_MODELVIEW_MATRIX, etc) then it's teaching you deprecated techniques that are going away, and are not present in the embedded version of OpenGL. So be careful, and make an effort to make sure all of your information is up to date and follows best practices.

Gah isn't this the truth.

I started learning OpenGL on my own using the latest version of the OpenGL SuperBible and things were going great until I had to start my multimedia programming class (which for whatever reason teaches OpenGL and DirectX at the same time).

Unfortunately for the class we use an old (SUPER old) version of OpenGL (1.3) and its quite conflicting with what I learn in the OpenGL SuperBible. I believe it was OpenGL 3 that got rid of a lot of the older stuff.
 
Gah isn't this the truth.

I started learning OpenGL on my own using the latest version of the OpenGL SuperBible and things were going great until I had to start my multimedia programming class (which for whatever reason teaches OpenGL and DirectX at the same time).

Unfortunately for the class we use an old (SUPER old) version of OpenGL (1.3) and its quite conflicting with what I learn in the OpenGL SuperBible. I believe it was OpenGL 3 that got rid of a lot of the older stuff.

OpenGL 3 hasn't gotten rid of the older stuff (to the dismay of a lot of people), but has made it deprecated. OpenGL ES 2.0 (on the iPhone for example) has actually gone as far as to get rid of functionality that would otherwise be considered deprecated. If you want your project to be forward compatible, you need to avoid using deprecated functions.

In particular:

Stop using geometry other than triangles, points, and lines. Stop using immediate mode rendering (glBegin / glEnd). Stop using the fixed functionality pipeline and use shaders instead. Don't use functions associated with the fixed functionality pipeline either (such as glLight). Stop using pre-defined vertex attributes (glVertex, glNormal, glColor, etc). Don't use client side vertex attributes (use vertex arrays and vertex buffer objects instead). Stop using display lists. Stop using the OpenGL matrix stack (glOrtho, glFrustum, glLoadIdentity, glRotate, glTranslate, etc) and use your own matrix stack instead.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.