Ejemplo n.º 1
0
int OGLWidget::getObjectAtScreenPos(int x, int y)
{
    // set up the selection buffer
    GLuint buffer[512];
    glSelectBuffer(512, buffer);

    // Get the viewport values
    GLint viewport[4];
    glGetIntegerv(GL_VIEWPORT, viewport);

    // Go into Selection Mode
    glRenderMode(GL_SELECT);
    glInitNames();		// Initializes The Name Stack
    glPushName(-1);		// Push at least one entry

    // go to projection matrix and limit the area around the mouse to be 'drawn'
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();		// Push The Projection Matrix
    glLoadIdentity();	// Resets The Matrix
    gluPickMatrix((GLdouble) x, (GLdouble) (viewport[3]-y), 1.0f, 1.0f, viewport);

    // also set the perspective to ensure the new aspect ratio is correct
    gluPerspective(45.0f, (GLfloat) (viewport[2]-viewport[0])/(GLfloat) (viewport[3]-viewport[1]), 0.1f, 1500.0f);

    // now paint the objects
    glMatrixMode(GL_MODELVIEW);
    parentView_->drawNodes();

    // switch everything back
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);

    // check for hits by switching render mode
    GLint hits=glRenderMode(GL_RENDER);

    // do we have any?
    if (hits > 0)
    {
        // note: selection buffer has 4 values per hit: # of hits at time, min depth, max depth, name

        // start by picking the first hit
        int choose = buffer[3];
        int depth = buffer[1];

        // now loop over the rest
        for (int loop = 1; loop < hits; loop++)
        {
            // is this object closer?
            if (buffer[loop*4+1] < GLuint(depth))
            {
                choose = buffer[loop*4+3];
                depth = buffer[loop*4+1];
            }
        }

        return choose;
    }

    return -1;
}
Ejemplo n.º 2
0
Archivo: glmenu.c Proyecto: nasa/QuIP
static COMMAND_FUNC( do_slct_obj )
{
	int x, y;
	const char *s;
	GLuint n_names, *ptr;
	GLint hits;
	GLuint this_hit=0;	/* initialize to silence compiler */
	GLuint the_hit;
	float z1,z2;
	float z_this,z_min;
	int clickWindowSize = 1;
	GLint viewport[4];
	GLint i;
	GLuint j;
	char ret_str[32];

	x=(int)HOW_MANY("x location");
	y=(int)HOW_MANY("y location");
	s=NAMEOF("scene render command");
	s=savestr(s);

	//glPushMatrix();

	glSelectBuffer(MAX_SELECT,selectBuf);
	check_gl_error("glSelectBuffer");
	glRenderMode(GL_SELECT);
	check_gl_error("glRenderMode");

	glMatrixMode(GL_PROJECTION);
	check_gl_error("glMatrixMode");
	glPushMatrix();
	check_gl_error("glPushMatrix");
	glLoadIdentity();
	check_gl_error("glLoadIdentity");

	glGetIntegerv(GL_VIEWPORT,viewport);
	check_gl_error("glGetIntegerv");
	gluPickMatrix(x,viewport[3]-y,
			clickWindowSize,clickWindowSize,viewport);
	check_gl_error("gluPickMatrix");
	// Setup camera.
	//drawer.setupCamera(&manager);
	//glMatrixMode(GL_MODELVIEW);
	glInitNames();
	check_gl_error("glInitNames");
	glPushName(0);
	check_gl_error("glPushName");
	//drawer.drawAirspace(&manager, &table);
	
	/* Call the user's draw routine here... */
	chew_text(s, "(gl object selection)" );
	rls_str(s);

	// Restoring the original projection matrix.
	glMatrixMode(GL_PROJECTION);
	check_gl_error("glMatrixMode GL_PROJECTION");
	glPopMatrix();
	check_gl_error("glPopMatrix");
	glMatrixMode(GL_MODELVIEW);
	check_gl_error("glMatrixMode GL_MODELVIEW");
	glFlush();
	check_gl_error("glFlush");

	// Returning to normal rendering mode.
	hits = glRenderMode(GL_RENDER);

	//printf ("hits = %d\n", hits);

	// Red book example.
	// When there are multiple objects, the hits are recorded
	// in drawing order, we have to check the z values to know
	// which is the foreground object.
	z_min=100000;
	ptr = (GLuint *) selectBuf;
	for (i = 0; i < hits; i++) {
		n_names = *ptr++;
		z1= ((float)*ptr++)/0x7fffffff;
		z2= ((float)*ptr++)/0x7fffffff;

		if( z1 < z2 ) z_this = z1;
		else z_this=z2;

		if( z_this < z_min ) z_min=z_this;

		for(j=0;j<n_names;j++){
			this_hit=*ptr++;
		}
//		sprintf(ERROR_STRING,"Hit %d, %d from %g to %g, last is %d",
//			i,n_names,z1,z2,this_hit);
//		advise(ERROR_STRING);
	}
	the_hit=0;
	ptr = (GLuint *) selectBuf;
	for (i = 0; i < hits; i++) {
		n_names = *ptr++;
		z1= ((float)*ptr++)/0x7fffffff;
		z2= ((float)*ptr++)/0x7fffffff;
		if( z1 < z2 ) z_this = z1;
		else z_this=z2;
		for(j=0;j<n_names;j++){
			this_hit=*ptr++;
		}
		if( z_this == z_min )
			the_hit=this_hit;
	}
//sprintf(ERROR_STRING,"front-most hit is %d",the_hit);
//advise(ERROR_STRING);
	sprintf(ret_str,"%d",the_hit);
	assign_reserved_var("selection_index",ret_str);

	//if (hits != 0) {
	//manager.advanceTrial(processHits());
	//}

	//glPopMatrix();

	/* Set a variable to indicate what happened */
}
Ejemplo n.º 3
0
//================================================================
  int GLBT_sel_sel (int *sTyp, long *sDbi, int *stat,
                    int sx, int sy) {
//================================================================
// start GL-selection only for selectors.
// see GL_sel_rect
 
  int      hits;
  long     *ia;
  float   fz;
  GLuint   *selectBuf, BUF_SIZ;



  // printf("GLBT_sel_sel ============================\n");


  // switch to ProjectionMode
  glMatrixMode (GL_PROJECTION);
  // save active matrix
  glPushMatrix ();
  // load Defaultmat.
  glLoadIdentity ();




  //----------------------------------------------------------------
  // Init Sel. Buffer (BEFORE switching to select)
  selectBuf = (int*)memspc501;
  BUF_SIZ = sizeof(memspc501) / sizeof(GLuint);
  glSelectBuffer (BUF_SIZ, selectBuf);

  // start select
  glRenderMode (GL_SELECT);
  GL_mode_draw_select = GR_MODE_2DSELECT;

  // Init NameStack.
  glInitNames(); 
  glPushName((GLuint)0);       // Muss sein. Damit ein Name am Stack ist,

  // define pick-window (rectangle 5x5 pixels)
  // - changes active (PROJECTION)-matrix !
  gluPickMatrix ((double)sx, (double)sy, 5., 5., GL_Viewp);



  //----------------------------------------------------------------
  // redraw all objs to be picked / selectors, buttons

  // set glOrtho - 2D, GLBT_ori
  GLBT_view__ ();
  // fz = GL_Scr_Siz_X * 10.f;
  // glOrtho (0.f, (float)GL_Scr_Siz_X, 0.f, (float)GL_Scr_Siz_Y, -fz, fz);
  // UT3D_pt_3db (&GLBT_ori, GL_Scr_Siz_X - GLBT_POS_ORI, GLBT_POS_ORI, 0.);

  // redraw
  if(GLBT_vcSelStat >= 0) GLBT_disp_vc ();
  if(GLBT_plnSelStat >= 0) GLBT_disp_Pln ();
  if(I2D_iNr > 0) GLBT_but_disp ();

  // close, fill buffer
  hits = glRenderMode (GL_RENDER);
    // printf(" GLBT-hits=%d\n",hits);

  // restore 
  GL_mode_draw_select = GR_MODE_DRAW;

  if(hits < 1) {
    if(hits < 0) TX_Print("ERROR: selectbuffer overflow ...");
    goto Fertig;
  }


  //----------------------------------------------------------------
  // decode hits, add hits into selectionBuffer
  ia = (long*)MEM_alloc_tmp ((int)(hits * sizeof(long)));

  GL_sel_hits (ia, selectBuf, hits);

  // 1-9 are vectors
  if(ia[0] < 10) {
    *sTyp = Typ_VC;
    // test specialVector GLBT_vcSelStat
    if(ia[0] == 7) *sDbi = GLBT_vcSelStat;
    else           *sDbi = -ia[0];   // stdVector negativ (DB_VCX_IND ..)
    goto Fertig;
  }

  // 11,12,13 = stdPlanes
  *sTyp = Typ_PLN;
  *sDbi = 10L - ia[0];


  //----------------------------------------------------------------
  Fertig:

  // replace saved matrix
  glMatrixMode (GL_PROJECTION);
  glPopMatrix ();
  // back to normal rendering
  glMatrixMode (GL_MODELVIEW);


  return 0;

}
Ejemplo n.º 4
0
void get_3d_object_under_mouse()
{
	//ok, first of all, let's see what objects we have in range...
	int i, count, x, y, dist1, dist2, hits;
	GLint viewport[4];
	GLuint *buffer, z_coordinate;
	double matrix[16];
	
	selected_3d_object = -1;
	x = (int)-camera_x;
	y = (int)-camera_y;

	count = 0;
	for (i = 0; i < MAX_OBJ_3D; i++)
	{
		if (objects_list[i] && objects_list[i]->blended != 20)
		{
			dist1 = x - (int)objects_list[i]->x_pos;
			dist2 = y - (int)objects_list[i]->y_pos;
			if (dist1 * dist1 + dist2 * dist2 <= ((40 * 40) * (zoom_level / 15.75f)))
			{
				count++;
			}
		}
	}

#ifndef EYE_CANDY
	if (count == 0)
	{
		return;
	}
#endif
	count++;
	count *= 4;
	glGetIntegerv(GL_VIEWPORT, viewport);
	buffer = malloc(count * sizeof(GLuint));
	glSelectBuffer(count, buffer);

	glGetDoublev(GL_PROJECTION_MATRIX, matrix);

	glRenderMode(GL_SELECT);
	glInitNames();
	glPushName(0);
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluPickMatrix(mouse_x, window_height-mouse_y, 1.0, 1.0, viewport);
	glMultMatrixd(matrix);
	glMatrixMode(GL_MODELVIEW);

	glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);

	glEnable(GL_CULL_FACE);
	glEnableClientState(GL_VERTEX_ARRAY);
	glPushMatrix();
	glLoadIdentity();					// Reset The Matrix
	Move();

	for (i = 0; i < MAX_OBJ_3D; i++)
	{
		if (objects_list[i] && objects_list[i]->blended != 20)
		{
			dist1 = x - (int)objects_list[i]->x_pos;
			dist2 = y - (int)objects_list[i]->y_pos;
			if (dist1 * dist1 + dist2 * dist2 <= ((40 * 40) * (zoom_level / 15.75f)))
			{
				glLoadName(i);
				draw_3d_object(objects_list[i]);
			}
		}
	}

#ifdef EYE_CANDY
	if (cur_mode == mode_eye_candy)
	{
	  draw_eye_candy_selectors();
	}
#endif

	glPopMatrix();
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glDisable(GL_CULL_FACE);
	glDisableClientState(GL_VERTEX_ARRAY);

	hits = glRenderMode(GL_RENDER);
	z_coordinate = 0xFFFFFFFF;
	for (i = 0; i < hits; i++)
	{
		if (buffer[(i * 4) + 1] < z_coordinate)
		{
			selected_3d_object = buffer[(i*4)+3];
			z_coordinate = buffer[(i*4)+1];
		}
	}
	free(buffer);
}
int GLWidget::getObjectID(int x, int y)
{
    // This will hold the amount of objects clicked
    int objectsFound = 0;

    // We need an array to hold our view port coordinates
    int	viewportCoords[4] = {0};

    // This will hold the ID's of the objects we click on.
    // We make it an arbitrary number of 32 because openGL also stores other information
    // that we don't care about.  There is about 4 slots of info for every object ID taken up.
    GLuint selectBuffer[32] = {0};

    // glSelectBuffer is what we register our selection buffer with.  The first parameter
    // is the size of our array.  The next parameter is the buffer to store the information found.
    // More information on the information that will be stored in selectBuffer is further below.
    // Setup our selection buffer to accept object ID's
    glSelectBuffer(32, selectBuffer);

    // This function returns information about many things in OpenGL.  We pass in GL_VIEWPORT
    // to get the view port coordinates.  It saves it like a RECT with {top, left, bottom, right}
    // Get the current view port coordinates
    glGetIntegerv(GL_VIEWPORT, viewportCoords);

    // Now we want to get out of our GL_MODELVIEW matrix and start effecting our
    // GL_PROJECTION matrix.  This allows us to check our X and Y coords against 3D space.
    // We now want to effect our projection matrix
    glMatrixMode(GL_PROJECTION);

    // We push on a new matrix so we don't effect our 3D projection
    glPushMatrix();

    // This makes it so it doesn't change the frame buffer if we render into it, instead,
    // a record of the names of primitives that would have been drawn if the render mode was
    // GL_RENDER are now stored in the selection array (selectBuffer).
    // Allows us to render the objects without changing framebuffer
    glRenderMode(GL_SELECT);

    // Reset our projection matrix
    glLoadIdentity();

    // gluPickMatrix allows us to create a projection matrix that is around our
    // cursor.  This basically only allows rendering in the region that we specify.
    // If an object is rendered into that region, then it saves that objects ID for us (The magic).
    // The first 2 parameters are the X and Y position to start from, then the next 2
    // are the width and height of the region from the starting point.  The last parameter is
    // of course our view port coordinates.  You will notice we subtract "y" from the
    // BOTTOM view port coordinate.  We do this to flip the Y coordinates around.  The 0 y
    // coordinate starts from the bottom, which is opposite to window's coordinates.
    // We also give a 2 by 2 region to look for an object in.  This can be changed to preference.
    gluPickMatrix(x, viewportCoords[3] - y, 2, 2, viewportCoords);

    // Next, we just call our normal gluPerspective() function, exactly as we did on startup.
    // This is to multiply the perspective matrix by the pick matrix we created up above.
    //Perspective view or Orthogonal View. Multiply by current projection matrix
    if(m_bPerspective)
    {
        GLfloat fov = 60.0f;
        gluPerspective(fov, (GLdouble)width()/height(), 1, 3000);
    }
    else
        glOrtho(-1.0, +1.0, -1.0, 1.0, -1.0, 1.0);


    // Go back into our model view matrix
    glMatrixMode(GL_MODELVIEW);

    m_cylinder.drawCurveControlPoints(true);

    // If we return to our normal render mode from select mode, glRenderMode returns
    // the number of objects that were found in our specified region (specified in gluPickMatrix())
    // Return to render mode and get the number of objects found
    objectsFound = glRenderMode(GL_RENDER);

    // Put our projection matrix back to normal.
    glMatrixMode(GL_PROJECTION);

    // Stop effecting our projection matrix
    glPopMatrix();

    // Go back to our normal model view matrix
    glMatrixMode(GL_MODELVIEW);

    if (objectsFound > 0)
    {
        // 1 is the first object's minimum Z value.
        // We use an unsigned int so we don't get a warning with selectBuffer below.
        unsigned int lowestDepth = selectBuffer[1];

        // Set the selected object to the first object to start it off.
        // 3 is the first object's object ID we passed into glLoadName().
        int selectedObject = selectBuffer[3];

        // Go through all of the objects found, but start at the second one
        for(int i = 1; i < objectsFound; i++)
        {
            // Check if the current objects depth is lower than the current lowest
            // Notice we times i by 4 (4 values for each object) and add 1 for the depth.
            if(selectBuffer[(i * 4) + 1] < lowestDepth)
            {
                // Set the current lowest depth
                lowestDepth = selectBuffer[(i * 4) + 1];

                // Set the current object ID
                selectedObject = selectBuffer[(i * 4) + 3];
            }
        }

        // Return the selected object
        return selectedObject;
    }

    // We didn't click on any objects so return nothing
    return -1;
}
Ejemplo n.º 6
0
void PerspectiveGLWidget::rectangularSelection (int preX, int preY, int curX, int curY, QList<Model *> &selectedModels, QList<Vector *> &selectedVertices)
{
	GLuint selectBuffer[1024];
	glSelectBuffer(1024, selectBuffer);
	glRenderMode(GL_SELECT);
	glClear(GL_DEPTH_BUFFER_BIT);
	glInitNames();
	glPushName(0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	float xCenter = (preX + curX) / 2;
	float yCenter = (preY + curY) / 2;
	float widthOfSelection = fabs(preX - curX);
	if(widthOfSelection < 5)
		widthOfSelection = 5;
	float heightOfSelection = fabs(preY - curY);
	if(heightOfSelection < 5)
		heightOfSelection = 5;
	int viewport[4];
	glGetIntegerv(GL_VIEWPORT, viewport);
	gluPickMatrix(xCenter, viewport[3] - yCenter, widthOfSelection, heightOfSelection, viewport);
	gluPerspective(45, aspectRatio, 1.0, 1000);
	int i = 0;
	while(i != ModelManager::getInstance ()->size ())
	{
		if(ModelManager::getInstance ()->at (i)->getDrawingMode () == ObjectMode)
		{
			glLoadName(i + 1);
			Model *s = ModelManager::getInstance ()->at(i);
			ModelManager::getInstance ()->at(i)->setSelectionIdentifier(i + 1);
			s->drawObjectModeSelect();
			i++;
		}
		else if(ModelManager::getInstance ()->at (i)->getDrawingMode () == VertexMode)
		{
			int t = 0;
			int j = 0;
			while(j != ModelManager::getInstance ()->size())
			{
				int vertexCount = ModelManager::getInstance ()->at(j)->getVertexManager()->size();
				for(int k = 0; k < vertexCount; k++)
				{
					glLoadName(t + 1);
					ModelManager::getInstance ()->at(j)->getVertexManager()->at(k)->setSelectionIdentifier(t + 1);
					ModelManager::getInstance ()->at(j)->drawVertexModeSelect(k);
					t++;
				}
				j++;
			}
		}
	}
	GLint hits = glRenderMode(GL_RENDER);
	GLuint names, *ptr;
	ptr = (GLuint *)selectBuffer;
	GLuint selectedObject = 0;
	for (int i = 0; i < hits; i++)
	{
		names = *ptr++;
		ptr++;
		ptr++;
		while(names--)
		{
			selectedObject = *ptr;
			for(int k = 0 ; k < ModelManager::getInstance ()->size() ; k++)
			{
				if(ModelManager::getInstance ()->at (k)->getDrawingMode () == ObjectMode)
				{
					GLuint modelID = ModelManager::getInstance ()->at(k)->getSelectionIdentifier();
					if(modelID == selectedObject)
					{
						selectedModels.append (ModelManager::getInstance ()->at(k));
					}
				}
				else if(ModelManager::getInstance ()->at (k)->getDrawingMode () == VertexMode)
				{
					int j = 0;
					while(j != ModelManager::getInstance ()->size())
					{
						int vertexCount = ModelManager::getInstance ()->at(j)->getVertexManager()->size();
						for(int k = 0; k < vertexCount; k++)
						{
							if(selectedObject == (GLuint)ModelManager::getInstance ()->at(j)->getVertexManager()->at(k)->getID())
							{
								selectedVertices.append (ModelManager::getInstance ()->at(j)->getVertexManager()->at(k));
							}
						}
						j++;
					}
				}
				ptr++;
			}
		}
	}
}
Ejemplo n.º 7
0
unsigned int C3dView::EndSelect ( void )
{
	if (!m_bDrawing)
		return 0xffffffff;

	GLint	hits = 0;
	long	iTopName = -1;
	float	LastZ = 0.0f;
	bool	bFirstShot = true;
	long	i;
	unsigned int	j;
	GLuint	names = 0, *ptr = NULL;
	float	z1 = 0,z2 = 0;
	long	iName = 0;

	glPopMatrix();

	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	
	glFlush();
	
	// end render
	hits = glRenderMode(GL_RENDER);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective (m_fov,m_fAspect,m_xNearZ,m_xFarZ);
	glViewport (0, 0, m_iViewportX, m_iViewportY);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity ();
	
	char	msg[255];

	if (hits >0)
	{
		ptr = (GLuint *) m_uiSelectBuf;

		for (i = 0; i < hits; i++) 
		{  /* for each hit  */
			names = *ptr;
			ptr++;
			z1 = (float) *ptr/0x7fffffff;
			ptr++;
			z2 = (float) *ptr/0x7fffffff;
			ptr++;
			
			// stupid compiler bug
			sprintf(msg,"names %u f1 %f f2 %f",(unsigned int)names,z1,z2);

			if (bFirstShot)
			{
				LastZ = z1;
				bFirstShot = false;
			}
			for (j = 0; j < names; j++)
			{  /* for each name */
				iName = *ptr;
				ptr++;
			}
			if (z1 <= LastZ)
			{
				LastZ = z1;
				iTopName = iName;
			}
		}

	}
	m_bDrawing = false;
	m_bOverlayMode = false;
	m_bForcedDrawing = false;


	if (iTopName == -1)
		return 0;
	else
		return iTopName;
}
static Icon *_cairo_dock_pick_icon_on_opengl_desklet (CairoDesklet *pDesklet)
{
	GLuint selectBuf[4];
	GLint hits=0;
	GLint viewport[4];
	
	if (! gldi_gl_container_make_current (CAIRO_CONTAINER (pDesklet)))
		return NULL;
	
	glGetIntegerv (GL_VIEWPORT, viewport);
	glSelectBuffer (4, selectBuf);
	
	glRenderMode(GL_SELECT);
	glInitNames();
	glPushName(0);
	
	glMatrixMode (GL_PROJECTION);
	glPushMatrix ();
	glLoadIdentity ();
	gluPickMatrix ((GLdouble) pDesklet->container.iMouseX, (GLdouble) (viewport[3] - pDesklet->container.iMouseY), 2.0, 2.0, viewport);
	gluPerspective (60.0, 1.0*(GLfloat)pDesklet->container.iWidth/(GLfloat)pDesklet->container.iHeight, 1., 4*pDesklet->container.iHeight);
	
	glMatrixMode (GL_MODELVIEW);
	glPushMatrix ();
	glLoadIdentity ();
	
	_set_desklet_matrix (pDesklet);
	
	if (pDesklet->iLeftSurfaceOffset != 0 || pDesklet->iTopSurfaceOffset != 0 || pDesklet->iRightSurfaceOffset != 0 || pDesklet->iBottomSurfaceOffset != 0)
	{
		glTranslatef ((pDesklet->iLeftSurfaceOffset - pDesklet->iRightSurfaceOffset)/2, (pDesklet->iBottomSurfaceOffset - pDesklet->iTopSurfaceOffset)/2, 0.);
		glScalef (1. - (double)(pDesklet->iLeftSurfaceOffset + pDesklet->iRightSurfaceOffset) / pDesklet->container.iWidth,
			1. - (double)(pDesklet->iTopSurfaceOffset + pDesklet->iBottomSurfaceOffset) / pDesklet->container.iHeight,
			1.);
	}
	
	glPolygonMode (GL_FRONT, GL_FILL);
	glColor4f (1., 1., 1., 1.);
	
	pDesklet->iPickedObject = 0;
	if (pDesklet->render_bounding_box != NULL)  // surclasse la fonction du moteur de rendu.
	{
		pDesklet->render_bounding_box (pDesklet);
	}
	else if (pDesklet->pRenderer && pDesklet->pRenderer->render_bounding_box != NULL)
	{
		pDesklet->pRenderer->render_bounding_box (pDesklet);
	}
	else  // on le fait nous-memes a partir des coordonnees des icones.
	{
		glTranslatef (-pDesklet->container.iWidth/2, -pDesklet->container.iHeight/2, 0.);
		
		double x, y, w, h;
		Icon *pIcon;
		
		pIcon = pDesklet->pIcon;
		if (pIcon != NULL && pIcon->image.iTexture != 0)
		{
			w = pIcon->fWidth/2;
			h = pIcon->fHeight/2;
			x = pIcon->fDrawX + w;
			y = pDesklet->container.iHeight - pIcon->fDrawY - h;
			
			glLoadName(pIcon->image.iTexture);
			
			glBegin(GL_QUADS);
			glVertex3f(x-w, y+h, 0.);
			glVertex3f(x+w, y+h, 0.);
			glVertex3f(x+w, y-h, 0.);
			glVertex3f(x-w, y-h, 0.);
			glEnd();
		}
		
		GList *ic;
		for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
		{
			pIcon = ic->data;
			if (pIcon->image.iTexture == 0)
				continue;
			
			w = pIcon->fWidth/2;
			h = pIcon->fHeight/2;
			x = pIcon->fDrawX + w;
			y = pDesklet->container.iHeight - pIcon->fDrawY - h;
			
			glLoadName(pIcon->image.iTexture);
			
			glBegin(GL_QUADS);
			glVertex3f(x-w, y+h, 0.);
			glVertex3f(x+w, y+h, 0.);
			glVertex3f(x+w, y-h, 0.);
			glVertex3f(x-w, y-h, 0.);
			glEnd();
		}
	}
	
	glPopName();
	
	hits = glRenderMode (GL_RENDER);

	glMatrixMode (GL_PROJECTION);
	glPopMatrix ();
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix ();
	
	Icon *pFoundIcon = NULL;
	if (hits != 0)
	{
		GLuint id = selectBuf[3];
		Icon *pIcon;
		
		if (pDesklet->render_bounding_box != NULL)
		{
			pDesklet->iPickedObject = id;
			//g_print ("iPickedObject <- %d\n", id);
			pFoundIcon = pDesklet->pIcon;  // il faut mettre qqch, sinon la notification est filtree par la macro CD_APPLET_ON_CLICK_BEGIN.
		}
		else
		{
			pIcon = pDesklet->pIcon;
			if (pIcon != NULL && pIcon->image.iTexture != 0)
			{
				if (pIcon->image.iTexture == id)
				{
					pFoundIcon = pIcon;
				}
			}
			
			if (pFoundIcon == NULL)
			{
				GList *ic;
				for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
				{
					pIcon = ic->data;
					if (pIcon->image.iTexture == id)
					{
						pFoundIcon = pIcon;
						break ;
					}
				}
			}
		}
	}
	
	return pFoundIcon;
}
Ejemplo n.º 9
0
void GLwidget::mousePressEvent(QMouseEvent *ev)
{
    float posX = ev->x();
    float posy = ev->y();
    GLuint buff[64] = {0};
      GLint hits, view[4];

      /*
         This choose the buffer where store the values for the selection data
         */
      glSelectBuffer(64, buff);

      /*
         This retrieve info about the viewport
         */
      glGetIntegerv(GL_VIEWPORT, view);

      /*
         Switching in selecton mode
         */
      glRenderMode(GL_SELECT);

      /*
         Clearing the name's stack
         This stack contains all the info about the objects
         */
      glInitNames();

      /*
         Now fill the stack with one element (or glLoadName will generate an error)
         */
      glPushName(0);

      /*
         Now modify the vieving volume, restricting selection area around the cursor
         */
      glMatrixMode(GL_PROJECTION);
      glPushMatrix();
      glLoadIdentity();

      /*
         restrict the draw to an area around the cursor
         */
      gluPickMatrix(posX, posy, 1.0, 1.0, view);
      gluPerspective(60.0, this->width()/this->height(), 0.0001, 1000.0);

      /*
         Draw the objects onto the screen
         */
      glMatrixMode(GL_MODELVIEW);

      /*
         draw only the names in the stack, and fill the array
         */
      //glutSwapBuffers();
      swapBuffers();
      //gl_draw();
      paintGL();

      /*
         Do you remeber? We do pushMatrix in PROJECTION mode
         */
      glMatrixMode(GL_PROJECTION);
      glPopMatrix();

      /*
         get number of objects drawed in that area
         and return to render mode
         */
      hits = glRenderMode(GL_RENDER);
      qDebug() << hits;
      /*
         Print a list of the objects
         */
      list_hits(hits, buff);

      /*
         uncomment this to show the whole buffer
       * /
       gl_selall(hits, buff);
       */

      glMatrixMode(GL_MODELVIEW);
}
Ejemplo n.º 10
0
static void
glgdGraphComputeHoverData(glgdGraph *graph, GLdouble mx, GLdouble my)
{
    int         i, j;
    GLint       nameCount;
    GLint       hitCount;
    GLuint      selectBuf[64];
    GLuint      *ptr;
    
    if (graph->nodeHead)
    {
        glSelectBuffer(64, selectBuf);
        glRenderMode(GL_SELECT);
    
        glInitNames();
    
        glgdGraphPushAttributes();
        glgdCamBeginPick(&graph->ctrlCam, mx, my);
        glgdGraphRender(graph, GL_SELECT);
        glgdCamEnd(&graph->ctrlCam);
        glgdGraphPopAttributes();

        glFlush();
        
        hitCount = glRenderMode(GL_RENDER);
        if (hitCount > 0)
        {
            ptr = &selectBuf[0];
            for (i=0; i<hitCount; i++)
            {
                nameCount = *ptr;
                ptr++;
                glgdTrace(3, "%3d: nameCount: %d\n", i, nameCount);
                glgdTrace(3, "     zMin: %g\n", (GLdouble)*ptr/0x7fffffff);
                ptr++;
                glgdTrace(3, "     zMax: %g\n", (GLdouble)*ptr/0x7fffffff);
                ptr++;

                if (*ptr == GLGDGRAPH_NODENAME)
                {
                    graph->hoverNode = glgdNodeByID(graph->nodeHead, ptr[1]);
                    graph->hoverLink = NULL;
                }
                else if (*ptr == GLGDGRAPH_LINKNAME)
                {
                    graph->hoverLink = glgdGraphLinkByNdx(graph, ptr[1]);
                    if (nameCount > 2)
                    {
                        graph->hoverNode = glgdNodeByID(graph->nodeHead, ptr[2]);
                    }
                }
                
                if (s_verbosity >= 3)
                {
                    for (j=0; j<nameCount; j++)
                    {
                        glgdTrace(3, "  name[%1d]: %d\n", j, ptr[j]);
                    }
                }
                
                ptr += nameCount;
            }
        }
        else
        {
            graph->hoverNode = NULL;
            graph->hoverLink = NULL;
        }
    }
}
Ejemplo n.º 11
0
/* picking */
int pick(int x, int y)
{

    GLuint hits = 0;
    GLint viewport[4];
    GLuint selectBuf[512];
    GLuint *ptr;
    GLuint i,j;
    GLint  k;
    GLint picked = -1;
	real mv_matrix[16];

    GLuint names, z1, z2, zmax;
    
    glMatrixMode(GL_MODELVIEW);
    glGetDoublev( GL_MODELVIEW_MATRIX, mv_matrix);
        
    glGetIntegerv( GL_VIEWPORT, viewport);
    glSelectBuffer(sizeof(selectBuf)/sizeof(selectBuf[0]), selectBuf);
    
    glRenderMode(GL_SELECT);
    
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluPickMatrix( (GLdouble) x, (GLdouble) (viewport[3] - y), 2.0,2.0,
    			viewport);
    glOrtho(ViewCenter[0]-ViewSize,ViewCenter[0]+ViewSize, 
		    ViewCenter[1]-ViewSize,ViewCenter[1]+ViewSize, 
            -3*ViewDepth*ViewSize, 3*ViewDepth*ViewSize);

    glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
    glLoadMatrixd(mv_matrix);
	glTranslated(-ObjectCenter[0], -ObjectCenter[1], -ObjectCenter[2]);

    glInitNames();
    glPushName((unsigned) -1);

    for (k= 1; k <=patch_num  ; k++)
    {
        glLoadName(k);
//		glCallList(patchList(k));
    }
    
    glPopMatrix();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    hits = glRenderMode(GL_RENDER);
    //printf("hits %d \n", hits);

    ptr = selectBuf;

    for (i = 0; i < hits; i++) { /*  for each hit  */
      names = *ptr;

      if(names !=1 ){
          //printf("something wrong?\n"); 
          break;  // wierd case, openGL bug? 
      }
      
      ptr++;
      z1 = *ptr;
      ptr++;
      z2 = *ptr;
      ptr++;

      // printf("names %d \n", names);
      
      if( i ==0 || z2 > zmax )
      {
          //printf("z: %ud \n", z2);
          zmax = z2;

        
          for (j = 0; j < names; j++) {     /*  for each name */
             if ( (*ptr <= (GLuint) patch_num) && (*ptr >= 1) )
             {
                picked = *ptr;
//                return picked;
             }
             ptr++;
          }
       }
    }
   
    return picked;
}
Ejemplo n.º 12
0
// `使用OpenGL來繪圖`
void RenderFrameOpenGL(void)
{
	// `取得視窗大小`
	int w, h;
	GutGetWindowSize(w, h);
	// `清除畫面`
	glClearColor(0.4f, 0.4f, 0.4f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// `在螢幕上畫出行星運動`
	RenderSolarSystemOpenGL(false);

	/* 
	`啟動Selection Buffer, 硬體會試著去重畫一次3D物件,` 
	`但不會更新畫面, 只會記錄下落在畫面中某個范圍內所有3D物件.`
	*/
	int x,y,buttons[3];
	GutGetMouseState(x, y, buttons);
	if ( buttons[0] )
	{
		GLint viewport[4];

		glSelectBuffer(BUFSIZE,selectBuf);
		glRenderMode(GL_SELECT);
		glInitNames();

		glGetIntegerv(GL_VIEWPORT,viewport);

		glMatrixMode(GL_PROJECTION);
		glPushMatrix();
		glLoadIdentity();
		// `設定Selection Buffer的檢查范圍`
		gluPickMatrix(x, viewport[3]-y, 3, 3, viewport);
		float fRatio = (viewport[2]+0.0) / viewport[3];
		glMultMatrixf( (float *)&g_projection_matrix );
		// `在Selection Buffer中畫出3D物件`
		RenderSolarSystemOpenGL(true);
		int hits = glRenderMode(GL_RENDER);

		GLuint *ptr = selectBuf;
		GLuint Zmin = 0xffffffff;
		GLuint SelectedObject = 0;
		// `找出檢查范圍中, 距離鏡頭最近的物體.`
		for ( int i=0; i<hits; i++, ptr+=4 )
		{
			if ( ptr[1] < Zmin )
			{
				Zmin = ptr[1];
				SelectedObject = ptr[3];
			}
		}

		switch(SelectedObject)
		{
		default:
		case 0:
			printf("Nothing\r");
			break;
		case 1:
			printf("Sun    \r");
			break;
		case 2:
			printf("Earth  \r");
			break;
		}

		glMatrixMode(GL_PROJECTION);
		glPopMatrix();
	}

	// `把背景backbuffer的畫面呈現出來`
	GutSwapBuffersOpenGL();
}
Ejemplo n.º 13
0
void MakeSelection(int nChoice)
	{
	// Space for the feedback buffer
	GLfloat feedBackBuff[FEED_BUFF_SIZE];

	// Storeage for counters, etc.
	int size,i,j,count;

	// Initial minimum and maximum values
	bRect.right = bRect.bottom = -999999.0f;
	bRect.left = bRect.top =  999999.0f;

	// Set the feedback buffer
	glFeedbackBuffer(FEED_BUFF_SIZE,GL_2D, feedBackBuff);

	// Enter feedback mode
	glRenderMode(GL_FEEDBACK);

	// Redraw the scene
	DrawObjects();

	// Leave feedback mode
	size = glRenderMode(GL_RENDER);

	// Parse the feedback buffer and get the
	// min and max X and Y window coordinates
	i = 0;
	while(i < size)
		{
		// Search for appropriate token
		if(feedBackBuff[i] == GL_PASS_THROUGH_TOKEN)
			if(feedBackBuff[i+1] == (GLfloat)nChoice)
			{
			i+= 2;
			// Loop until next token is reached
			while(i < size && feedBackBuff[i] != GL_PASS_THROUGH_TOKEN)
				{
				// Just get the polygons
				if(feedBackBuff[i] == GL_POLYGON_TOKEN)
					{
					// Get all the values for this polygon
					count = (int)feedBackBuff[++i]; // How many vertices
					i++;

					for(j = 0; j < count; j++)	// Loop for each vertex
						{
						// Min and Max X
						if(feedBackBuff[i] > bRect.right)
							bRect.right = feedBackBuff[i];

						if(feedBackBuff[i] < bRect.left)
							bRect.left = feedBackBuff[i];
						i++;

						// Min and Max Y
						if(feedBackBuff[i] > bRect.bottom)
							bRect.bottom = feedBackBuff[i];

						if(feedBackBuff[i] < bRect.top)
							bRect.top = feedBackBuff[i];
						i++;
						}
					}
				else
					i++;	// Get next index and keep looking
				}
			break;
			}
		i++;
		}
	}
Ejemplo n.º 14
0
guint Render::find_object_at(gdouble x, gdouble y)
{
  // Render everything in selection mode
  GdkGLContext *glcontext = gtk_widget_get_gl_context (get_widget());
  GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (get_widget());

  const GLsizei BUFSIZE = 256;
  GLuint select_buffer[BUFSIZE];

  if (!gldrawable || !gdk_gl_drawable_gl_begin (gldrawable, glcontext))
    return 0;

  glSelectBuffer(BUFSIZE, select_buffer);
  (void)glRenderMode(GL_SELECT);

  GLint viewport[4];

  glMatrixMode (GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity ();
  glGetIntegerv(GL_VIEWPORT,viewport);
  gluPickMatrix(x,viewport[3]-y,2,2,viewport); // 2x2 pixels around the cursor
  gluPerspective (45.0f, (float)get_width()/(float)get_height(),1.0f, 1000000.0f);
  glMatrixMode (GL_MODELVIEW);
  glInitNames();
  glPushName(0);
  glLoadIdentity ();

  glTranslatef (0.0, 0.0, -2.0 * m_zoom);
  glMultMatrixf (m_transform.M);
  CenterView();
  glPushMatrix();
  glColor3f(0.75f,0.75f,1.0f);

  glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);

  Gtk::TreeModel::iterator no_object;
  m_view->Draw (no_object);

  // restor projection and model matrices
  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_MODELVIEW);
  glPopMatrix();
  // restore rendering mode
  GLint hits = glRenderMode(GL_RENDER);

  if (gdk_gl_drawable_is_double_buffered(gldrawable))
    gdk_gl_drawable_swap_buffers (gldrawable);
  else
    glFlush();

  gdk_gl_drawable_gl_end (gldrawable);

  // Process the selection hits
  GLuint *ptr = select_buffer;
  GLuint name = 0;
  GLuint minZ = G_MAXUINT;

  for (GLint i = 0; i < hits; i++) { /*  for each hit  */
     GLuint n = *ptr++; // number of hits in this record
     GLuint z1 = *ptr++; // Minimum Z in the hit record
     ptr++; // Skip Maximum Z coord
     if (n > 0 && z1 < minZ) {
       // Found an object further forward.
       name = *ptr;
       minZ = z1;
     }
     ptr += n; // Skip n name records;
  }

  return name;
}
Ejemplo n.º 15
0
bool Viewer::on_button_press_event(GdkEventButton* event)
{
  DEBUG_MSG( "Stub: Button " << event->button << " pressed" );


  m_lastMouse = Point2D(event->x, event->y);

  // pick here
  if (m_mode == JOINTS && event->button == 1) {

    GLuint buffer[512];
    GLint viewport[4];
    glSelectBuffer (512, buffer);

    // don't actually draw
    glRenderMode(GL_SELECT);
    glInitNames();  //init the name buffer

    GLint hits;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();


    //glViewport(0, 0, get_width(), get_height
    glGetIntegerv(GL_VIEWPORT, viewport);
    for (int i = 0; i < 4; i++) {

      DEBUG_MSG("Viewport[i]: " << viewport[i]);
    }

    gluPickMatrix(event->x, viewport[3] - event->y, 1, 1, viewport);
    gluPerspective(40.0, (GLfloat)get_width()/(GLfloat)get_height(), 0.1, 1000.0);

  // change to model view for drawing
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glPushMatrix();

    //Matrix4x4 daT = translation(Vector3D(5.0, 0.0, 0.0));
    //glMultMatrixd(daT.transpose().begin());

    // gl use column order matrix, m4x4 is row order
    Matrix4x4 trackballM = m_trackballTranslation * m_trackballRotation;
    glMultMatrixd(trackballM.transpose().begin());

      // draw model
    m_root->walk_gl(true);

    glPopMatrix();

    hits = glRenderMode(GL_RENDER);

    DEBUG_MSG("picked: " << hits << "==========================");

    //parse the hits
    int c = 0;  // buffer counter
    for (int h = 0; h < hits; h++) {
      int qStack = buffer[c++];
      int minZ = buffer[c++];
      int maxZ = buffer[c++];
      DEBUG_MSG("HIT(" << h << ")" << qStack << " (" << minZ << "," << maxZ << ")");
      for (int q = 0; q < qStack; q++) {
        int id = buffer[c++];
        DEBUG_MSG("\tname " << id);

        SceneNode *selNode = m_root->find(id);
        if (selNode == NULL) {
                  *(int*)0=0;
                  DEBUG_MSG("IMPOSSIBLE");
                  exit(-1);
        }

        // check if selNode is selectable (has a joint parent)
        if (selNode->jointParent()) {

          bool selected = selNode->toggleSelected();
          if (selected) {
            m_selected.push_back(selNode);
          }
          else {
            m_selected.remove(selNode);
          }
        }
      }

    }

    // select the primitives if they have joint owners
    // when dragging, move the joints of the parents

    // able to get GemeotryNode from id
      // tree or global arraylist

    // get parent from child
  }

  invalidate();
  return true;
}
Ejemplo n.º 16
0
void GLWidget::processFindingObject(double p_xPos, double p_yPos)
{
	int view[4];
	uint selectionBuffer[32] = {0};
	int numberOfSelectedObjects = 0;

	// For selected objects
	glSelectBuffer(32, selectionBuffer);
	glGetIntegerv(GL_VIEWPORT, view);
	glRenderMode(GL_SELECT);

	// Clearing object names for identifying objects
	glInitNames();
 	glPushName(0);

	// Backup projection matrix in order restore it after view restriction around cursor area
	glMatrixMode(GL_PROJECTION);
 	glPushMatrix();
	glLoadIdentity();
 
 	// Restrict the draw to an area around the cursor
	gluPickMatrix(p_xPos, p_yPos, 10.0, 10.0, view);
    gluPerspective(30.0, 1.0, 1.0, 10000.0); 

	// Redraw with restricted view area
	glMatrixMode(GL_MODELVIEW);
	m_mapRenderer.setSelectionMode();
	m_mapRenderer.render(this);

	// Restore projection matrix
	glMatrixMode(GL_PROJECTION);
 	glPopMatrix();

	numberOfSelectedObjects = glRenderMode(GL_RENDER);
	glMatrixMode(GL_MODELVIEW);

    std::vector<int> selectedObjects; 
	if(numberOfSelectedObjects > 0) {
		Hit* pHitArray = reinterpret_cast<Hit*>(selectionBuffer);
	    for(int i = 0; i < numberOfSelectedObjects; i++) {
			if(m_mapRenderer.getTurnMapId() == pHitArray[i].id && m_moveMap) {
				m_turnMap = true;
				return;
			}
			selectedObjects.push_back(pHitArray[i].id);
		}
	}
	else {
		selectedObjects.push_back(0);
	}

	if(m_moveMap) {
		return;
	}
	m_mapRenderer.selectObjects(selectedObjects);
	updateGL();

	int selectionNumber = selectedObjects.front();
	if(0 != selectionNumber && m_mapRenderer.getTurnMapId() != selectionNumber) {
		showPlaceDetailsWidget(selectionNumber);
	}
}
Ejemplo n.º 17
0
void PerspectiveGLWidget::pointSelection (int x, int y, QList<Model *> &selectedModels, QList<Vector *> &selectedVertices)
{
	GLuint selectBuffer[1024];
	glSelectBuffer(1024, selectBuffer);
	glRenderMode(GL_SELECT);
	glClear(GL_DEPTH_BUFFER_BIT);
	glInitNames();
	glPushName(0);
	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ();
	int viewport[4];
	glGetIntegerv(GL_VIEWPORT, viewport);
	gluPickMatrix(x, viewport[3] - y, 10.0, 10.0, viewport);
	gluPerspective(45, aspectRatio, 1.0, 1000);
	int i = 0;
	while(i != ModelManager::getInstance ()->size ())
	{
		if(ModelManager::getInstance ()->at (i)->getDrawingMode () == ObjectMode)
		{
			glLoadName(i + 1);
			Model *s = ModelManager::getInstance ()->at(i);
			ModelManager::getInstance ()->at(i)->setSelectionIdentifier(i + 1);
			s->drawObjectModeSelect();
			i++;
		}
		else if(ModelManager::getInstance ()->at (i)->getDrawingMode () == VertexMode)
		{
			int i = 0;
			int j = 0;
			while(j != ModelManager::getInstance ()->size())
			{
				int vertexCount = ModelManager::getInstance ()->at(j)->getVertexManager()->size();
				for(int k = 0; k < vertexCount; k++)
				{
					glLoadName(i + 1);
					ModelManager::getInstance ()->at(j)->getVertexManager()->at(k)->setSelectionIdentifier(i + 1);
					ModelManager::getInstance ()->at(j)->drawVertexModeSelect(k);
					i++;
				}
				j++;
			}
		}
	}
	GLint hits = glRenderMode(GL_RENDER);
	GLuint names, *ptr;
	ptr = (GLuint *)selectBuffer;
	GLuint selectedObject = 0;
	for (int i = 0; i < hits; i++)
	{
		names = *ptr++;
		ptr++;
		ptr++;
		while(names--)
		{
			selectedObject = *ptr;
			ptr++;
		}
	}
	for(int k = 0 ; k < ModelManager::getInstance ()->size() ; k++)
	{
		if(ModelManager::getInstance ()->at (k)->getDrawingMode () == ObjectMode)
		{
			GLuint modelID = ModelManager::getInstance ()->at(k)->getSelectionIdentifier();
			if(modelID == selectedObject)
			{
				selectedModels.append (ModelManager::getInstance ()->at(k));
			}
		}
		else if(ModelManager::getInstance ()->at (i)->getDrawingMode () == VertexMode)
		{
			int j = 0;
			while(j != ModelManager::getInstance ()->size())
			{
				int vertexCount = ModelManager::getInstance ()->at(j)->getVertexManager()->size();
				for(int k = 0; k < vertexCount; k++)
				{
					if(selectedObject == (GLuint)ModelManager::getInstance ()->at(j)->getVertexManager()->at(k)->getID())
					{
						selectedVertices.append (ModelManager::getInstance ()->at(j)->getVertexManager()->at(k));
					}
				}
				j++;
			}
		}
	}
}
Ejemplo n.º 18
0
// Select
void bwindow_pick(BWindow self){
    static GLuint selectionBuffer[256];

    GLuint *ptr, *selection, num_obj, z1,z2,z;
    GLint hits;
    int num, i,j;

    raster_hit =0;
    current_window = self;
    draw_status = SELECT;

    self->event.pos.y = self->height - self->event.pos.y;
    self->event.dpos.y *=-1;

    pick_dx = self->event.pos.x - pick_x;
    pick_dy = self->event.pos.y - pick_y;
    
    pick_x = self->event.pos.x;
    pick_y = self->event.pos.y;
    
    // initialize selection buffer
    glSelectBuffer(256,selectionBuffer);

    //--------------------------------------------------------------------------------------------
    glViewport(0,0,self->width,self->height);
    current_viewport[0] = 0;
    current_viewport[1] = 0;
    current_viewport[2] = self->width;
    current_viewport[3] = self->height;

    //--------------------------------------------------------------------------------------------

    /*
        * Hit stack looks like this:
        *
        * num_obj (GLuint)- number of objects on stack
        * z1 (GLuint) - value of closest point in hit
        * z2 (GLuint) - value of farthest point in hit
        * first object in hit  - this is the id (or in this case pointer) of the first object in hit
        *  .
        *  .
        * n  object in hit  - this is the id (or in this case pointer) of the n object in hit
        */

    ptr = selectionBuffer;
    num_obj = z1 = z2 = z=0;
    selection=NULL;

    glRenderMode(GL_SELECT);
    glInitNames();

    // iterate window's items and draw them
    im_draw( self->items);

    hits = glRenderMode(GL_RENDER); //number of hit stacks

    if (hits){

        // initialize values for first hit
        num_obj = num = *ptr++;  // number of objects in stack
        z = z1 =  *ptr++;  // min depth of hit
        z2 =  *ptr++;  // max depth of hit
        selection = ptr; // selection remembers closest hit

        // if there is more than one hit selection will be the one with the nearest point
        for (i = 1; i<hits ; i++){
            ptr+=num; // increment ahead to next hit
            num = *ptr++;
            z1 =  *ptr++;
            z2 =  *ptr++;

            if (z1 < z){
                selection = ptr;
                z = z1;
                num_obj=num;
            }
        }

        // num is the number of hits in this stack
        // j = 0 is the view
        Layer lay  = NULL;
        Link child = NULL;
        Binding binding = NULL;

        view_transform(current_view);
        for (j = 0 ; j< num_obj ; j++){
            child=(Link) index_get(bound_layers, *selection++);
            lay = child->value.vptr;
            layer_transform(child->value.vptr);
            
            binding = lay->bindings;
            while(binding){
                if(     ((binding->event.state & current_window->event.state) == binding->event.state) &&
                        (binding->event.key == current_window->event.key))  
                {
                    callback(child,binding->callback);
                }

                binding = binding->next;
            }
        }
    }
    
    if (self->update) bwindow_paint(self);
}
Ejemplo n.º 19
0
/* Mouse hit detection
 */
static void
find_mouse_gear (ModeInfo *mi)
{
  pinion_configuration *pp = &pps[MI_SCREEN(mi)];
  int screen_width = MI_WIDTH (mi);
  int screen_height = MI_HEIGHT (mi);
  GLfloat h = (GLfloat) screen_height / (GLfloat) screen_width;
  int x, y;
  int hits;

  pp->mouse_gear_id = 0;

  /* Poll mouse position */
  {
    Window r, c;
    int rx, ry;
    unsigned int m;
    XQueryPointer (MI_DISPLAY (mi), MI_WINDOW (mi),
                   &r, &c, &rx, &ry, &x, &y, &m);
  }

  if (x < 0 || y < 0 || x > screen_width || y > screen_height)
    return;  /* out of window */

  /* Run OpenGL hit detector */
  {
    GLint vp[4];
    GLuint selbuf[512];

    glSelectBuffer (sizeof(selbuf), selbuf);  /* set up "select" mode */
    glRenderMode (GL_SELECT);
    glMatrixMode (GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glGetIntegerv (GL_VIEWPORT, vp);         /* save old vp */
    gluPickMatrix (x, vp[3]-y, 5, 5, vp);
    gluPerspective (30.0, 1/h, 1.0, 100.0);  /* must match reshape_pinion() */
    glMatrixMode (GL_MODELVIEW);

    draw_gears (mi);                         /* render into "select" buffer */

    glMatrixMode (GL_PROJECTION);            /* restore old vp */
    glPopMatrix ();
    glMatrixMode (GL_MODELVIEW);
    glFlush();
    hits = glRenderMode (GL_RENDER);         /* done selecting */

    if (hits > 0)
      {
        int i;
        GLuint name_count = 0;
        GLuint *p = (GLuint *) selbuf;
        GLuint *pnames = 0;
        GLuint min_z = ~0;

        for (i = 0; i < hits; i++)
          {     
            int names = *p++;
            if (*p < min_z)                  /* find match closest to screen */
              {
                name_count = names;
                min_z = *p;
                pnames = p+2;
              }
            p += names+2;
          }

        if (name_count > 0)                  /* take first hit */
          pp->mouse_gear_id = pnames[0];
      }
  }
}
Ejemplo n.º 20
0
gint buttonpress(GtkWidget *glarea, GdkEventButton *event) {
  int x = (int) event->x;
  int y = (int) event->y;
  GLuint *buffer;
  GLint hits;
  GLint viewport[4];
  switch(event->button) {
    case 1:
      // button 1, do picking
      glGetIntegerv(GL_VIEWPORT, viewport);
      buffer = new GLuint[doc->world.list.size() * 4];
      glSelectBuffer(doc->world.list.size() * 4, buffer);
      glRenderMode(GL_SELECT);
      glInitNames();
      glPushName(0);
      glMatrixMode(GL_PROJECTION);
      glPushMatrix();
      glLoadIdentity();
      gluPickMatrix((double) x, (double) (viewport[3] - y), 1.0, 1.0, viewport);
      gluPerspective(45.0, (float) (viewport[2] - viewport[0]) / (float) (viewport[3] - viewport[1]), 3.0, 2500.0);
      glMatrixMode(GL_MODELVIEW);
      doc->world.render_targets();
      glMatrixMode(GL_PROJECTION);
      glPopMatrix();
      glMatrixMode(GL_MODELVIEW);
      hits = glRenderMode(GL_RENDER);
      if(hits > 0) {
	int choose = buffer[3];
	int depth = buffer[1];
	for(int i = 0; i < hits; i++) {
	  if(buffer[i * 4 + 1] < depth) {
	    choose = buffer[i * 4 + 3];
	    depth = buffer[i * 4 + 1];
	  }
	}
	choose--;
	mainwin->select(choose);
      } else {
	mainwin->unselectAll();
      }
      delete buffer;
      break;
    case 2:
      // button 2, pick and center
      glGetIntegerv(GL_VIEWPORT, viewport);
      buffer = new GLuint[doc->world.list.size() * 4];
      glSelectBuffer(doc->world.list.size() * 4, buffer);
      glRenderMode(GL_SELECT);
      glInitNames();
      glPushName(0);
      glMatrixMode(GL_PROJECTION);
      glPushMatrix();
      glLoadIdentity();
      gluPickMatrix((double) x, (double) (viewport[3] - y), 1.0, 1.0, viewport);
      gluPerspective(45.0, (float) (viewport[2] - viewport[0]) / (float) (viewport[3] - viewport[1]), 3.0, 2500.0);
      glMatrixMode(GL_MODELVIEW);
      doc->world.render_targets();
      glMatrixMode(GL_PROJECTION);
      glPopMatrix();
      glMatrixMode(GL_MODELVIEW);
      hits = glRenderMode(GL_RENDER);
      if(hits > 0) {
	int choose = buffer[3];
	int depth = buffer[1];
	for(int i = 0; i < hits; i++) {
	  if(buffer[i * 4 + 1] < depth) {
	    choose = buffer[i * 4 + 3];
	    depth = buffer[i * 4 + 1];
	  }
	}
	choose--;
	if(doc->world.list[choose].type != LINK) {
	  doc->camera.fx = doc->world.list[choose].obj->get_px();
	  doc->camera.fy = doc->world.list[choose].obj->get_py();
	  doc->camera.fz = doc->world.list[choose].obj->get_pz();
	  doc->camera.fcamera = true;
	}
	mainwin->select(choose);
      } else {
	doc->camera.fx = 0;
	doc->camera.fy = 0;
	doc->camera.fz = 0;
	doc->camera.fcamera = true;
	mainwin->unselectAll();
      }
      delete buffer;
      break;
    case 3:
      // button 3, start roaming
      mainwin->mouse_x = event->x_root;
      mainwin->mouse_y = event->y_root;
      break;
    case 4:
      // button 4, mouse wheel up, zoom in
      break;
    case 5:
      // button 5, mouse wheel down, zoom out
      break;
  }
  return TRUE;
}
Ejemplo n.º 21
0
void get_light_under_mouse()
{
	//ok, first of all, let's see what objects we have in range...
	int i, count, x, y, dist1, dist2, hits;
	GLint viewport[4];
	GLuint *buffer, z_coordinate;
	double matrix[16];

	selected_light = -1;
	x = (int)-camera_x;
	y = (int)-camera_y;

	count = 0;
	for (i = 0; i < MAX_LIGHTS; i++)
	{
		if (lights_list[i])
		{
			dist1 = x - (int)lights_list[i]->pos_x;
			dist2 = y - (int)lights_list[i]->pos_y;
			if (dist1 * dist1 + dist2 * dist2 <= ((40 * 40) * (zoom_level / 15.75f)))
			{
				count++;
			}
		}
	}

	if (count == 0)
	{
		return;
	}
	count++;
	count *= 4;
	glGetIntegerv(GL_VIEWPORT, viewport);
	buffer = malloc(count * sizeof(GLuint));
	glSelectBuffer(count, buffer);

	glGetDoublev(GL_PROJECTION_MATRIX, matrix);

	glRenderMode(GL_SELECT);
	glInitNames();
	glPushName(0);
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluPickMatrix(mouse_x, window_height-mouse_y, 1.0, 1.0, viewport);
	glMultMatrixd(matrix);
	glMatrixMode(GL_MODELVIEW);

	glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);

	glPushMatrix();
	glLoadIdentity();					// Reset The Matrix
	Move();

	for (i = 0; i < MAX_LIGHTS; i++)
	{
		if (lights_list[i])
		{
			dist1 = x - (int)lights_list[i]->pos_x;
			dist2 = y - (int)lights_list[i]->pos_y;
			if (dist1 * dist1 + dist2 * dist2 <= ((40 * 40) * (zoom_level / 15.75f)))
			{
				glLoadName(i);
				draw_light_source(lights_list[i]);
			}
		}
	}

	glPopMatrix();
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);

	hits = glRenderMode(GL_RENDER);
	z_coordinate = 0xFFFFFFFF;
	for (i = 0; i < hits; i++)
	{
		if (buffer[(i * 4) + 1] < z_coordinate)
		{
			selected_light = buffer[(i*4)+3];
			z_coordinate = buffer[(i*4)+1];
		}
	}
	free(buffer);

}
Ejemplo n.º 22
0
Archivo: zpr.c Proyecto: sveinfid/Antix
static void
zprPick(GLdouble x, GLdouble y,GLdouble delX, GLdouble delY)
{
   GLuint buffer[1024];
   const int bufferSize = sizeof(buffer)/sizeof(GLuint);

   GLint    viewport[4];
   GLdouble projection[16];

   GLint hits;
   GLint i,j,k;

   GLint  min  = -1;
   GLuint minZ = -1;

   glSelectBuffer(bufferSize,buffer);              /* Selection buffer for hit records */
   glRenderMode(GL_SELECT);                        /* OpenGL selection mode            */
   glInitNames();                                  /* Clear OpenGL name stack          */

   glMatrixMode(GL_PROJECTION);
   glPushMatrix();                                 /* Push current projection matrix   */
   glGetIntegerv(GL_VIEWPORT,viewport);            /* Get the current viewport size    */
   glGetDoublev(GL_PROJECTION_MATRIX,projection);  /* Get the projection matrix        */
   glLoadIdentity();                               /* Reset the projection matrix      */
   gluPickMatrix(x,y,delX,delY,viewport);          /* Set the picking matrix           */
   glMultMatrixd(projection);                      /* Apply projection matrix          */

   glMatrixMode(GL_MODELVIEW);

   if (selection)
      selection();                                 /* Draw the scene in selection mode */

   hits = glRenderMode(GL_RENDER);                 /* Return to normal rendering mode  */

   /* Diagnostic output to stdout */

   #ifndef NDEBUG
   if (hits!=0)
   {
      printf("hits = %d\n",hits);

      for (i=0,j=0; i<hits; i++)
      {
         printf("\tsize = %u, min = %u, max = %u : ",buffer[j],buffer[j+1],buffer[j+2]);
         for (k=0; k < (GLint) buffer[j]; k++)
            printf("%u ",buffer[j+3+k]);
         printf("\n");

         j += 3 + buffer[j];
      }
   }
   #endif

   /* Determine the nearest hit */

   if (hits)
   {
      for (i=0,j=0; i<hits; i++)
      {
         if (buffer[j+1]<minZ)
         {
            /* If name stack is empty, return -1                */
            /* If name stack is not empty, return top-most name */

            if (buffer[j]==0)
               min = -1;
            else
               min  = buffer[j+2+buffer[j]];

            minZ = buffer[j+1];
         }

         j += buffer[j] + 3;
      }
   }

   glMatrixMode(GL_PROJECTION);
   glPopMatrix();                         /* Restore projection matrix           */
   glMatrixMode(GL_MODELVIEW);

   if (pick)
      pick(min);                          /* Pass pick event back to application */
}
Ejemplo n.º 23
0
int RetrieveObjectID(int x, int y)
{
    int objectsFound = 0;								// This will hold the amount of objects clicked
    int	viewportCoords[4] = {0};						// We need an array to hold our view port coordinates

    // This will hold the ID's of the objects we click on.
    // We make it an arbitrary number of 32 because openGL also stores other information
    // that we don't care about.  There is about 4 slots of info for every object ID taken up.
    unsigned int selectBuffer[32] = {0};

    // glSelectBuffer is what we register our selection buffer with.  The first parameter
    // is the size of our array.  The next parameter is the buffer to store the information found.
    // More information on the information that will be stored in selectBuffer is further below.

    glSelectBuffer(32, selectBuffer);					// Setup our selection buffer to accept object ID's

    // This function returns information about many things in OpenGL.  We pass in GL_VIEWPORT
    // to get the view port coordinates.  It saves it like a RECT with {top, left, bottom, right}

    glGetIntegerv(GL_VIEWPORT, viewportCoords);			// Get the current view port coordinates

    // Now we want to get out of our GL_MODELVIEW matrix and start effecting our
    // GL_PROJECTION matrix.  This allows us to check our X and Y coords against 3D space.

    glMatrixMode(GL_PROJECTION);						// We want to now effect our projection matrix

    glPushMatrix();										// We push on a new matrix so we don't effect our 3D projection

    // This makes it so it doesn't change the frame buffer if we render into it, instead,
    // a record of the names of primitives that would have been drawn if the render mode was
    // GL_RENDER are now stored in the selection array (selectBuffer).

    glRenderMode(GL_SELECT);						// Allows us to render the objects, but not change the frame buffer

    glLoadIdentity();								// Reset our projection matrix

    // gluPickMatrix allows us to create a projection matrix that is around our
    // cursor.  This basically only allows rendering in the region that we specify.
    // If an object is rendered into that region, then it saves that objects ID for us (The magic).
    // The first 2 parameters are the X and Y position to start from, then the next 2
    // are the width and height of the region from the starting point.  The last parameter is
    // of course our view port coordinates.  You will notice we subtract "y" from the
    // BOTTOM view port coordinate.  We do this to flip the Y coordinates around.  The 0 y
    // coordinate starts from the bottom, which is opposite to window's coordinates.
    // We also give a 2 by 2 region to look for an object in.  This can be changed to preference.

    gluPickMatrix(x, viewportCoords[3] - y, 2, 2, viewportCoords);

    // Next, we just call our normal gluPerspective() function, exactly as we did on startup.
    // This is to multiply the perspective matrix by the pick matrix we created up above.

    gluPerspective(45.0f,(float)g_rRect.right/(float)g_rRect.bottom,0.1f,150.0f);

    glMatrixMode(GL_MODELVIEW);						// Go back into our model view matrix

    RenderScene();									// Now we render into our selective mode to pinpoint clicked objects

    // If we return to our normal render mode from select mode, glRenderMode returns
    // the number of objects that were found in our specified region (specified in gluPickMatrix())

    objectsFound = glRenderMode(GL_RENDER);			// Return to render mode and get the number of objects found

    glMatrixMode(GL_PROJECTION);					// Put our projection matrix back to normal.
    glPopMatrix();										// Stop effecting our projection matrix

    glMatrixMode(GL_MODELVIEW);							// Go back to our normal model view matrix

    // PHEW!  That was some stuff confusing stuff.  Now we are out of the clear and should have
    // an ID of the object we clicked on.  objectsFound should be at least 1 if we found an object.

    if (objectsFound > 0)
    {
        // If we found more than one object, we need to check the depth values
        // of all the objects found.  The object with the LEAST depth value is
        // the closest object that we clicked on.  Depending on what you are doing,
        // you might want ALL the objects that you clicked on (if some objects were
        // behind the closest one), but for this tutorial we just care about the one
        // in front.  So, how do we get the depth value?  Well, The selectionBuffer
        // holds it.  For every object there is 4 values.  The first value is
        // "the number of names in the name stack at the time of the event, followed
        // by the minimum and maximum depth values of all vertices that hit since the
        // previous event, then followed by the name stack contents, bottom name first." - MSDN
        // The only ones we care about are the minimum depth value (the second value) and
        // the object ID that was passed into glLoadName() (This is the fourth value).
        // So, [0 - 3] is the first object's data, [4 - 7] is the second object's data, etc...
        // Be carefull though, because if you are displaying 2D text in front, it will
        // always find that as the lowest object.  So make sure you disable text when
        // rendering the screen for the object test.  I use a flag for RenderScene().
        // So, lets get the object with the lowest depth!

        // Set the lowest depth to the first object to start it off.
        // 1 is the first object's minimum Z value.
        // We use an unsigned int so we don't get a warning with selectBuffer below.
        unsigned int lowestDepth = selectBuffer[1];

        // Set the selected object to the first object to start it off.
        // 3 is the first object's object ID we passed into glLoadName().
        int selectedObject = selectBuffer[3];

        // Go through all of the objects found, but start at the second one
        for(int i = 1; i < objectsFound; i++)
        {
            // Check if the current objects depth is lower than the current lowest
            // Notice we times i by 4 (4 values for each object) and add 1 for the depth.
            if(selectBuffer[(i * 4) + 1] < lowestDepth)
            {
                // Set the current lowest depth
                lowestDepth = selectBuffer[(i * 4) + 1];

                // Set the current object ID
                selectedObject = selectBuffer[(i * 4) + 3];
            }
        }

        // Return the selected object
        return selectedObject;
    }

    // We didn't click on any objects so return 0
    return 0;
}
Ejemplo n.º 24
0
void Selection(void)											// This Is Where Selection Is Done
{
	GLuint	buffer[512];										// Set Up A Selection Buffer
	GLint	hits;												// The Number Of Objects That We Selected

	if (game)													// Is Game Over?
		return;													// If So, Don't Bother Checking For Hits
	
	PlaySound("data/shot.wav",NULL,SND_ASYNC);					// Play Gun Shot Sound

	// The Size Of The Viewport. [0] Is <x>, [1] Is <y>, [2] Is <length>, [3] Is <width>
	GLint	viewport[4];

	// This Sets The Array <viewport> To The Size And Location Of The Screen Relative To The Window
	glGetIntegerv(GL_VIEWPORT, viewport);
	glSelectBuffer(512, buffer);								// Tell OpenGL To Use Our Array For Selection

	// Puts OpenGL In Selection Mode. Nothing Will Be Drawn.  Object ID's and Extents Are Stored In The Buffer.
	(void) glRenderMode(GL_SELECT);

	glInitNames();												// Initializes The Name Stack
	glPushName(0);												// Push 0 (At Least One Entry) Onto The Stack

	glMatrixMode(GL_PROJECTION);								// Selects The Projection Matrix
	glPushMatrix();												// Push The Projection Matrix
	glLoadIdentity();											// Resets The Matrix

	// This Creates A Matrix That Will Zoom Up To A Small Portion Of The Screen, Where The Mouse Is.
	gluPickMatrix((GLdouble) mouse_x, (GLdouble) (viewport[3]-mouse_y), 1.0f, 1.0f, viewport);

	// Apply The Perspective Matrix
	gluPerspective(45.0f, (GLfloat) (viewport[2]-viewport[0])/(GLfloat) (viewport[3]-viewport[1]), 0.1f, 100.0f);
	glMatrixMode(GL_MODELVIEW);									// Select The Modelview Matrix
	DrawTargets();												// Render The Targets To The Selection Buffer
	glMatrixMode(GL_PROJECTION);								// Select The Projection Matrix
	glPopMatrix();												// Pop The Projection Matrix
	glMatrixMode(GL_MODELVIEW);									// Select The Modelview Matrix
	hits=glRenderMode(GL_RENDER);								// Switch To Render Mode, Find Out How Many
																// Objects Were Drawn Where The Mouse Was
	if (hits > 0)												// If There Were More Than 0 Hits
	{
		int	choose = buffer[3];									// Make Our Selection The First Object
		int depth = buffer[1];									// Store How Far Away It Is 

		for (int loop = 1; loop < hits; loop++)					// Loop Through All The Detected Hits
		{
			// If This Object Is Closer To Us Than The One We Have Selected
			if (buffer[loop*4+1] < GLuint(depth))
			{
				choose = buffer[loop*4+3];						// Select The Closer Object
				depth = buffer[loop*4+1];						// Store How Far Away It Is
			}       
		}

		if (!object[choose].hit)								// If The Object Hasn't Already Been Hit
		{
			object[choose].hit=TRUE;							// Mark The Object As Being Hit
			score+=1;											// Increase Score
			kills+=1;											// Increase Level Kills
			if (kills>level*5)									// New Level Yet?
			{
				miss=0;											// Misses Reset Back To Zero
				kills=0;										// Reset Level Kills
				level+=1;										// Increase Level
				if (level>30)									// Higher Than 30?
					level=30;									// Set Level To 30 (Are You A God?)
			}
		}
    }
}
int GLWidget::hitObjects(int x, int y, const int nMaxObjectsHit)
{
    int nFoundObjects = 0;
    int viewport[4] = {0};
    GLuint selectBuffer[32];
    int N = 6;

    glInitNames();
    glPushName(0);

    //Register selection buffer
    glSelectBuffer(32, selectBuffer);

    //Get Viewport from OpenGL. Can use this function to obtain many info
    glGetIntegerv(GL_VIEWPORT, viewport);

    //Need to change projection matrix
    glMatrixMode(GL_PROJECTION);

    //Save current projection matrix
    glPushMatrix();

    //load identity to top matrix
    glLoadIdentity();

    //Pick Matrix for receiving points
    gluPickMatrix((double)x, (double)(viewport[3] - y), N, N, viewport);

    //Perspective view or Orthogonal View. Multiply by current projection matrix
    if(m_bPerspective)
    {
        GLfloat fov = 60.0f;
        gluPerspective(fov, (GLdouble)width()/height(), 1, 3000);
    }
    else
        glOrtho(-1.0, +1.0, -1.0, 1.0, -1.0, 1.0);

    //Set render mode to select objects
    //glRenderMode(GL_SELECT);

    //Goto Model View to draw objects
    glMatrixMode(GL_MODELVIEW);

    //Draw with names
    m_cylinder.drawCurveControlPoints(true);

    //Revert to previous projection matrix
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);

    nFoundObjects = glRenderMode(GL_RENDER);

    if(nFoundObjects > 0)
    {
        //Minimum Depth
        GLuint minDepth = selectBuffer[1];

        //Selection ID
        int selectID = selectBuffer[3];

        for(int i=1; i < nFoundObjects; i++)
        {
            if(selectBuffer[i*4 + 1] < minDepth)
            {
                minDepth = selectBuffer[i*4 + 1];
                selectID = selectBuffer[i*4 + 3];
            }
        }
        return selectID;
    }
    return -1;
}
Ejemplo n.º 26
0
   void VisualSceneOCCGeometry :: MouseDblClick (int px, int py)
   {
      int hits;

      // select surface triangle by mouse click

      GLuint selbuf[10000];
      glSelectBuffer (10000, selbuf);

      glRenderMode (GL_SELECT);

      GLint viewport[4];
      glGetIntegerv (GL_VIEWPORT, viewport);

      glMatrixMode (GL_PROJECTION);
      glPushMatrix();

      GLdouble projmat[16];
      glGetDoublev (GL_PROJECTION_MATRIX, projmat);

      glLoadIdentity();
      gluPickMatrix (px, viewport[3] - py, 1, 1, viewport);
      glMultMatrixd (projmat);

      glClearColor(backcolor, backcolor, backcolor, 1.0);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

      glMatrixMode (GL_MODELVIEW);

      glPushMatrix();
      glMultMatrixf (transformationmat);

      glInitNames();
      glPushName (1);

      glPolygonOffset (1, 1);
      glEnable (GL_POLYGON_OFFSET_FILL);

      glDisable(GL_CLIP_PLANE0);

      // Philippose - 30/01/2009
      // Enable clipping planes for Selection mode in OCC Geometry
      if (vispar.clipenable)
      {
         Vec<3> n(clipplane[0], clipplane[1], clipplane[2]);
         double len = Abs(n);
         double mu = -clipplane[3] / (len*len);
         Point<3> p (mu * n);
         n /= len;
         Vec<3> t1 = n.GetNormal ();
         Vec<3> t2 = Cross (n, t1);

         double xi1mid = (center - p) * t1;
         double xi2mid = (center - p) * t2;

         glLoadName (0);
         glBegin (GL_QUADS);
         glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid-rad) * t2);
         glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid-rad) * t2);
         glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid+rad) * t2);
         glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid+rad) * t2);
         glEnd ();
      }

      glCallList (trilists.Get(1));

      glDisable (GL_POLYGON_OFFSET_FILL);

      glPopName();

      glMatrixMode (GL_PROJECTION);
      glPopMatrix();

      glMatrixMode (GL_MODELVIEW);
      glPopMatrix();

      glFlush();

      hits = glRenderMode (GL_RENDER);

      int minname = 0;
      GLuint mindepth = 0;

      // find clippingplane
      GLuint clipdepth = 0; // GLuint(-1);

      for (int i = 0; i < hits; i++)
      {
         int curname = selbuf[4*i+3];
         if (!curname) clipdepth = selbuf[4*i+1];
      }

      for (int i = 0; i < hits; i++)
      {
         int curname = selbuf[4*i+3];
         GLuint curdepth = selbuf[4*i+1];
         if (curname && (curdepth> clipdepth) &&
               (curdepth < mindepth || !minname))
         {
            mindepth = curdepth;
            minname = curname;
         }
      }

      occgeometry->LowLightAll();

      if (minname)
      {
         occgeometry->fvispar[minname-1].Highlight();

         if (vispar.occzoomtohighlightedentity)
         occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE;
         else
         occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE;
         cout << "Selected face: " << minname << endl;
      }
      else
      {
         occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE;
      }

      glDisable(GL_CLIP_PLANE0);

      SelectFaceInOCCDialogTree (minname);

      // Philippose - 30/01/2009
      // Set the currently selected face in the array
      // for local face mesh size definition
      occgeometry->SetSelectedFace(minname);

      //  selecttimestamp = NextTimeStamp();
   }
Ejemplo n.º 27
0
void Gource::mousetrace(Frustum& frustum, float dt) {
    GLuint	buffer[512];
	GLint	viewport[4];

	glGetIntegerv(GL_VIEWPORT, viewport);
	glSelectBuffer(512, buffer);

    glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);

	(void) glRenderMode(GL_SELECT);

	glInitNames();
	glPushName(0);

	glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPickMatrix((GLdouble) mousepos.x, (GLdouble) (viewport[3]-mousepos.y), 1.0f, 1.0f, viewport);
    gluPerspective(90.0f, (GLfloat)display.width/(GLfloat)display.height, 0.1f, camera.getZFar());
    camera.look();

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    for(std::map<std::string,RUser*>::iterator it = users.begin(); it!=users.end(); it++) {
        it->second->drawSimple(dt);
    }

    glDisable(GL_TEXTURE_2D);
    glColor4f(1.0, 1.0, 1.0, 1.0);

    root->drawSimple(frustum, dt);

    glMatrixMode(GL_MODELVIEW);

    mouse_hits = glRenderMode(GL_RENDER);

    RFile* fileSelection = 0;
    RUser* userSelection = 0;

    if (mouse_hits > 0) {
        int choice   = buffer[3];
        GLuint depth = buffer[1];

        for (int loop = 1; loop < mouse_hits; loop++) {
            if (buffer[loop*4+1] < depth) {
                choice = buffer[loop*4+3];
                depth  = buffer[loop*4+1];
            }
        }

        if(choice != 0) {
            selectionDepth = depth;

            std::map<int, RFile*>::iterator filetest;
            std::map<int, RUser*>::iterator usertest;

            if((filetest = tagfilemap.find(choice)) != tagfilemap.end()) {
                fileSelection = filetest->second;
            }
            else if((usertest = tagusermap.find(choice)) != tagusermap.end()) {
                userSelection = usertest->second;
            }
		}
    }

    glDisable(GL_DEPTH_TEST);

    // is over a file
    if(fileSelection != 0) {
        // un hover a user
        if(hoverUser != 0) {
            hoverUser->setMouseOver(false);
            hoverUser = 0;
        }

        if(fileSelection != hoverFile) {
            //deselect previous selection
            if(hoverFile !=0) hoverFile->setMouseOver(false);

            //select new
            fileSelection->setMouseOver(true);
            hoverFile = fileSelection;
        }

    // is over a user
    } else if(userSelection != 0) {
        // un hover a file
        if(hoverFile != 0) {
            hoverFile->setMouseOver(false);
            hoverFile = 0;
        }

        if(userSelection != hoverUser) {
            //deselect previous selection
            if(hoverUser !=0) hoverUser->setMouseOver(false);

            //select new
            userSelection->setMouseOver(true);
            hoverUser = userSelection;
        }
    } else {
        if(hoverFile!=0) hoverFile->setMouseOver(false);
        if(hoverUser!=0) hoverUser->setMouseOver(false);
        hoverFile=0;
        hoverUser=0;
    }

    if(mouseclicked) {
        if(hoverUser!=0) selectUser(hoverUser);
        else if(hoverFile!=0) selectFile(hoverFile);
        else selectUser(0);
    }
}
Ejemplo n.º 28
0
int
__glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc)
{
    ClientPtr client = cl->client;
    __GLXcontext *cx;
    xGLXRenderModeReply reply;
    GLint nitems = 0, retBytes = 0, retval, newModeCheck;
    GLubyte *retBuffer = NULL;
    GLenum newMode;

    __GLX_DECLARE_SWAP_VARIABLES;
    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
    int error;

    REQUEST_FIXED_SIZE(xGLXSingleReq, 4);

    __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
    cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
    if (!cx) {
        return error;
    }

    pc += __GLX_SINGLE_HDR_SIZE;
    __GLX_SWAP_INT(pc);
    newMode = *(GLenum *) pc;
    retval = glRenderMode(newMode);

    /* Check that render mode worked */
    glGetIntegerv(GL_RENDER_MODE, &newModeCheck);
    if (newModeCheck != newMode) {
        /* Render mode change failed.  Bail */
        newMode = newModeCheck;
        goto noChangeAllowed;
    }

    /*
     ** Render mode might have still failed if we get here.  But in this
     ** case we can't really tell, nor does it matter.  If it did fail, it
     ** will return 0, and thus we won't send any data across the wire.
     */

    switch (cx->renderMode) {
    case GL_RENDER:
        cx->renderMode = newMode;
        break;
    case GL_FEEDBACK:
        if (retval < 0) {
            /* Overflow happened. Copy the entire buffer */
            nitems = cx->feedbackBufSize;
        }
        else {
            nitems = retval;
        }
        retBytes = nitems * __GLX_SIZE_FLOAT32;
        retBuffer = (GLubyte *) cx->feedbackBuf;
        __GLX_SWAP_FLOAT_ARRAY((GLbyte *) retBuffer, nitems);
        cx->renderMode = newMode;
        break;
    case GL_SELECT:
        if (retval < 0) {
            /* Overflow happened.  Copy the entire buffer */
            nitems = cx->selectBufSize;
        }
        else {
            GLuint *bp = cx->selectBuf;
            GLint i;

            /*
             ** Figure out how many bytes of data need to be sent.  Parse
             ** the selection buffer to determine this fact as the
             ** return value is the number of hits, not the number of
             ** items in the buffer.
             */
            nitems = 0;
            i = retval;
            while (--i >= 0) {
                GLuint n;

                /* Parse select data for this hit */
                n = *bp;
                bp += 3 + n;
            }
            nitems = bp - cx->selectBuf;
        }
        retBytes = nitems * __GLX_SIZE_CARD32;
        retBuffer = (GLubyte *) cx->selectBuf;
        __GLX_SWAP_INT_ARRAY((GLbyte *) retBuffer, nitems);
        cx->renderMode = newMode;
        break;
    }

    /*
     ** First reply is the number of elements returned in the feedback or
     ** selection array, as per the API for glRenderMode itself.
     */
 noChangeAllowed:;
    reply = (xGLXRenderModeReply) {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = nitems,
        .retval = retval,
        .size = nitems,
        .newMode = newMode
    };
    __GLX_SWAP_SHORT(&reply.sequenceNumber);
    __GLX_SWAP_INT(&reply.length);
    __GLX_SWAP_INT(&reply.retval);
    __GLX_SWAP_INT(&reply.size);
    __GLX_SWAP_INT(&reply.newMode);
    WriteToClient(client, sz_xGLXRenderModeReply, &reply);
    if (retBytes) {
        WriteToClient(client, retBytes, retBuffer);
    }
    return Success;
}

int
__glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc)
{
    ClientPtr client = cl->client;
    __GLXcontext *cx;
    int error;

    __GLX_DECLARE_SWAP_VARIABLES;

    REQUEST_SIZE_MATCH(xGLXSingleReq);

    __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
    cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
    if (!cx) {
        return error;
    }

    glFlush();
    return Success;
}
Ejemplo n.º 29
0
/* Tesselates a high order rectangular patch into single triangles using gl evaluators
 *
 * The problem is that OpenGL does not offer a direct way to return the tesselated primitives,
 * and they can't be sent off for rendering directly either. Tesselating is slow, so we want
 * to cache the patches in a vertex buffer. But more importantly, gl can't bind generated
 * attributes to numbered shader attributes, so we have to store them and rebind them as needed
 * in drawprim.
 *
 * To read back, the opengl feedback mode is used. This creates a problem because we want
 * untransformed, unlit vertices, but feedback runs everything through transform and lighting.
 * Thus disable lighting and set identity matrices to get unmodified colors and positions.
 * To overcome clipping find the biggest x, y and z values of the vertices in the patch and scale
 * them to [-1.0;+1.0] and set the viewport up to scale them back.
 *
 * Normals are more tricky: Draw white vertices with 3 directional lights, and calculate the
 * resulting colors back to the normals.
 *
 * NOTE: This function activates a context for blitting, modifies matrices & viewport, but
 * does not restore it because normally a draw follows immediately afterwards. The caller is
 * responsible of taking care that either the gl states are restored, or the context activated
 * for drawing to reset the lastWasBlit flag.
 */
HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
                            struct WineD3DRectPatch *patch) {
    unsigned int i, j, num_quads, out_vertex_size, buffer_size, d3d_out_vertex_size;
    float max_x = 0.0f, max_y = 0.0f, max_z = 0.0f, neg_z = 0.0f;
    struct wined3d_stream_info stream_info;
    struct wined3d_stream_info_element *e;
    struct wined3d_context *context;
    const BYTE *data;
    const WINED3DRECTPATCH_INFO *info = &patch->RectPatchInfo;
    DWORD vtxStride;
    GLenum feedback_type;
    GLfloat *feedbuffer;

    /* Simply activate the context for blitting. This disables all the things we don't want and
     * takes care of dirtifying. Dirtifying is preferred over pushing / popping, since drawing the
     * patch (as opposed to normal draws) will most likely need different changes anyway. */
    context = context_acquire(This, NULL, CTXUSAGE_BLIT);

    /* First, locate the position data. This is provided in a vertex buffer in the stateblock.
     * Beware of vbos
     */
    device_stream_info_from_declaration(This, FALSE, &stream_info, NULL);

    e = &stream_info.elements[WINED3D_FFP_POSITION];
    if (e->buffer_object)
    {
        struct wined3d_buffer *vb;
        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx];
        e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb));
    }
    vtxStride = e->stride;
    data = e->data +
           vtxStride * info->Stride * info->StartVertexOffsetHeight +
           vtxStride * info->StartVertexOffsetWidth;

    /* Not entirely sure about what happens with transformed vertices */
    if (stream_info.position_transformed) FIXME("Transformed position in rectpatch generation\n");

    if(vtxStride % sizeof(GLfloat)) {
        /* glMap2f reads vertex sizes in GLfloats, the d3d stride is in bytes.
         * I don't see how the stride could not be a multiple of 4, but make sure
         * to check it
         */
        ERR("Vertex stride is not a multiple of sizeof(GLfloat)\n");
    }
    if(info->Basis != WINED3DBASIS_BEZIER) {
        FIXME("Basis is %s, how to handle this?\n", debug_d3dbasis(info->Basis));
    }
    if(info->Degree != WINED3DDEGREE_CUBIC) {
        FIXME("Degree is %s, how to handle this?\n", debug_d3ddegree(info->Degree));
    }

    /* First, get the boundary cube of the input data */
    for(j = 0; j < info->Height; j++) {
        for(i = 0; i < info->Width; i++) {
            const float *v = (const float *)(data + vtxStride * i + vtxStride * info->Stride * j);
            if(fabs(v[0]) > max_x) max_x = fabs(v[0]);
            if(fabs(v[1]) > max_y) max_y = fabs(v[1]);
            if(fabs(v[2]) > max_z) max_z = fabs(v[2]);
            if(v[2] < neg_z) neg_z = v[2];
        }
    }

    /* This needs some improvements in the vertex decl code */
    FIXME("Cannot find data to generate. Only generating position and normals\n");
    patch->has_normals = TRUE;
    patch->has_texcoords = FALSE;

    ENTER_GL();

    glMatrixMode(GL_PROJECTION);
    checkGLcall("glMatrixMode(GL_PROJECTION)");
    glLoadIdentity();
    checkGLcall("glLoadIndentity()");
    glScalef(1.0f / (max_x), 1.0f / (max_y), max_z == 0.0f ? 1.0f : 1.0f / (2.0f * max_z));
    glTranslatef(0.0f, 0.0f, 0.5f);
    checkGLcall("glScalef");
    glViewport(-max_x, -max_y, 2 * (max_x), 2 * (max_y));
    checkGLcall("glViewport");

    /* Some states to take care of. If we're in wireframe opengl will produce lines, and confuse
     * our feedback buffer parser
     */
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_FILLMODE));
    if(patch->has_normals) {
        static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
        static const GLfloat red[]   = {1.0f, 0.0f, 0.0f, 0.0f};
        static const GLfloat green[] = {0.0f, 1.0f, 0.0f, 0.0f};
        static const GLfloat blue[]  = {0.0f, 0.0f, 1.0f, 0.0f};
        static const GLfloat white[] = {1.0f, 1.0f, 1.0f, 1.0f};
        glEnable(GL_LIGHTING);
        checkGLcall("glEnable(GL_LIGHTING)");
        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black);
        checkGLcall("glLightModel for MODEL_AMBIENT");
        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_AMBIENT));

        for (i = 3; i < context->gl_info->limits.lights; ++i)
        {
            glDisable(GL_LIGHT0 + i);
            checkGLcall("glDisable(GL_LIGHT0 + i)");
            IWineD3DDeviceImpl_MarkStateDirty(This, STATE_ACTIVELIGHT(i));
        }

        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_ACTIVELIGHT(0));
        glLightfv(GL_LIGHT0, GL_DIFFUSE, red);
        glLightfv(GL_LIGHT0, GL_SPECULAR, black);
        glLightfv(GL_LIGHT0, GL_AMBIENT, black);
        glLightfv(GL_LIGHT0, GL_POSITION, red);
        glEnable(GL_LIGHT0);
        checkGLcall("Setting up light 1");
        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_ACTIVELIGHT(1));
        glLightfv(GL_LIGHT1, GL_DIFFUSE, green);
        glLightfv(GL_LIGHT1, GL_SPECULAR, black);
        glLightfv(GL_LIGHT1, GL_AMBIENT, black);
        glLightfv(GL_LIGHT1, GL_POSITION, green);
        glEnable(GL_LIGHT1);
        checkGLcall("Setting up light 2");
        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_ACTIVELIGHT(2));
        glLightfv(GL_LIGHT2, GL_DIFFUSE, blue);
        glLightfv(GL_LIGHT2, GL_SPECULAR, black);
        glLightfv(GL_LIGHT2, GL_AMBIENT, black);
        glLightfv(GL_LIGHT2, GL_POSITION, blue);
        glEnable(GL_LIGHT2);
        checkGLcall("Setting up light 3");

        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_MATERIAL);
        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORVERTEX));
        glDisable(GL_COLOR_MATERIAL);
        glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, white);
        checkGLcall("Setting up materials");
    }

    /* Enable the needed maps.
     * GL_MAP2_VERTEX_3 is needed for positional data.
     * GL_AUTO_NORMAL to generate normals from the position. Do not use GL_MAP2_NORMAL.
     * GL_MAP2_TEXTURE_COORD_4 for texture coords
     */
    num_quads = ceilf(patch->numSegs[0]) * ceilf(patch->numSegs[1]);
    out_vertex_size = 3 /* position */;
    d3d_out_vertex_size = 3;
    glEnable(GL_MAP2_VERTEX_3);
    if(patch->has_normals && patch->has_texcoords) {
        FIXME("Texcoords not handled yet\n");
        feedback_type = GL_3D_COLOR_TEXTURE;
        out_vertex_size += 8;
        d3d_out_vertex_size += 7;
        glEnable(GL_AUTO_NORMAL);
        glEnable(GL_MAP2_TEXTURE_COORD_4);
    } else if(patch->has_texcoords) {
        FIXME("Texcoords not handled yet\n");
        feedback_type = GL_3D_COLOR_TEXTURE;
        out_vertex_size += 7;
        d3d_out_vertex_size += 4;
        glEnable(GL_MAP2_TEXTURE_COORD_4);
    } else if(patch->has_normals) {
        feedback_type = GL_3D_COLOR;
        out_vertex_size += 4;
        d3d_out_vertex_size += 3;
        glEnable(GL_AUTO_NORMAL);
    } else {
        feedback_type = GL_3D;
    }
    checkGLcall("glEnable vertex attrib generation");

    buffer_size = num_quads * out_vertex_size * 2 /* triangle list */ * 3 /* verts per tri */
                   + 4 * num_quads /* 2 triangle markers per quad + num verts in tri */;
    feedbuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_size * sizeof(float) * 8);

    glMap2f(GL_MAP2_VERTEX_3,
            0.0f, 1.0f, vtxStride / sizeof(float), info->Width,
            0.0f, 1.0f, info->Stride * vtxStride / sizeof(float), info->Height,
            (const GLfloat *)data);
    checkGLcall("glMap2f");
    if(patch->has_texcoords) {
        glMap2f(GL_MAP2_TEXTURE_COORD_4,
                0.0f, 1.0f, vtxStride / sizeof(float), info->Width,
                0.0f, 1.0f, info->Stride * vtxStride / sizeof(float), info->Height,
                (const GLfloat *)data);
        checkGLcall("glMap2f");
    }
    glMapGrid2f(ceilf(patch->numSegs[0]), 0.0f, 1.0f, ceilf(patch->numSegs[1]), 0.0f, 1.0f);
    checkGLcall("glMapGrid2f");

    glFeedbackBuffer(buffer_size * 2, feedback_type, feedbuffer);
    checkGLcall("glFeedbackBuffer");
    glRenderMode(GL_FEEDBACK);

    glEvalMesh2(GL_FILL, 0, ceilf(patch->numSegs[0]), 0, ceilf(patch->numSegs[1]));
    checkGLcall("glEvalMesh2");

    i = glRenderMode(GL_RENDER);
    if(i == -1) {
        LEAVE_GL();
        ERR("Feedback failed. Expected %d elements back\n", buffer_size);
        HeapFree(GetProcessHeap(), 0, feedbuffer);
        context_release(context);
        return WINED3DERR_DRIVERINTERNALERROR;
    } else if(i != buffer_size) {
        LEAVE_GL();
        ERR("Unexpected amount of elements returned. Expected %d, got %d\n", buffer_size, i);
        HeapFree(GetProcessHeap(), 0, feedbuffer);
        context_release(context);
        return WINED3DERR_DRIVERINTERNALERROR;
    } else {
        TRACE("Got %d elements as expected\n", i);
    }

    HeapFree(GetProcessHeap(), 0, patch->mem);
    patch->mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, num_quads * 6 * d3d_out_vertex_size * sizeof(float) * 8);
    i = 0;
    for(j = 0; j < buffer_size; j += (3 /* num verts */ * out_vertex_size + 2 /* tri marker */)) {
        if(feedbuffer[j] != GL_POLYGON_TOKEN) {
            ERR("Unexpected token: %f\n", feedbuffer[j]);
            continue;
        }
        if(feedbuffer[j + 1] != 3) {
            ERR("Unexpected polygon: %f corners\n", feedbuffer[j + 1]);
            continue;
        }
        /* Somehow there are different ideas about back / front facing, so fix up the
         * vertex order
         */
        patch->mem[i + 0] =  feedbuffer[j + out_vertex_size * 2 + 2]; /* x, triangle 2 */
        patch->mem[i + 1] =  feedbuffer[j + out_vertex_size * 2 + 3]; /* y, triangle 2 */
        patch->mem[i + 2] = (feedbuffer[j + out_vertex_size * 2 + 4] - 0.5f) * 4.0f * max_z; /* z, triangle 3 */
        if(patch->has_normals) {
            patch->mem[i + 3] = feedbuffer[j + out_vertex_size * 2 + 5];
            patch->mem[i + 4] = feedbuffer[j + out_vertex_size * 2 + 6];
            patch->mem[i + 5] = feedbuffer[j + out_vertex_size * 2 + 7];
        }
        i += d3d_out_vertex_size;

        patch->mem[i + 0] =  feedbuffer[j + out_vertex_size * 1 + 2]; /* x, triangle 2 */
        patch->mem[i + 1] =  feedbuffer[j + out_vertex_size * 1 + 3]; /* y, triangle 2 */
        patch->mem[i + 2] = (feedbuffer[j + out_vertex_size * 1 + 4] - 0.5f) * 4.0f * max_z; /* z, triangle 2 */
        if(patch->has_normals) {
            patch->mem[i + 3] = feedbuffer[j + out_vertex_size * 1 + 5];
            patch->mem[i + 4] = feedbuffer[j + out_vertex_size * 1 + 6];
            patch->mem[i + 5] = feedbuffer[j + out_vertex_size * 1 + 7];
        }
        i += d3d_out_vertex_size;

        patch->mem[i + 0] =  feedbuffer[j + out_vertex_size * 0 + 2]; /* x, triangle 1 */
        patch->mem[i + 1] =  feedbuffer[j + out_vertex_size * 0 + 3]; /* y, triangle 1 */
        patch->mem[i + 2] = (feedbuffer[j + out_vertex_size * 0 + 4] - 0.5f) * 4.0f * max_z; /* z, triangle 1 */
        if(patch->has_normals) {
            patch->mem[i + 3] = feedbuffer[j + out_vertex_size * 0 + 5];
            patch->mem[i + 4] = feedbuffer[j + out_vertex_size * 0 + 6];
            patch->mem[i + 5] = feedbuffer[j + out_vertex_size * 0 + 7];
        }
        i += d3d_out_vertex_size;
    }

    if(patch->has_normals) {
        /* Now do the same with reverse light directions */
        static const GLfloat x[] = {-1.0f,  0.0f,  0.0f, 0.0f};
        static const GLfloat y[] = { 0.0f, -1.0f,  0.0f, 0.0f};
        static const GLfloat z[] = { 0.0f,  0.0f, -1.0f, 0.0f};
        glLightfv(GL_LIGHT0, GL_POSITION, x);
        glLightfv(GL_LIGHT1, GL_POSITION, y);
        glLightfv(GL_LIGHT2, GL_POSITION, z);
        checkGLcall("Setting up reverse light directions");

        glRenderMode(GL_FEEDBACK);
        checkGLcall("glRenderMode(GL_FEEDBACK)");
        glEvalMesh2(GL_FILL, 0, ceilf(patch->numSegs[0]), 0, ceilf(patch->numSegs[1]));
        checkGLcall("glEvalMesh2");
        i = glRenderMode(GL_RENDER);
        checkGLcall("glRenderMode(GL_RENDER)");

        i = 0;
        for(j = 0; j < buffer_size; j += (3 /* num verts */ * out_vertex_size + 2 /* tri marker */)) {
            if(feedbuffer[j] != GL_POLYGON_TOKEN) {
                ERR("Unexpected token: %f\n", feedbuffer[j]);
                continue;
            }
            if(feedbuffer[j + 1] != 3) {
                ERR("Unexpected polygon: %f corners\n", feedbuffer[j + 1]);
                continue;
            }
            if(patch->mem[i + 3] == 0.0f)
                patch->mem[i + 3] = -feedbuffer[j + out_vertex_size * 2 + 5];
            if(patch->mem[i + 4] == 0.0f)
                patch->mem[i + 4] = -feedbuffer[j + out_vertex_size * 2 + 6];
            if(patch->mem[i + 5] == 0.0f)
                patch->mem[i + 5] = -feedbuffer[j + out_vertex_size * 2 + 7];
            normalize_normal(patch->mem + i + 3);
            i += d3d_out_vertex_size;

            if(patch->mem[i + 3] == 0.0f)
                patch->mem[i + 3] = -feedbuffer[j + out_vertex_size * 1 + 5];
            if(patch->mem[i + 4] == 0.0f)
                patch->mem[i + 4] = -feedbuffer[j + out_vertex_size * 1 + 6];
            if(patch->mem[i + 5] == 0.0f)
                patch->mem[i + 5] = -feedbuffer[j + out_vertex_size * 1 + 7];
            normalize_normal(patch->mem + i + 3);
            i += d3d_out_vertex_size;

            if(patch->mem[i + 3] == 0.0f)
                patch->mem[i + 3] = -feedbuffer[j + out_vertex_size * 0 + 5];
            if(patch->mem[i + 4] == 0.0f)
                patch->mem[i + 4] = -feedbuffer[j + out_vertex_size * 0 + 6];
            if(patch->mem[i + 5] == 0.0f)
                patch->mem[i + 5] = -feedbuffer[j + out_vertex_size * 0 + 7];
            normalize_normal(patch->mem + i + 3);
            i += d3d_out_vertex_size;
        }
    }

    glDisable(GL_MAP2_VERTEX_3);
    glDisable(GL_AUTO_NORMAL);
    glDisable(GL_MAP2_NORMAL);
    glDisable(GL_MAP2_TEXTURE_COORD_4);
    checkGLcall("glDisable vertex attrib generation");
    LEAVE_GL();

    context_release(context);

    HeapFree(GetProcessHeap(), 0, feedbuffer);

    vtxStride = 3 * sizeof(float);
    if(patch->has_normals) {
        vtxStride += 3 * sizeof(float);
    }
    if(patch->has_texcoords) {
        vtxStride += 4 * sizeof(float);
    }
    memset(&patch->strided, 0, sizeof(patch->strided));
    patch->strided.position.format = WINED3DFMT_R32G32B32_FLOAT;
    patch->strided.position.lpData = (BYTE *) patch->mem;
    patch->strided.position.dwStride = vtxStride;

    if(patch->has_normals) {
        patch->strided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
        patch->strided.normal.lpData = (BYTE *) patch->mem + 3 * sizeof(float) /* pos */;
        patch->strided.normal.dwStride = vtxStride;
    }
    if(patch->has_texcoords) {
        patch->strided.texCoords[0].format = WINED3DFMT_R32G32B32A32_FLOAT;
        patch->strided.texCoords[0].lpData = (BYTE *) patch->mem + 3 * sizeof(float) /* pos */;
        if(patch->has_normals) {
            patch->strided.texCoords[0].lpData += 3 * sizeof(float);
        }
        patch->strided.texCoords[0].dwStride = vtxStride;
    }

    return WINED3D_OK;
}
Ejemplo n.º 30
0
int sftcpy(pScene sc,pMesh mesh) {
    FILE     *file;
    GLfloat  *fbbuffer;
    GLint     nvalues;
    GLsizei   size;
    char     *ptr,data[128];
    static int nfree=0;

    /* default */
    if ( ddebug ) printf("soft copy\n");

//#ifdef IGL
//#define SFT_EXT "ps"
//#define GL2PS_EXT GL2PS_EPS
//#else
#define SFT_EXT "ps"
//#endif
    /* get file name */
    strcpy(data,mesh->name);
    ptr = (char*)strstr(data,".mesh");
    if ( ptr ) *ptr = '\0';
    nfree = filnum(data,nfree,SFT_EXT);
    if ( nfree == -1 )  return(0);

    /* open PS file */
    sprintf(data,"%s.%.3d." SFT_EXT,data,nfree);
    file = fopen(data,"w");
    if ( !file ) {
        fprintf(stdout,"  Unable to open %s\n",data);
        return(0);
    }

//#ifdef IGL
//  // http://www.geuz.org/gl2ps/#tth_sEc3
//  GLint buffsize = 0, state = GL2PS_OVERFLOW;
//  GLint viewport[4];
//
//  glGetIntegerv(GL_VIEWPORT, viewport);
//
//  while( state == GL2PS_OVERFLOW ){
//    buffsize += 1024*1024;
//    gl2psBeginPage (mesh->name, "medit", viewport,
//        GL2PS_EXT, GL2PS_BSP_SORT, GL2PS_SILENT |
//        GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT,
//        GL_RGBA, 0, NULL, 0, 0, 0, buffsize,
//        file, data );
//    drawModel(sc);
//    if ( sc->type & S_DECO )  redrawStatusBar(sc);
//    state = gl2psEndPage();
//  }
//
//  fclose(file);
//
//#else

    /* size for feedback buffer */
    size    =  0;
    nvalues = -1;
    do {
        size += 1024*1024;
        fbbuffer = (GLfloat *)calloc(1+size,sizeof(GLfloat));
        if ( !fbbuffer ) {
            return(0);
        }
        if ( ddebug ) printf("feedback pointer = %p\n",fbbuffer);

        /* draw scene in back buffer */
        glFeedbackBuffer(size,GL_3D_COLOR,fbbuffer);
        (void)glRenderMode(GL_FEEDBACK);
        /*
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
            gluLookAt(0.,0.,-sc->persp->depth, 0.,0.,0., 0.0,1.0,0.0);

            setupView(sc);
            glMultMatrixf(sc->view->matrix);
            glTranslatef(sc->cx,sc->cy,sc->cz);
        */
        drawModel(sc);
        if ( sc->type & S_DECO )  redrawStatusBar(sc);

        /*drawModel(sc);*/
        nvalues = (GLint)glRenderMode(GL_RENDER);
        if ( nvalues < 0 )
            free(fbbuffer);
    }
    while ( nvalues < 0 );

    if ( nvalues < 1 ) {
        return(0);
    }
    else if ( ddebug )  printf("nvalues = %d  size = %d\n",nvalues,size);

    /* write EPS file */
    glutSetCursor(GLUT_CURSOR_WAIT);

    headps(file);
    coreps(file,size,fbbuffer);
    tailps(file);

    if ( ddebug ) fprintf(stdout,"%s written\n",data);
    glutSetCursor(GLUT_CURSOR_INHERIT);
//#endif

    return(1);
}