Hi im new to this forum and this post is about a problem im having with selection and feedback, more likely is the feedback then selection, here is my prob:
First i shot in the code and then i tell you what i need to do
Code:
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
#define SELECT_BUFF 64
#define FEEDBACK_BUFF 512
#define cube 1
struct Rect
{
float left;
float right;
float bottom;
float top;
float near;
float far;
} typedef Rect;
int selectedObject = 0;
Rect box;
void unproject(float x, float y, float z, GLdouble *dest)
{
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat wx = x, wy, wz = z;
glGetIntegerv(GL_VIEWPORT,viewport);
glGetDoublev(GL_MODELVIEW_MATRIX,modelview);
glGetDoublev(GL_PROJECTION_MATRIX,projection);
wy = y = viewport[3]-y;
gluUnProject(wx, wy, wz, modelview, projection, viewport, &dest[0], &dest[1], &dest[2]);
}
void kocka (int color)
{
glColor3f(0.5, 0.5, 0.5);
if(color == 1)
{
glColor3f(1,1,1);
}
glBegin(GL_QUADS);
// Front face
glVertex3f(-1.0, -1.0, 1.0);
glVertex3f( 1.0, -1.0, 1.0);
glVertex3f( 1.0, 1.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0);
// Back face
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f(-1.0, 1.0, -1.0);
glVertex3f(1.0, 1.0, -1.0);
glVertex3f( 1.0, -1.0, -1.0);
// Top face
glVertex3f(-1.0, 1.0, -1.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f( 1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0);
// Bottom face
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f( 1.0, -1.0, -1.0);
glVertex3f( 1.0, -1.0, 1.0);
glVertex3f(-1.0, -1.0, 1.0);
// Right face
glVertex3f(1.0, -1.0, -1.0);
glVertex3f(1.0, 1.0, -1.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
// Left face
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(-1.0, 1.0, -1.0);
glEnd();
}
void drawScene(GLenum mode)
{
if(mode == GL_RENDER || mode == GL_FEEDBACK)
{
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(65, 800/600, 1, 100);
}
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gluLookAt(2, 5, 4, 0, 0, 0, 0, 1, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if(mode == GL_SELECT) glLoadName(cube);
if(mode == GL_FEEDBACK) glPassThrough((GLfloat)cube);
glPushMatrix();
glTranslatef(-2, 1, 1);
kocka(selectedObject);
glPopMatrix();
}
void makeSelection(int object)
{
static GLfloat feedbackBuffer[FEEDBACK_BUFF];
int size, i, j, count;
glFeedbackBuffer(FEEDBACK_BUFF, GL_3D, feedbackBuffer);
glRenderMode(GL_FEEDBACK);
drawScene(GL_FEEDBACK);
size = glRenderMode(GL_RENDER);
i = 0;
while(i < size)
{
if(feedbackBuffer[i] == GL_PASS_THROUGH_TOKEN)
{
if(feedbackBuffer[i+1] == (GLfloat)object)
{
i += 2;
while(i < size && feedbackBuffer[i] != GL_PASS_THROUGH_TOKEN)
{
if(feedbackBuffer[i] == GL_POLYGON_TOKEN)
{
count = (int)feedbackBuffer[++i];
i++;
for(j = 0; j < count; j++)
{
//min x , max x
if(feedbackBuffer[i] < box.left) box.left = feedbackBuffer[i];
if(feedbackBuffer[i] > box.right) box.right = feedbackBuffer[i++];
//min y, max y
if(feedbackBuffer[i] < box.bottom) box.bottom = feedbackBuffer[i];
if(feedbackBuffer[i] > box.top) box.top = feedbackBuffer[i++];
//min z, max z (depth)
if(feedbackBuffer[i] < box.near) box.near = feedbackBuffer[i];
if(feedbackBuffer[i] > box.far) box.far = feedbackBuffer[i++];
}
}
else
{
i++;
}
}
break;
}
}
i++;
}
glutPostRedisplay();
}
void processSelection(float x, float y)
{
static GLuint selectBuffer[SELECT_BUFF];
GLint hits, viewport[4];
glSelectBuffer(SELECT_BUFF, selectBuffer);
glGetIntegerv(GL_VIEWPORT, viewport);
glRenderMode(GL_SELECT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix((GLdouble)x, viewport[3] - (GLdouble)y, 0.5, 0.5, viewport);
gluPerspective(65, 800/600, 1, 100);
glInitNames();
glPushName(0);
drawScene(GL_SELECT);
glPopName();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
hits = glRenderMode(GL_RENDER);
if(hits > 0)
{
makeSelection(selectBuffer[3]);
if(selectedObject == 0) selectedObject = 1;
else selectedObject = 0;
}
}
void display()
{
drawScene(GL_RENDER);
if(selectedObject != 0)
{
GLdouble vk1[3], vk2[3];
unproject(box.left, box.bottom, box.near, vk1);
unproject(box.right, box.top, box.far, vk2);
printf("********************
");
printf("x: %f, y: %f, z: %f
", vk1[0], vk1[1], vk1[2]);
printf("x: %f, y: %f, z: %f
", vk2[0], vk2[1], vk2[2]);
printf("********************
");
glPushMatrix();
glTranslatef(vk1[0], vk1[1], vk1[2]);
glScalef(0.5, 0.5, 0.5);
kocka(selectedObject);
glPopMatrix();
}
glFlush();
glutSwapBuffers();
}
void init(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_SMOOTH);
box.left = 9999;
box.right = -9999;
box.bottom = 9999;
box.top = -9999;
box.near = 9999;
box.far = -9999;
}
void mouseCallback(int button, int state, int x, int y)
{
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
processSelection((float)x, (float)y);
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize (800, 600);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Test");
init();
glutDisplayFunc(display);
glutMouseFunc(mouseCallback);
glutMainLoop();
return 0;
}
So im supposed to make when i select the cube to draw box around it on the same spot where it is, as you can see i got function as default mouse function called mouseCallback, when i click with the mouse on the screen that function calls the processSelection function which takes the (x,y) position of the mouse currently being clicked and then here i do the GL_SELECT mode drawing in this case i draw in just tiny cube around the mouse position with width and height of 0.5 with center at (x,y) the mouse position, and as usual draw everything that is inside that new drawing-volume giving corresponding names to the objects being drawn in the drawing-volume that is the objects that were intersecting the new drawing-volume i have made with making new clean identity projection matrix and then multiplying that one with the gluPickMatrix with the given parameters and last multiplying that with perspective matrix with the given parameters and finally i get the new draw-volume (new world space for selection mode), so far going good i think well what i do next in the same function i get the first item being drawn on the selection buffer i previously defined in on the top in the function that’s selectionBuffer, the id of the first item on the buffer is located on the 4 spot actually 3 cause starting from 0, so i fetch that id with selectionBuffer[3] and send it to the makeSelection function which now represents the feedbackBuffer browsing function, as usual i draw everthing i drew in GL_RENDER mode but now in GL_FEEDBACK mode and i put in tokens for the objects in this case one token defined on the top of the .c file named cube with value 1, so i passThrough((GLfloat)cube) (my feedbackBuffer is of type GLfloat) and now with everthing put on the buffer i get the size and start looking for the id that shares both the feedback and selection buffers and thus i get the selected item to be found in the feedback buffer as well, so when i reach it i just find the min and max values for x and y and the min and max depth for z coords of the object drawn after the id token for the same object i selected previously and those min and max values i set in struct to hold them named Rect, when i get those info cause i get those in screen coords i use the unproject function which now uses gluUnproject function to determine the actual world coords for the object so i can draw the bounding box there…
After all this i wrote i still have to say “THIS DAMN THING DOESNT WORK!!”
So help please, thanks!! :))))