hi,
im trying to merge a shadow example and a picking example but when I click on the screen it only picks at the center of the screen even though theres nothing at the center.
It’s for a music appication im developing. Light-Track Studio!
I know it has something to do with camera projection matrixes. something i have yet to learn.
heres my code, help would be great!
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include "GLee/GLee.h" //GL header file, including extensions
#include <GL/glut.h>
#include "Maths/Maths.h"
#include "TIMER.h"
#include "FPS_COUNTER.h"
#include "main.h"
#include <iostream>
using namespace std;
#define EARTH 1
#define MARS 2
#define MOON1 3
#define MOON2 4
#define BUFFER_LENGTH 512
//Timer used for frame rate independent movement
TIMER timer;
//Frames per second counter
FPS_COUNTER fpsCounter;
//Camera & light positions
VECTOR3D cameraPosition(-2.5f, 3.5f,-2.5f);
VECTOR3D lightPosition(2.0f, 3.0f,-2.0f);
//Size of shadow map
const int shadowMapSize=512;
//Textures
GLuint shadowMapTexture;
//window size
int windowWidth, windowHeight;
//Matrices
MATRIX4X4 lightProjectionMatrix, lightViewMatrix;
MATRIX4X4 cameraProjectionMatrix, cameraViewMatrix;
//Called for initiation
bool Init(void)
{
//Check for necessary extensions
if (!GLEE_ARB_depth_texture || !GLEE_ARB_shadow)
{
printf("I require ARB_depth_texture and ARB_shadow extensionsn
");
return false;
}
//Load identity modelview
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//Shading states
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
//Depth states
glClearDepth(1.0f);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
//We use glScale when drawing the scene
glEnable(GL_NORMALIZE);
//Create the shadow map texture
glGenTextures(1, &shadowMapTexture);
glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapSize, shadowMapSize, 0,
GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
//Use the color as the ambient and diffuse material
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
//White specular material color, shininess 16
glMaterialfv(GL_FRONT, GL_SPECULAR, white);
glMaterialf(GL_FRONT, GL_SHININESS, 16.0f);
//Calculate & save matrices
glPushMatrix();
glLoadIdentity();
gluPerspective(45.0f, 1.0f, 1.0f, 100.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, cameraProjectionMatrix);
glLoadIdentity();
gluLookAt(cameraPosition.x, cameraPosition.y, cameraPosition.z,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, cameraViewMatrix);
glLoadIdentity();
gluPerspective(45.0f, 1.0f, 2.0f, 8.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, lightProjectionMatrix);
glLoadIdentity();
gluLookAt( lightPosition.x, lightPosition.y, lightPosition.z,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, lightViewMatrix);
glPopMatrix();
//Reset timer
timer.Reset();
return true;
}
void DrawScene()
{
glColor3f(0.0f, 1.0f, 0.0f);
glInitNames();
glPushName(0);
glLoadName(2);
glTranslatef(0.45f, 1.0f, 0.45f);
glutSolidSphere(0.2, 24, 24);
glTranslatef(-0.9f, 0.0f, 0.0f);
glutSolidSphere(0.2, 24, 24);
glTranslatef(0.0f, 0.0f,-0.9f);
glutSolidSphere(0.2, 24, 24);
glTranslatef(0.9f, 0.0f, 0.0f);
glutSolidSphere(0.2, 24, 24);
glPopName();
}
//Called to draw scene
//Called to draw scene
void Display(void)
{
//angle of spheres in scene. Calculate from time
float angle=timer.GetTime()/10;
//First pass - from light's point of view
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(lightProjectionMatrix);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(lightViewMatrix);
//Use viewport the same size as the shadow map
glViewport(0, 0, shadowMapSize, shadowMapSize);
//Draw back faces into the shadow map
glCullFace(GL_FRONT);
//Disable color writes, and use flat shading for speed
glShadeModel(GL_FLAT);
glColorMask(0, 0, 0, 0);
//Draw the scene
DrawScene();
//Read the depth buffer into the shadow map texture
glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowMapSize, shadowMapSize);
//restore states
glCullFace(GL_BACK);
glShadeModel(GL_SMOOTH);
glColorMask(1, 1, 1, 1);
//2nd pass - Draw from camera's point of view
glClear(GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(cameraProjectionMatrix);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(cameraViewMatrix);
glViewport(0, 0, windowWidth, windowHeight);
//Use dim light to represent shadowed areas
glLightfv(GL_LIGHT1, GL_POSITION, VECTOR4D(lightPosition));
glLightfv(GL_LIGHT1, GL_AMBIENT, white*0.2f);
glLightfv(GL_LIGHT1, GL_DIFFUSE, white*0.2f);
glLightfv(GL_LIGHT1, GL_SPECULAR, black);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);
DrawScene();
//3rd pass
//Draw with bright light
glLightfv(GL_LIGHT1, GL_DIFFUSE, white);
glLightfv(GL_LIGHT1, GL_SPECULAR, white);
//Calculate texture matrix for projection
//This matrix takes us from eye space to the light's clip space
//It is postmultiplied by the inverse of the current view matrix when specifying texgen
static MATRIX4X4 biasMatrix(0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f); //bias from [-1, 1] to [0, 1]
MATRIX4X4 textureMatrix=biasMatrix*lightProjectionMatrix*lightViewMatrix;
//Set up texture coordinate generation.
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_S, GL_EYE_PLANE, textureMatrix.GetRow(0));
glEnable(GL_TEXTURE_GEN_S);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_T, GL_EYE_PLANE, textureMatrix.GetRow(1));
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_R, GL_EYE_PLANE, textureMatrix.GetRow(2));
glEnable(GL_TEXTURE_GEN_R);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_Q, GL_EYE_PLANE, textureMatrix.GetRow(3));
glEnable(GL_TEXTURE_GEN_Q);
//Bind & enable shadow map texture
glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
glEnable(GL_TEXTURE_2D);
//Enable shadow comparison
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
//Shadow comparison should be true (ie not in shadow) if r<=texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
//Shadow comparison should generate an INTENSITY result
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
//Set alpha test to discard false comparisons
glAlphaFunc(GL_GEQUAL, 0.99f);
glEnable(GL_ALPHA_TEST);
DrawScene();
//Disable textures and texgen
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_GEN_Q);
//Restore other states
glDisable(GL_LIGHTING);
glDisable(GL_ALPHA_TEST);
//Update frames per second counter
fpsCounter.Update();
//Print fps
static char fpsString[32];
sprintf(fpsString, "%.2f", fpsCounter.GetFps());
//Set matrices for ortho
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(-1.0f, 1.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
//Print text
glRasterPos2f(-1.0f, 0.9f);
for (unsigned int i=0; i<strlen(fpsString); ++i)
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, fpsString[i]);
//reset matrices
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glFinish();
glutSwapBuffers();
glutPostRedisplay();
}
//Called on window resize
void Reshape(int w, int h)
{
//Save new window size
windowWidth=w, windowHeight=h;
//Update the camera's projection matrix
glPushMatrix();
glLoadIdentity();
gluPerspective(45.0f, 1.0f, 1.0f, 100.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, cameraProjectionMatrix);
glPopMatrix();
}
//Called when a key is pressed
void Keyboard(unsigned char key, int x, int y)
{
//If escape is pressed, exit
//if(key==27)
// exit(0);
//Use P to pause the animation and U to unpause
if (key=='P' || key=='p')
timer.Pause();
if (key=='U' || key=='u')
timer.Unpause();
}
void pointerMotion(int x, int y)
{
// Space for selection buffer
GLuint selectBuff[BUFFER_LENGTH];
// Hit counter and viewport storage
GLint hits, viewport[4];
// Get the viewport
glGetIntegerv(GL_VIEWPORT, viewport);
// Set up selection buffer
glSelectBuffer(BUFFER_LENGTH, selectBuff);
// Switch to projection and save the matrix
glMatrixMode(GL_PROJECTION);
glPushMatrix();
// Change render mode
glRenderMode(GL_SELECT);
// Establish new clipping volume to be unit cube around
// mouse cursor point (xPos, yPos) and extending two pixels
// in the vertical and horizontal direction
glLoadIdentity();
gluPickMatrix(x, 512 - y, 2,2, viewport);
// Apply matrix
gluPerspective(45.0f, 1.0f, 1.0f, 100.0f);
glViewport(0, 0, windowWidth, windowHeight);
DrawScene();
// Collect the hits
hits = glRenderMode(GL_RENDER);
// If a single hit occurred, display the info.
if (hits >= 1)
{
int id,count;
char cMessage[64];
// How many names on the name stack
count = selectBuff[0];
// Bottom of the name stack
id = selectBuff[3];
// Select on earth or mars, whichever was picked
switch (id)
{
case EARTH:
cout << "You clicked Earth." << std::endl;
break;
case MARS:
cout << "You clicked Mars." << std::endl;
break;
// If nothing was clicked we shouldn't be here!
default:
cout << "Error - Nothing was clicked on!" << std::endl;
break;
}
}
// Restore the projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
// Go back to modelview for normal rendering
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(640, 512);
glutCreateWindow("Light Track Studio");
if (!Init())
return 0;
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Keyboard);
glutMotionFunc(pointerMotion);
glutMainLoop();
return 0;
}