Skip to main content
GameDev.net gamedev.net
🔒 Locked

picking quads

Started by hearo Jan 22, 2008 at 10:46 AM 0 replies 550+ views
Original Post
hearo
hearo
Hi, I posted a while back about GL_POINTS and videocard problems. Seems not all cards support all point sizes. It was suggested on the list I try to use GL_QUADS instead of points, which I've done. But now I've lost the picking capability. Not sure what's happening, and could use some advice. I understand ray picking is better, but I'm not quite at that level yet. This is a slight var. of the Kilgard ex. editgrid.c, but instead of points I'm using glquads, but can't seem to pick them. Thank you for comments, advice.

/* Adapted from Mark J. Kilgard editgrid.c, 1997. */

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>

#define DEBUG

int antialiasing = 0;
int gridSize = 20;
GLuint selectedPoint = ~0;
int winWidth, winHeight;
GLuint selectBuffer[64];
GLdouble modelMatrix[16], projMatrix[16];
GLint viewport[4];


/* 4nd order initial grid.  16 points (4 by 4). */
GLfloat grid4x4[4][4][3] =
{
  {
    {-2.0, -2.0, 0.0},
    {-0.5, -2.0, 0.0},
    {0.5, -2.0, 0.0},
    {2.0, -2.0, 0.0}},
  {
    {-2.0, -0.5, 0.0},
    {-0.5, -0.5, 0.0},
    {0.5, -0.5, 0.0},
    {2.0, -0.5, 0.0}},
  {
    {-2.0, 0.5, 0.0},
    {-0.5, 0.5, 0.0},
    {0.5, 0.5, 0.0},
    {2.0, 0.5, 0.0}},
  {
    {-2.0, 2.0, 0.0},
    {-0.5, 2.0, 0.0},
    {0.5, 2.0, 0.0},
    {2.0, 2.0, 0.0}}
};

GLfloat quadpoints [4][4][3] =
{
	//top left
	{
	{ -1.2f,  1.1f, 0.0f},	// Top Left
	{ -1.0f,  1.1f, 0.0f},	// Top Right
	{ -1.0f,  0.9f, 0.0f},	// Bottom Right
	{ -1.2f,  0.9f, 0.0f}},  // Bottom Left

	//top right square
	{
	{ 1.0f, 1.1f, 0.0f},// Top Left
	{1.2f,  1.1f, 0.0f},// Top Right
	{1.2f,  0.9f, 0.0f},// Bottom Right
	{1.0f,  0.9f, 0.0f}},//Bottom Left

	//bottom right square
	{
	{1.0f, -1.2f, 0.0f},	// Top Left
	{1.2f,  -1.2f, 0.0f},	// Top Right
	{1.2f,  -1.4f, 0.0f},	// Bottom Right
	{1.0f, -1.4f, 0.0f}},  // Bottom Left

	//bottomleft square
	{
	{-1.2f, -1.2f, 0.0f},	// Top Left
	{-1.0f,  -1.2f, 0.0f},	// Top Right
	{-1.0f,  -1.4f, 0.0f},	// Bottom Right
	{-1.2f, -1.4f, 0.0f}}   // Bottom Left
    
    }; 
    
GLfloat *quad = &quadpoints[0][0][0];
GLfloat *grid = &grid4x4[0][0][0];

int uSize = 4;
int vSize = 4;

void
setupMesh(void)
{
  glEnable(GL_MAP2_VERTEX_3);
  glMapGrid2f(gridSize, 0.0, 1.0, gridSize, 0.0, 1.0);
}

void
evaluateGrid(void)
{
  glColor3f(1.0, 1.0, 1.0);
  glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, uSize, 0, 1, uSize * 3, vSize, grid);
  glEvalMesh2(GL_LINE, 0, gridSize, 0, gridSize);
}

void
drawQuadPoints(void)
{
  int i;

  glColor3f(1.0, 1.0, 0.0);
  glBegin(GL_QUADS);
  for (i = 0; i < uSize * vSize; i++) {
    glVertex3fv(&quad[i * 3]);
  }
  glEnd();
  
  
  
}

void
selectQuadPoints(void)
{
  int i;

  for (i = 0; i < uSize * vSize; i++) {
    glLoadName(i);
    glBegin(GL_QUADS);
    glVertex3fv(&quad[i * 3]);
    glEnd();
  }
  
}

void
display(void)
{
  glClear(GL_COLOR_BUFFER_BIT);
  evaluateGrid();
  drawQuadPoints();
  glutSwapBuffers();
}

void
ortho(void)
{
  if (winWidth <= winHeight)
    glOrtho(-4.0, 4.0, -4.0 * (GLfloat) winHeight / (GLfloat) winWidth,
      4.0 * (GLfloat) winHeight / (GLfloat) winWidth, -4.0, 4.0);
  else
    glOrtho(-4.0 * (GLfloat) winWidth / (GLfloat) winHeight,
      4.0 * (GLfloat) winWidth / (GLfloat) winHeight, -4.0, 4.0, -4.0, 4.0);
}

GLuint
pick(int x, int y)
{
  int hits;

  (void) glRenderMode(GL_SELECT);
  glInitNames();
  glPushName(~0);
  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  gluPickMatrix(x, winHeight - y, 8.0, 8.0, viewport);
  ortho();
  glMatrixMode(GL_MODELVIEW);
  selectQuadPoints();
  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_MODELVIEW);
  hits = glRenderMode(GL_RENDER); 
  
  if (hits) {
#ifdef DEBUG
    {
      unsigned int i;
      GLint names;
      GLuint *ptr;

      printf("hits = %d\n", hits);
      ptr = (GLuint *) selectBuffer;
      for (i = 0; i < hits; i++) {  /* for each hit  */
        int j;

        names = *ptr;
        printf("number of names for hit = %d\n", *ptr);
        ptr++;
        printf("  z1 is %g;", (float) *ptr / 0xffffffff);
        ptr++;
        printf("  z2 is %g\n", (float) *ptr / 0xffffffff);
        ptr++;
        printf(" the name is ");
        for (j = 0; j < names; j++) {  /* For each name. */
          printf("%d ", *ptr);
          ptr++;
        }
        printf("\n");
      }
    }
#endif
    return selectBuffer[3];
  } else {
    return ~0;
  }
}

void
reshape(int w, int h)
{
  glViewport(0, 0, w, h);
  winWidth = w;
  winHeight = h;

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  ortho();
  glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
  viewport[0] = 0;
  viewport[1] = 0;
  viewport[2] = winWidth;
  viewport[3] = winHeight;
}

void
mouse(int button, int state, int x, int y)
{
  if (button == GLUT_LEFT_BUTTON) {
    if (state == GLUT_DOWN) {
      selectedPoint = pick(x, y);
    } //else {
      //selectedPoint = -1;
    //}
  }
}

void
motion(int x, int y)
{
  GLdouble objx, objy, objz;

  if (selectedPoint != ~0) {
    gluUnProject(x, winHeight - y, 0.95,
      modelMatrix, projMatrix, viewport,
      &objx, &objy, &objz);
    grid[selectedPoint * 3 + 0] = objx;
    grid[selectedPoint * 3 + 1] = objy;
    glutPostRedisplay();
  }

}
int
main(int argc, char **argv)
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  glutCreateWindow("editgrid");
  glutReshapeFunc(reshape);
  glutDisplayFunc(display);
  glutMouseFunc(mouse);
  glutMotionFunc(motion);
  glSelectBuffer(sizeof(selectBuffer), selectBuffer);
  setupMesh();
  glutMainLoop();
  return 0;             /* ANSI C requires main to return int. */
}


Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.