Add the picking feature.

We can now select a LED on the screen and get the index of the LED.
To get the right index, we use the color picking technique mentioned
in the OpenGL RedBook. This works suprisingly pretty well (and fast!).
This commit is contained in:
Aaron Mueller 2011-10-30 23:55:53 +01:00
parent b2d11488fa
commit 37e885f02e
6 changed files with 59 additions and 13 deletions

View file

@ -10,8 +10,12 @@
#define PI 3.1415926535897932 #define PI 3.1415926535897932
#define TOP_ORIENTATION 1 // Poor Man's enums
#define SIDE_ORIENTATION 2 #define TOP_ORIENTATION 0x01
#define SIDE_ORIENTATION 0x02
#define RENDER_MODE 0x01
#define PICKING_MODE 0x02
// Materials // Materials
extern float ledOnMaterial[]; extern float ledOnMaterial[];

View file

@ -5,21 +5,23 @@
#include "display.h" #include "display.h"
void drawLEDCube(orientation) { void drawLEDs(int orientation, int mode) {
int x, y, z; int x, y, z;
int colorIndex = 0;
if (orientation == TOP_ORIENTATION) { if (orientation == TOP_ORIENTATION) {
glRotatef(90, 2, 0, 0); glRotatef(90, 2, 0, 0);
} }
// LEDs
glMaterialfv(GL_FRONT, GL_AMBIENT, ledOnMaterial);
for (z=-10; z<=10; z+=10) // Ebene for (z=-10; z<=10; z+=10) // Ebene
for (y=-10; y<=10; y+=10) // Zeile for (y=-10; y<=10; y+=10) // Zeile
for (x=-10; x<=10; x+=10) { // Spalte for (x=-10; x<=10; x+=10) { // Spalte
if (mode == PICKING_MODE) {
// TODO: Test different colors glColor3ub(0, 0, colorIndex*8);
colorIndex++;
} else {
glMaterialfv(GL_FRONT, GL_AMBIENT, (z == 0 ? ledOnMaterial : ledOffMaterial)); glMaterialfv(GL_FRONT, GL_AMBIENT, (z == 0 ? ledOnMaterial : ledOffMaterial));
}
glPushMatrix(); glPushMatrix();
glTranslatef(x, y, z-0.8); glTranslatef(x, y, z-0.8);
@ -35,8 +37,10 @@ void drawLEDCube(orientation) {
glPopMatrix(); glPopMatrix();
} }
}
// Wires void drawWires() {
int x, y;
for (y=-10; y<=10; y+=10) for (y=-10; y<=10; y+=10)
for (x=-10; x<=10; x+=10) { for (x=-10; x<=10; x+=10) {
glMaterialfv(GL_FRONT, GL_AMBIENT, ((x == 0 || y == 0) ? innerWireMaterial : wireMaterial)); glMaterialfv(GL_FRONT, GL_AMBIENT, ((x == 0 || y == 0) ? innerWireMaterial : wireMaterial));
@ -61,9 +65,8 @@ void drawLEDCube(orientation) {
} }
} }
void display() { void setScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
gluPerspective(ZOOM_LEVEL, WINDOW_WIDTH/WINDOW_HEIGHT, 1.0, 350.0); gluPerspective(ZOOM_LEVEL, WINDOW_WIDTH/WINDOW_HEIGHT, 1.0, 350.0);
@ -71,8 +74,25 @@ void display() {
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
gluLookAt(lookX, eyeAngle, lookZ, 0, 0, 0, 0, 1, 0); gluLookAt(lookX, eyeAngle, lookZ, 0, 0, 0, 0, 1, 0);
}
drawLEDCube(TOP_ORIENTATION); // OpenGL Display function
void display() {
setScene();
drawLEDs(TOP_ORIENTATION, RENDER_MODE);
drawWires();
glutSwapBuffers(); glutSwapBuffers();
} }
// Picking function
void displayPickingObjects() {
setScene();
glDisable(GL_DITHER);
glDisable(GL_LIGHTING);
drawLEDs(TOP_ORIENTATION, PICKING_MODE);
glEnable(GL_LIGHTING);
glEnable(GL_DITHER);
}

View file

@ -2,8 +2,13 @@
#define _DISPLAY_H #define _DISPLAY_H
void drawLEDCube(); void drawLEDs(int orientation, int mode);
void drawWires();
void display(); void display();
void displayPickingObjects();
void setScene();
#endif #endif

View file

@ -4,6 +4,7 @@
#include "config.h" #include "config.h"
#include "input.h" #include "input.h"
#include "display.h"
void moveCameraPosition(float direction) { void moveCameraPosition(float direction) {
eyePos += direction; eyePos += direction;
@ -46,3 +47,16 @@ void keyboard_special(int key, int x, int y) {
glutPostRedisplay(); glutPostRedisplay();
} }
void mouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
int viewport[4];
GLubyte pixel[3];
displayPickingObjects();
glGetIntegerv(GL_VIEWPORT, viewport);
glReadPixels(x, viewport[3]-y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, (void*)pixel);
printf("%d\n", pixel[2]/8); // Selected LED
}
}

View file

@ -7,5 +7,7 @@ void moveCameraAngle(float angle);
void keyboard(unsigned char key, int x, int y); void keyboard(unsigned char key, int x, int y);
void keyboard_special(int key, int x, int y); void keyboard_special(int key, int x, int y);
void mouse(int button, int state, int x, int y);
#endif #endif

View file

@ -33,6 +33,7 @@ int main(int argc, char* argv[]) {
glutDisplayFunc(display); glutDisplayFunc(display);
glutKeyboardFunc(keyboard); glutKeyboardFunc(keyboard);
glutSpecialFunc(keyboard_special); glutSpecialFunc(keyboard_special);
glutMouseFunc(mouse);
glClearColor(0.0, 0.0, 0.0, 1.0); glClearColor(0.0, 0.0, 0.0, 1.0);
glShadeModel(GL_SMOOTH); glShadeModel(GL_SMOOTH);