picking problem

Started by
1 comment, last by mageziyx 21 years, 7 months ago
hi there, i have been experimenting with picking but can't seem to get it to work on my computer with a 3D Prophet 4500 card. The program seems to work other machines though(Tnt2, Voodoo3) Anyone can check if it works on your system???
    
#include "sphere.h" 
#include <glut.h>
#include <iostream>
#include <cassert>

using namespace std;

Sphere	sphere0;
Sphere	sphere1;
Sphere	sphere2;
GLuint select_buffer[100];
GLfloat angle = 0;

const GLuint RED_SPHERE   = 10;
const GLuint GREEN_SPHERE = 20;
const GLuint BLUE_SPHERE  = 30;

void lights() 
{
	// lights

	GLfloat position[] = { 500.0f, 0.0f, 500.0f, 1.0f };
	GLfloat ambient[]  = { 0.6f, 0.6f, 0.6f, 1.0f };
	GLfloat diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat emission[] = { 0.0f, 0.0f, 0.0f, 1.0f };

	glLightfv(GL_LIGHT0, GL_POSITION,	position);
	glLightfv(GL_LIGHT0, GL_AMBIENT,	ambient);
	glLightfv(GL_LIGHT0, GL_DIFFUSE,	diffuse);
	glLightfv(GL_LIGHT0, GL_SPECULAR,	specular);
	glLightfv(GL_LIGHT0, GL_EMISSION,	emission);
}

void displayfunc()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(200.0f, 200.0f,   0.0f, 
			    0.0f,   0.0f,   0.0f, 
				0.0f,   0.0f,   1.0f);

	lights();

	glRotatef(angle, 0.0f, 0.0f, 1.0f);
	
	sphere0.draw();
	sphere1.draw();
	sphere2.draw();

	angle += 0.5f;
	if(angle > 360.0f) {
		angle -= 360.0f;
	}
	glutSwapBuffers();
}

void reshapefunc(int width, int height)
{
	GLfloat aspect = (GLfloat) width / (GLfloat) height;
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0f, aspect, 0.1f, 1000.0f);
	glViewport(0, 0, width, height);
}

void idlefunc()
{
	glutPostRedisplay();
}

void pick(int x, int y)
{
	GLint viewport[4];
	glGetIntegerv(GL_VIEWPORT, viewport);

	GLfloat width  = viewport[2];
	GLfloat height = viewport[3];
	GLfloat aspect = width / height;

	// opengl windows coordinates is

	// x to the right & y upwards

	// but glut gives mouse coordinates with

	// x to the right & y downwards

	// also, glut give mouse coordinates with respect to 

	// client area but opengl is with respect to viewport

	// do the following conversion :

	GLuint gl_x = x - viewport[0];
	GLuint gl_y = viewport[1] + viewport[3] - y - 1;

	cout << "***************************************" << endl;
	cout << "               PICK                    " << endl;
	cout << "***************************************" << endl;
	cout << "Pick Matrix : gl_x = " << gl_x << " gl_y = " << gl_y << endl;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();	
	gluPickMatrix(gl_x, gl_y,	// coordinates

				  1, 1,			// size 

				  viewport);
	gluPerspective(45.0f, aspect, 0.1f, 1000.0f);

	// drawing for selection

	glRenderMode(GL_SELECT); // note that glSelectBuffer MUST be called before glRenderMode(GL_SELECT)

	glInitNames(); // gl*Names functions are ignored unless in GL_SELECT render mode

	glPushName(0);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(200.0f, 200.0f,   0.0f, 
				0.0f,   0.0f,   0.0f, 
				0.0f,   0.0f,   1.0f);
	glRotatef(angle, 0.0f, 0.0f, 1.0f);
	glLoadName(RED_SPHERE);
	sphere0.draw();
	glLoadName(GREEN_SPHERE);
	sphere1.draw();	
	glLoadName(BLUE_SPHERE);
	sphere2.draw();	
	glFlush();
	// end drawing for selection


	GLuint hits = glRenderMode(GL_RENDER);

	cout << "number of hits = " << hits << endl;
	
	// structure for a single hit record (all integers)

	//

	// 1. number of names on name stack when hit occured

	// 2. minimum depth of all hit primitives

	// 3. maximum depth of all hit primitives 

	// 4. entries in name stack

	//


	GLuint *p = select_buffer;
	GLuint nearest_obj = 0;
	GLuint most_min_depth = 0;

	cout << "iterate through all hit records" << endl;

	// loop thru' all hit records

	for(GLuint i=0; i<hits; i++) {

		cout << "HIT RECORD " << i << " :" << endl;

		GLuint name_count = *p;

		cout << "hit " << i << endl;
		cout << "number of names on name stack = " << name_count << endl;
		
		GLuint min_depth = *(++p);
		GLuint max_depth = *(++p);

		cout << "min depth = " << min_depth << endl;
		cout << "max depth = " << max_depth << endl;
		for(GLuint j=0; j<name_count; j++) {
			cout << "name " << j << " = " << *(++p) << endl;
		}

		// if this is the first hit to be examined...

		// or this object has the minimum depth

		// then set nearest obj so far to this obj

		if(most_min_depth == 0 || min_depth < most_min_depth) {
			most_min_depth = min_depth;
			nearest_obj = *p;
			cout << "nearest_obj = " << *p << endl;
		}
		p++;
	}

	sphere0.hide_bbox();
	sphere1.hide_bbox();
	sphere2.hide_bbox();

	if(nearest_obj == RED_SPHERE) {
		sphere0.show_bbox();
		cout << "red sphere picked" << endl;
	}
	else if(nearest_obj == GREEN_SPHERE) {
		sphere1.show_bbox();
		cout << "green sphere picked" << endl;
	}
	else if(nearest_obj == BLUE_SPHERE) {
		sphere2.show_bbox();
		cout << "blue sphere picked" << endl;
	}

	// reset the projection matrix

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();		
	gluPerspective(45.0f, aspect, 0.1f, 1000.0f);

	// redraw

	glutPostRedisplay();
}

void mousefunc(int button, int state, int x, int y)
{
	if(state == GLUT_DOWN) {
		pick(x, y);
	}
}

void init()
{
	// gl settings

	glEnable(GL_DEPTH_TEST);
	glShadeModel(GL_SMOOTH);
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);				
	glClearDepth(1.0f);												
	glDepthFunc(GL_LEQUAL);							
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

	// selection

	glSelectBuffer(100, select_buffer);

	// light

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);

	// sphere 0 - RED

	sphere0.toggle_bbox();
	sphere0.material.set_ambient(0.2f, 0.2f, 0.2f, 1.0f);
	sphere0.material.set_diffuse(0.5f, 0.0f, 0.0f, 1.0f);
	sphere0.material.set_specular(0.6f, 0.6f, 0.6f, 1.0f);
	sphere0.material.set_emission(0.0f, 0.0f, 0.0f, 1.0f);
	sphere0.material.set_shininess(40); // 0.0f to 128.0f

	sphere0.set_position(100, 0, 0);
	sphere0.set_radius(20);
	sphere0.set_slices(40);
	sphere0.set_stacks(40);

	// sphere 1 - GREEN

	sphere1.material.set_ambient(0.2f, 0.2f, 0.2f, 1.0f);
	sphere1.material.set_diffuse(0.0f, 0.5f, 0.0f, 1.0f);
	sphere1.material.set_specular(0.6f, 0.6f, 0.6f, 1.0f);
	sphere1.material.set_emission(0.0f, 0.0f, 0.0f, 1.0f);
	sphere1.material.set_shininess(40);
	sphere1.set_position(0, 0, 0);
	sphere1.set_radius(20);
	sphere1.set_slices(40);
	sphere1.set_stacks(40);

	// sphere 2 - BLUE

	sphere2.material.set_ambient(0.2f, 0.2f, 0.2f, 1.0f);
	sphere2.material.set_diffuse(0.0f, 0.0f, 0.5f, 1.0f);
	sphere2.material.set_specular(1.0f, 1.0f, 1.0f, 1.0f);
	sphere2.material.set_emission(0.0f, 0.0f, 0.0f, 1.0f);
	sphere2.material.set_shininess(40);	
	sphere2.set_position(-100, 0, 0);
	sphere2.set_radius(20);
	sphere2.set_slices(40);
	sphere2.set_stacks(40);
}

int main(int argc, char *argv[])
{
	glutInitWindowSize(320, 240);
	glutInitWindowPosition(100, 100);
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH |GLUT_DOUBLE);
	glutCreateWindow("picking - click sphere to select");
	glutDisplayFunc(displayfunc);
	glutReshapeFunc(reshapefunc);
	glutIdleFunc(idlefunc);
	glutMouseFunc(mousefunc);

	init();

	glutMainLoop();
	return 0;
}
  

      
#ifndef SPHERE_H
#define SPHERE_H

#include "material.h"
#include "win32_gl.h"
#include <gl\gl.h>
#include <gl\glu.h>

class Sphere {
public:
	Material material;

	Sphere();
	~Sphere();
	void set_position(float x, float y, float z);
	void set_color(float r, float g, float b);
	void set_radius(float radius);
	void set_slices(GLuint slices);
	void set_stacks(GLuint stacks);
	void toggle_bbox();
	void show_bbox();
	void hide_bbox();
	void draw();
private:	
	GLfloat x;
	GLfloat y;
	GLfloat z;

	GLfloat r;
	GLfloat g;
	GLfloat b;

	GLUquadric *quadric;
	GLfloat radius;
	GLuint slices;
	GLuint stacks;

	bool bbox_visible; 

	void draw_bbox();
};

#endif // include guard

  

      
#include "sphere.h"
#include <cassert>

Sphere::Sphere() : bbox_visible(false) {
	quadric = gluNewQuadric();

	if(!quadric)
		assert(false);
}

Sphere::~Sphere() {
	gluDeleteQuadric(quadric);
}

void Sphere::set_position(float x, float y, float z) {
	Sphere::x = x;
	Sphere::y = y;
	Sphere::z = z;
}

void Sphere::set_color(float r, float g, float b) {
	Sphere::r = r;
	Sphere::g = g;
	Sphere::b = b;
}

void Sphere::set_radius(float radius) {
	Sphere::radius = radius;
}

void Sphere::set_slices(GLuint slices) {
	Sphere::slices = slices;
}

void Sphere::set_stacks(GLuint stacks) {
	Sphere::stacks = stacks;
}

void Sphere::toggle_bbox() {
	bbox_visible = !bbox_visible;
}

void Sphere::show_bbox() {
	bbox_visible = true;
}

void Sphere::hide_bbox() {
	bbox_visible = false;
}

void Sphere::draw() {
	glPushMatrix();
		glTranslatef(x, y, z);
		glMaterialfv(GL_FRONT, GL_AMBIENT,  material.get_ambient());
		glMaterialfv(GL_FRONT, GL_DIFFUSE,  material.get_diffuse());
		glMaterialfv(GL_FRONT, GL_SPECULAR, material.get_specular());
		glMaterialfv(GL_FRONT, GL_EMISSION, material.get_emission());
		glMaterialf(GL_FRONT, GL_SHININESS, material.get_shininess());
		gluSphere(quadric, radius, slices, stacks);
		if(bbox_visible)
			draw_bbox();
	glPopMatrix();
}


void Sphere::draw_bbox() {
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glDisable(GL_LIGHTING);
	glColor3f(1.0f, 1.0f, 0.0f);
	
	glBegin(GL_QUAD_STRIP);	
		// vertical walls

		// front, right, back, left

		// total five vertical edges to define

		
		// first edge : near-left

		glVertex3f(-radius, -radius, -radius);
		glVertex3f(-radius, -radius,  radius);
		
		// second edge : near-right

		glVertex3f( radius, -radius, -radius);
		glVertex3f( radius, -radius,  radius);
		
		// third edge : far-right

		glVertex3f( radius,  radius, -radius);
		glVertex3f( radius,  radius,  radius);
		
		// fourth edge : far-left

		glVertex3f(-radius,  radius, -radius);
		glVertex3f(-radius,  radius,  radius);
		
		// fifth edge : near-left

		glVertex3f(-radius, -radius, -radius);
		glVertex3f(-radius, -radius,  radius);
	glEnd();
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	glEnable(GL_LIGHTING);
}

  

      
#ifndef MATERIAL_H
#define MATERIAL_H

#include "win32_gl.h"
#include <gl\gl.h>

class Material {
public:
	Material();
	~Material();

	void set_specular(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
	void set_ambient(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
	void set_diffuse(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
	void set_emission(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
	void set_shininess(GLfloat s);
		
	const GLfloat * get_specular() const;
	const GLfloat * get_ambient() const;
	const GLfloat * get_diffuse() const;
	const GLfloat * get_emission() const;
	GLfloat get_shininess() const;
private:
	GLfloat specular[4];
	GLfloat ambient[4];
	GLfloat diffuse[4];
	GLfloat emission[4];
	GLfloat shininess;
};

#endif
  

      
#include "material.h"

Material::Material() {

}

Material::~Material() {

}

void Material::set_ambient(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
	ambient[0] = r;
	ambient[1] = g;
	ambient[2] = b;
	ambient[3] = a;	
}

void Material::set_diffuse(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
	diffuse[0] = r;
	diffuse[1] = g;
	diffuse[2] = b;
	diffuse[3] = a;	
}

void Material::set_specular(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
	specular[0] = r;
	specular[1] = g;
	specular[2] = b;
	specular[3] = a;	
}

void Material::set_emission(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
	emission[0] = r;
	emission[1] = g;
	emission[2] = b;
	emission[3] = a;	
}

void Material::set_shininess(GLfloat s) {
	shininess = s;
}

const GLfloat * Material::get_specular() const {
	return specular;
}

const GLfloat * Material::get_ambient() const {
	return ambient;
}

const GLfloat * Material::get_diffuse() const {
	return diffuse;
}

const GLfloat * Material::get_emission() const {
	return emission;
}

GLfloat Material::get_shininess() const {
	return shininess;
}
  

      
#ifndef WIN32_GL_H
#define WIN32_GL_H

// do the following or else need to include <windows.h> 

// which comes with loads of rubbish


#if defined(_WIN32)
	
	#ifndef WINGDIAPI
		#define WINGDIAPI __declspec(dllimport)
	#endif
	
	#ifndef APIENTRY
		#define APIENTRY __stdcall
	#endif	

	#ifndef CALLBACK
		#define CALLBACK __stdcall
	#endif	

	#ifndef _WCHAR_T_DEFINED
		typedef unsigned short wchar_t;
		#define _WCHAR_T_DEFINED
	#endif

#endif // _WIN32 


#endif // include guard

    
[edited by - mageziyx on September 9, 2002 12:36:05 PM]
Advertisement
It works damn well ! good work !

I've tested it on GeForce2MX, GeForce3, GeForce4Ti, Radeon 8500 and G450.

ps: Here's the code in a more copy'n'paste-friendly version :
       #include <windows.h>   #ifndef WIN32_GL_H   #define WIN32_GL_H   // do the following or else need to include <windows.h>    // which comes with loads of rubbish   #if defined(_WIN32)                      #ifndef WINGDIAPI                   #define WINGDIAPI __declspec(dllimport)           #endif                      #ifndef APIENTRY                   #define APIENTRY __stdcall           #endif             #ifndef CALLBACK                   #define CALLBACK __stdcall           #endif             #ifndef _WCHAR_T_DEFINED                   typedef unsigned short wchar_t;                   #define _WCHAR_T_DEFINED           #endif   #endif // _WIN32    #endif // include guard       #ifndef MATERIAL_H   #define MATERIAL_H   #include <gl\gl.h>   class Material {   public:           Material();           ~Material();           void set_specular(GLfloat r, GLfloat g, GLfloat b, GLfloat a);           void set_ambient(GLfloat r, GLfloat g, GLfloat b, GLfloat a);           void set_diffuse(GLfloat r, GLfloat g, GLfloat b, GLfloat a);           void set_emission(GLfloat r, GLfloat g, GLfloat b, GLfloat a);           void set_shininess(GLfloat s);                              const GLfloat * get_specular() const;           const GLfloat * get_ambient() const;           const GLfloat * get_diffuse() const;           const GLfloat * get_emission() const;           GLfloat get_shininess() const;   private:           GLfloat specular[4];           GLfloat ambient[4];           GLfloat diffuse[4];           GLfloat emission[4];           GLfloat shininess;   };   #endif                 Material::Material() {   }   Material::~Material() {   }   void Material::set_ambient(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {           ambient[0] = r;           ambient[1] = g;           ambient[2] = b;           ambient[3] = a;    }   void Material::set_diffuse(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {           diffuse[0] = r;           diffuse[1] = g;           diffuse[2] = b;           diffuse[3] = a;    }   void Material::set_specular(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {           specular[0] = r;           specular[1] = g;           specular[2] = b;           specular[3] = a;           }   void Material::set_emission(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {           emission[0] = r;           emission[1] = g;           emission[2] = b;           emission[3] = a;           }   void Material::set_shininess(GLfloat s) {           shininess = s;   }   const GLfloat * Material::get_specular() const {           return specular;   }   const GLfloat * Material::get_ambient() const {           return ambient;   }   const GLfloat * Material::get_diffuse() const {           return diffuse;   }   const GLfloat * Material::get_emission() const {           return emission;   }   GLfloat Material::get_shininess() const {           return shininess;   }        #ifndef SPHERE_H   #define SPHERE_H   #include <gl\glu.h>   class Sphere {   public:           Material material;           Sphere();           ~Sphere();           void set_position(float x, float y, float z);           void set_color(float r, float g, float b);           void set_radius(float radius);           void set_slices(GLuint slices);           void set_stacks(GLuint stacks);           void toggle_bbox();           void show_bbox();           void hide_bbox();           void draw();   private:                   GLfloat x;           GLfloat y;           GLfloat z;           GLfloat r;           GLfloat g;           GLfloat b;           GLUquadric *quadric;           GLfloat radius;           GLuint slices;           GLuint stacks;           bool bbox_visible;            void draw_bbox();   };   #endif // include guard                 #include <cassert>   Sphere::Sphere() : bbox_visible(false) {           quadric = gluNewQuadric();           if(!quadric)                   assert(false);   }   Sphere::~Sphere() {           gluDeleteQuadric(quadric);   }   void Sphere::set_position(float x, float y, float z) {           Sphere::x = x;           Sphere::y = y;           Sphere::z = z;   }   void Sphere::set_color(float r, float g, float b) {           Sphere::r = r;           Sphere::g = g;           Sphere::b = b;   }   void Sphere::set_radius(float radius) {           Sphere::radius = radius;   }   void Sphere::set_slices(GLuint slices) {           Sphere::slices = slices;   }   void Sphere::set_stacks(GLuint stacks) {           Sphere::stacks = stacks;   }   void Sphere::toggle_bbox() {           bbox_visible = !bbox_visible;   }   void Sphere::show_bbox() {           bbox_visible = true;   }   void Sphere::hide_bbox() {           bbox_visible = false;   }   void Sphere::draw() {           glPushMatrix();                   glTranslatef(x, y, z);                   glMaterialfv(GL_FRONT, GL_AMBIENT,  material.get_ambient());                   glMaterialfv(GL_FRONT, GL_DIFFUSE,  material.get_diffuse());                   glMaterialfv(GL_FRONT, GL_SPECULAR, material.get_specular());                   glMaterialfv(GL_FRONT, GL_EMISSION, material.get_emission());                   glMaterialf(GL_FRONT, GL_SHININESS, material.get_shininess());                   gluSphere(quadric, radius, slices, stacks);                   if(bbox_visible)                           draw_bbox();           glPopMatrix();   }   void Sphere::draw_bbox() {           glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);           glDisable(GL_LIGHTING);           glColor3f(1.0f, 1.0f, 0.0f);                      glBegin(GL_QUAD_STRIP);                    // vertical walls                   // front, right, back, left                   // total five vertical edges to define                                      // first edge : near-left                   glVertex3f(-radius, -radius, -radius);                   glVertex3f(-radius, -radius,  radius);                                      // second edge : near-right                   glVertex3f( radius, -radius, -radius);                   glVertex3f( radius, -radius,  radius);                                      // third edge : far-right                   glVertex3f( radius,  radius, -radius);                   glVertex3f( radius,  radius,  radius);                                      // fourth edge : far-left                   glVertex3f(-radius,  radius, -radius);                   glVertex3f(-radius,  radius,  radius);                                      // fifth edge : near-left                   glVertex3f(-radius, -radius, -radius);                   glVertex3f(-radius, -radius,  radius);           glEnd();           glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);           glEnable(GL_LIGHTING);   }   #include <glut.h>   #include <iostream>   using namespace std;   Sphere  sphere0;   Sphere  sphere1;   Sphere  sphere2;   GLuint select_buffer[100];   GLfloat angle = 0;   const GLuint RED_SPHERE   = 10;   const GLuint GREEN_SPHERE = 20;   const GLuint BLUE_SPHERE  = 30;   void lights()    {           // lights           GLfloat position[] = { 500.0f, 0.0f, 500.0f, 1.0f };           GLfloat ambient[]  = { 0.6f, 0.6f, 0.6f, 1.0f };           GLfloat diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };           GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };           GLfloat emission[] = { 0.0f, 0.0f, 0.0f, 1.0f };           glLightfv(GL_LIGHT0, GL_POSITION,       position);           glLightfv(GL_LIGHT0, GL_AMBIENT,        ambient);           glLightfv(GL_LIGHT0, GL_DIFFUSE,        diffuse);           glLightfv(GL_LIGHT0, GL_SPECULAR,       specular);           glLightfv(GL_LIGHT0, GL_EMISSION,       emission);   }   void displayfunc()   {           glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);           glMatrixMode(GL_MODELVIEW);           glLoadIdentity();           gluLookAt(200.0f, 200.0f,   0.0f,                                0.0f,   0.0f,   0.0f,                                    0.0f,   0.0f,   1.0f);           lights();           glRotatef(angle, 0.0f, 0.0f, 1.0f);                      sphere0.draw();           sphere1.draw();           sphere2.draw();           angle += 0.5f;           if(angle > 360.0f) {                   angle -= 360.0f;           }           glutSwapBuffers();   }   void reshapefunc(int width, int height)   {           GLfloat aspect = (GLfloat) width / (GLfloat) height;                      glMatrixMode(GL_PROJECTION);           glLoadIdentity();           gluPerspective(45.0f, aspect, 0.1f, 1000.0f);           glViewport(0, 0, width, height);   }   void idlefunc()   {           glutPostRedisplay();   }   void pick(int x, int y)   {           GLint viewport[4];           glGetIntegerv(GL_VIEWPORT, viewport);           GLfloat width  = viewport[2];           GLfloat height = viewport[3];           GLfloat aspect = width / height;           // opengl windows coordinates is           // x to the right & y upwards           // but glut gives mouse coordinates with           // x to the right & y downwards           // also, glut give mouse coordinates with respect to            // client area but opengl is with respect to viewport           // do the following conversion :           GLuint gl_x = x - viewport[0];           GLuint gl_y = viewport[1] + viewport[3] - y - 1;           cout << "***************************************" << endl;           cout << "               PICK                    " << endl;           cout << "***************************************" << endl;           cout << "Pick Matrix : gl_x = " << gl_x << " gl_y = " << gl_y << endl;           glMatrixMode(GL_PROJECTION);           glLoadIdentity();                  gluPickMatrix(gl_x, gl_y,       // coordinates                                     1, 1,                 // size                                      viewport);           gluPerspective(45.0f, aspect, 0.1f, 1000.0f);           // drawing for selection           glRenderMode(GL_SELECT); // note that glSelectBuffer MUST be called before glRenderMode(GL_SELECT)           glInitNames(); // gl*Names functions are ignored unless in GL_SELECT render mode           glPushName(0);           glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);           glMatrixMode(GL_MODELVIEW);           glLoadIdentity();           gluLookAt(200.0f, 200.0f,   0.0f,                                    0.0f,   0.0f,   0.0f,                                    0.0f,   0.0f,   1.0f);           glRotatef(angle, 0.0f, 0.0f, 1.0f);           glLoadName(RED_SPHERE);           sphere0.draw();           glLoadName(GREEN_SPHERE);           sphere1.draw();            glLoadName(BLUE_SPHERE);           sphere2.draw();            glFlush();           // end drawing for selection           GLuint hits = glRenderMode(GL_RENDER);           cout << "number of hits = " << hits << endl;                      // structure for a single hit record (all integers)           //           // 1. number of names on name stack when hit occured           // 2. minimum depth of all hit primitives           // 3. maximum depth of all hit primitives            // 4. entries in name stack           //           GLuint *p = select_buffer;           GLuint nearest_obj = 0;           GLuint most_min_depth = 0;           cout << "iterate through all hit records" << endl;           // loop thru' all hit records           for(GLuint i=0; i<hits; i++) {                   cout << "HIT RECORD " << i << " :" << endl;                   GLuint name_count = *p;                   cout << "hit " << i << endl;                   cout << "number of names on name stack = " << name_count << endl;                                      GLuint min_depth = *(++p);                   GLuint max_depth = *(++p);                   cout << "min depth = " << min_depth << endl;                   cout << "max depth = " << max_depth << endl;                   for(GLuint j=0; j<name_count; j++) {                           cout << "name " << j << " = " << *(++p) << endl;                   }                   // if this is the first hit to be examined...                   // or this object has the minimum depth                   // then set nearest obj so far to this obj                   if(most_min_depth == 0 || min_depth < most_min_depth) {                           most_min_depth = min_depth;                           nearest_obj = *p;                           cout << "nearest_obj = " << *p << endl;                   }                   p++;           }           sphere0.hide_bbox();           sphere1.hide_bbox();           sphere2.hide_bbox();           if(nearest_obj == RED_SPHERE) {                   sphere0.show_bbox();                   cout << "red sphere picked" << endl;           }           else if(nearest_obj == GREEN_SPHERE) {                   sphere1.show_bbox();                   cout << "green sphere picked" << endl;           }           else if(nearest_obj == BLUE_SPHERE) {                   sphere2.show_bbox();                   cout << "blue sphere picked" << endl;           }           // reset the projection matrix           glMatrixMode(GL_PROJECTION);           glLoadIdentity();                          gluPerspective(45.0f, aspect, 0.1f, 1000.0f);           // redraw           glutPostRedisplay();   }   void mousefunc(int button, int state, int x, int y)   {           if(state == GLUT_DOWN) {                   pick(x, y);           }   }   void init()   {           // gl settings           glEnable(GL_DEPTH_TEST);           glShadeModel(GL_SMOOTH);           glClearColor(0.0f, 0.0f, 0.0f, 1.0f);                                      glClearDepth(1.0f);                                                                                                        glDepthFunc(GL_LEQUAL);                                                            glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);           // selection           glSelectBuffer(100, select_buffer);           // light           glEnable(GL_LIGHTING);           glEnable(GL_LIGHT0);           // sphere 0 - RED           sphere0.toggle_bbox();           sphere0.material.set_ambient(0.2f, 0.2f, 0.2f, 1.0f);           sphere0.material.set_diffuse(0.5f, 0.0f, 0.0f, 1.0f);           sphere0.material.set_specular(0.6f, 0.6f, 0.6f, 1.0f);           sphere0.material.set_emission(0.0f, 0.0f, 0.0f, 1.0f);           sphere0.material.set_shininess(40); // 0.0f to 128.0f           sphere0.set_position(100, 0, 0);           sphere0.set_radius(20);           sphere0.set_slices(40);           sphere0.set_stacks(40);           // sphere 1 - GREEN           sphere1.material.set_ambient(0.2f, 0.2f, 0.2f, 1.0f);           sphere1.material.set_diffuse(0.0f, 0.5f, 0.0f, 1.0f);           sphere1.material.set_specular(0.6f, 0.6f, 0.6f, 1.0f);           sphere1.material.set_emission(0.0f, 0.0f, 0.0f, 1.0f);           sphere1.material.set_shininess(40);           sphere1.set_position(0, 0, 0);           sphere1.set_radius(20);           sphere1.set_slices(40);           sphere1.set_stacks(40);           // sphere 2 - BLUE           sphere2.material.set_ambient(0.2f, 0.2f, 0.2f, 1.0f);           sphere2.material.set_diffuse(0.0f, 0.0f, 0.5f, 1.0f);           sphere2.material.set_specular(1.0f, 1.0f, 1.0f, 1.0f);           sphere2.material.set_emission(0.0f, 0.0f, 0.0f, 1.0f);           sphere2.material.set_shininess(40);                sphere2.set_position(-100, 0, 0);           sphere2.set_radius(20);           sphere2.set_slices(40);           sphere2.set_stacks(40);   }   int main(int argc, char *argv[])   {           glutInitWindowSize(320, 240);           glutInitWindowPosition(100, 100);           glutInit(&argc, argv);           glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH |GLUT_DOUBLE);           glutCreateWindow("picking - click sphere to select");           glutDisplayFunc(displayfunc);           glutReshapeFunc(reshapefunc);           glutIdleFunc(idlefunc);           glutMouseFunc(mousefunc);           init();           glutMainLoop();           return 0;   }  


[edited by - vincoof on September 9, 2002 2:52:34 PM]
thks vincoof, guess something''s wrong with my prophet card or drivers then, maybe should get another card

This topic is closed to new replies.

Advertisement