#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
picking problem
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???
[edited by - mageziyx on September 9, 2002 12:36:05 PM]
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 :
[edited by - vincoof on September 9, 2002 2:52:34 PM]
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]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement