All pastes #559773 Raw Edit

Something

public text v1 · immutable
·published 2007-06-11 22:01 UTC
rendered paste body
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <GL/glut.h>

#include <stdio.h>
#include <stdlib.h>

#define SW 400
#define SH 400

 int selected = 0;

 void gl_draw();
 void gl_init(int w, int h);
 void gl_select(int x, int y);
 void gl_selall(GLint hits, GLuint *buff);
 void sdl_events();
 void sdl_mousedw(int x, int y, int but);
 void draw_block(float x, float y, float z);
 void list_hits(GLint hits, GLuint *names);

 void gl_draw()
{

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glTranslatef(0.0, 0.0, -5.0);

	glColor3f(1.0, 0.0, 0.0);
	glLoadName(7); /* Overwrite the first name in the buffer */
	draw_block(-0.3, 0, -2);

	glColor3f(0.0, 1.0, 0.0);
	glLoadName(14); /* Overwrite the first name in the buffer */
	draw_block(0, 0, -4);

	glColor3f(0.0, 0.0, 1.0);
	glLoadName(21); /* Overwrite the first name in the buffer */
	draw_block(0.3, 0, -6);
}

 void gl_init(int w, int h)
{
	glClearColor(0.0, 0.0, 0.0, 1.0);
	glViewport(0, 0, w, h);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	gluPerspective(60.0, 1.0, 0.0001, 1000.0);

	glMatrixMode(GL_MODELVIEW);
}

 void sdl_events()
{
	SDL_Event event;

	while (SDL_PollEvent(&event))
	{
		switch (event.type)
		{
			case SDL_QUIT: exit(0);
			case SDL_MOUSEBUTTONDOWN:
			{
				sdl_mousedw(event.button.x, event.button.y, event.button.button);
			}; break;
			case SDL_KEYDOWN:
				switch (event.key.keysym.sym)
				{
					case SDLK_ESCAPE: exit(0);
				}
		}
	}
}

 void sdl_mousedw(int x, int y, int but)
{
	printf("Mouse button %d pressed at %d %d\n", but, x, y);
	if (but == SDL_BUTTON_LEFT)
		gl_select(x,SH-y); //Important: gl (0,0) ist bottom left but window coords (0,0) are top left so we have to change this!
}

 void gl_select(int x, int y)
{
	GLuint buff[64] = {0};
	GLint hits, view[4];
	int id;

        /*
	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(x, y, 1.0, 1.0, view);
	gluPerspective(60, 1.0, 0.0001, 1000.0);

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

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

                /*
	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);

        /*
	Print a list of the objects
	*/
	list_hits(hits, buff);

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

	glMatrixMode(GL_MODELVIEW);
}

 void gl_selall(GLint hits, GLuint *buff)
{
	GLuint *p;
	int i;

	gl_draw();

	p = buff;
	for (i = 0; i < 6 * 4; i++)
	{
		printf("Slot %d: - Value: %d\n", i, p[i]);
	}

	printf("Buff size: %x\n", (GLbyte)buff[0]);
}

 void draw_block(float x, float y, float z)
{
	glPushMatrix();
	glTranslatef(x, y, z);
	glutSolidTeapot(2.0);
	glPopMatrix();
}

 void list_hits(GLint hits, GLuint *names)
{
	int i;

        /*
                For each hit in the buffer are allocated 4 bytes:
	1. Number of hits selected (always one,
	beacuse when we draw each object
	we use glLoadName, so we replace the
	prevous name in the stack)
	2. Min Z
	3. Max Z
	4. Name of the hit (glLoadName)
	*/

	printf("%d hits:\n", hits);

	for (i = 0; i < hits; i++)
		printf( "Number: %d\n"
				"Min Z: %d\n"
				"Max Z: %d\n"
				"Name on stack: %d\n",
		(GLubyte)names[i * 4],
		(GLubyte)names[i * 4 + 1],
		(GLubyte)names[i * 4 + 2],
		(GLubyte)names[i * 4 + 3]
		      );

	printf("\n");
}

 int main(int argc, char **argv)
{
	if (SDL_Init(SDL_INIT_VIDEO) < 0)
	{

		exit(1);
	}

	atexit(SDL_Quit);

	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

	if (!SDL_SetVideoMode(SW, SH, 0, SDL_OPENGL))
	{

		exit(1);
	}

	gl_init(SW, SH);
	glutInit(&argc, argv);

	while (1)
	{
		sdl_events();
		gl_draw();
		SDL_GL_SwapBuffers();
	}

	return EXIT_SUCCESS;
}