problem with glutKeyboardFunc(keyboard);

Hi all,

I am developing an opengl application with MFC Appwizard.In Appwizard I will get .h and .cpp files hope all knows about this files.
I have developed an 3d room.Now,my task is to establish movement for an object (ex:triangle…) in that room.For that I have called the function <u>“glutKeyboardFunc(keyboard);”</u>in .cpp file and I included the declaration in .h file as <u>“void glutKeyboardFunc( void (*func)(unsigned char, int , int ));”</u>
I have included the <gl\glut.h> header file in .h file.

Now, when I’m trying to build this project I’m getting error: error C2664: ‘glutKeyboardFunc’ : cannot convert parameter 1 from ‘void (unsigned char,int,int)’ to ‘void (__cdecl *)(unsigned char,int,int)’

can any one help me on this error or give me any idea on how to make a movement for that object.

thanks in advance.

Hi,
Recheck the prototype for the given function and correct the argument noted in the error message. If still didn’t fix the problem then post the prototype of the function which you are passing as a function pointer to “glutKeyboardFunc”.
Hope this will work.

Hi

I have created a class(.h&.cpp) and I used the following code.Here the problem is both the object are moving but I want make the cube which is created by the function “glutWireCube(5);” should move inside that room which made by glBegin&glEnd(QUAD).

Here I’m giving the code which I made,can any one plz help me on this issue

void MFCOpenGL::Display(void)
{

glDrawBuffer(GL_FRONT_LEFT);
//glColor3f(1, 1, 1);
glClearColor(1,1,1,1);//set the background color to black
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
		
		//Image Starts

		glBegin(GL_QUADS);
		glColor3d(1.0, 0.0, 0.0);
		glVertex2d(0.0, 0.0);
		glVertex2d(10.4, -1.4);
		glVertex2d(10.45, 10.5);
		glVertex2d(0.0, 10.7);
		glEnd();
		
		glBegin(GL_QUADS);
		glColor3d(0.0, 1.0, 0.0);
		glVertex2d(-10.5, -1.4);
		glVertex2d(0.0, 0.0);
		glVertex2d(10.0, 10.7);
		glVertex2d(-10.5, 10.5);
		glEnd();
		
		glBegin(GL_QUADS);
		glColor3d(0.0, 0.0,0.0);
		glVertex2d(-10.5, -1.4);
		glVertex2d(10.4, -1.4);
		glVertex2d(0.0, 0.0);
		glVertex2d(0.0,-8.45);
		glEnd();

          glPushMatrix();
     glTranslatef(-10, 10, -10);

    glColor3f(1.0f, 0.0f, 0.0f); //set cube color
glutWireCube(5); //use the premade glut function to draw
                       //a wire cube  
      glPopMatrix();

      glutPostRedisplay();

      glutSwapBuffers();

}

void MFCOpenGL::Resize(int width,int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)width / (float)height, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Set the viewing position and orientation
gluLookAt(
0.0, 0.0, 200.0, // eye location
0.0, 0.0, 0.0, // center location
0.0, 1.0, 0.0); // up vector
}

void MFCOpenGL::keyboard(int key, int x, int y)
{
switch (key)
{
case ‘a’:
case ‘A’:
glTranslatef(-10.0, 0.0, 0.0);
break;
case ‘d’:
case ‘D’:
glTranslatef(10.0, 0.0, 0.0);
break;
case ‘w’:
case ‘W’:
glTranslatef(0.0, 0.0, 10.0);
break;
case ‘s’:
case ‘S’:
glTranslatef(0.0, 0.0, -10.0);
break;

}

}
Thanks in advance

It’s almost never a good idea to put OpenGL calls in your keyboard function. It’s best to define some global variables that you can update when a key is pressed.



float objx = 0.0f;
float objy = 0.0f;
float objz = 0.0f;

void MFCOpenGL::Display(void)
{
...
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glPushMatrix();
glTranslatef(-objx, -objy, -objz);
//use the premade glut function to draw a wire cube
glPopMatrix();

...

glutSwapBuffers();

glutPostRedisplay();
}

void MFCOpenGL::keyboard(int key, int x, int y)
{
switch (key)
{
case 'a':
case 'A':
    objx=10.0f;
    objy=0.0f;
    objz=0.0f;
break;
case 'd':
case 'D':
    objx=-10.0f;
    objy=0.0f;
    objz=0.0f;
break;
case 'w':
case 'W':
    objx=0.0f;
    objy=0.0f;
    objz=-10.0f;
break;
case 's':
case 'S':
    objx=0.0f;
    objy=0.0f;
    objz=10.0f;
break;


}

In display function I drawn one room with 3sides and one solidcube. Here my problem is once I execute my program,the two objects(room,cube) both are moving by the keyboard function. But I want to make the movement only for the “cube”.

I have tried the declaration of the global variables for the glut functions as from previous reply.But this is not working means I’m not getting both the room and cube.

I hope someone will help me from this situation.

Thanks in advance…

Could you post your updated code please?

This is my code after placing global variables,I am a beginner so can u make corrections and send code…for movement of the solid cube only.

float objx = 0.0f;
float objy = 0.0f;
float objz = 0.0f;

void MFCOpenGL::Display(void)
{
glDrawBuffer(GL_FRONT_LEFT);
glColor3d(1, 1, 1);
glClearColor(1,1,1,1);//set the background color to black
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);

		glBegin(GL_QUADS);
		glColor3d(1.0, 0.0, 0.0);
		glVertex2d(0.0, 0.0);
		glVertex2d(0.4, -0.35);
		glVertex2d(0.45, 0.5);
		glVertex2d(0.0, 0.7);
		glEnd();
	
		
		glBegin(GL_QUADS);
		glColor3d(0.0, 1.0, 0.0);
		glVertex2d(-0.5, -0.2);
		glVertex2d(0.0, 0.0);
		glVertex2d(0.0, 0.7);
		glVertex2d(-0.5, 0.5);
		glEnd();
		

		glBegin(GL_QUADS);
		glColor3d(0.0, 0.0, 0.0);
        glVertex2d(-0.2, -0.65);
        glVertex2d(0.4, -0.35);
        glVertex2d(-0.5, -0.2);
        glVertex2d(0.0,0.0);
        glEnd();


		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

		glPushMatrix();
		glTranslatef(-objx,-objy,-objz);
		glutSolidCube (0.1);  //use the premade glut function to draw a wire cube
		glPopMatrix();

		glutPostRedisplay();

		glutSwapBuffers();

}

void MFCOpenGL::Resize(int width,int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)width / (float)height, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Set the viewing position and orientation
gluLookAt(
0.0, 0.0, 10.0, // eye location
0.0, 0.0, 5.0, // center location
0.0, 1.0, 1.0); // up vector
}

void MFCOpenGL::keyboard(int key, int x, int y)
{
switch (key)
{
case ‘a’:
case ‘A’:
objx=1.0f;
objy=0.0f;
objz=0.0f;
break;

	case 'd':
	case 'D':
		objx=-1.0f;
		objy=0.0f;
		objz=0.0f;
	break;
	
	case 'w':
	case 'W':
		objx=0.0f;
		objy=0.0f;
		objz=-1.0f;
	break;
	
	case 's':
	case 'S':
		objx=0.0f;
		objy=0.0f;
		objz=1.0f;
	break;
}

}

Well, didn’t check it completely, but it should be something like this:


float objx = 0.0f;
float objy = 0.0f;
float objz = 0.0f;

void MFCOpenGL::Display(void)
{
glDrawBuffer(GL_FRONT_LEFT);
glColor3d(1, 1, 1);
glClearColor(1,1,1,1);//set the background color to black
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);

//MOVED THESE TWO LINES HERE
// if you don't load identity here, your walls will get transformed by the modelview value at the end of your previous render call
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glBegin(GL_QUADS);
glColor3d(1.0, 0.0, 0.0);
glVertex2d(0.0, 0.0);
glVertex2d(0.4, -0.35);
glVertex2d(0.45, 0.5);
glVertex2d(0.0, 0.7);
glEnd();


glBegin(GL_QUADS);
glColor3d(0.0, 1.0, 0.0);
glVertex2d(-0.5, -0.2);
glVertex2d(0.0, 0.0);
glVertex2d(0.0, 0.7);
glVertex2d(-0.5, 0.5);
glEnd();


glBegin(GL_QUADS);
glColor3d(0.0, 0.0, 0.0);
glVertex2d(-0.2, -0.65);
glVertex2d(0.4, -0.35);
glVertex2d(-0.5, -0.2);
glVertex2d(0.0,0.0);
glEnd();


glPushMatrix();
glTranslatef(-objx,-objy,-objz);
glutSolidCube (0.1); //use the premade glut function to draw a wire cube
glPopMatrix();

glutPostRedisplay();

glutSwapBuffers();

}


void MFCOpenGL::Resize(int width,int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)width / (float)height, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Set the viewing position and orientation
gluLookAt(
0.0, 0.0, 10.0, // eye location
0.0, 0.0, 5.0, // center location
0.0, 1.0, 1.0); // up vector
}

void MFCOpenGL::keyboard(int key, int x, int y)
{
switch (key)
{
case 'a':
case 'A':
objx=1.0f;
objy=0.0f;
objz=0.0f;
break;

case 'd':
case 'D':
objx=-1.0f;
objy=0.0f;
objz=0.0f;
break;

case 'w':
case 'W':
objx=0.0f;
objy=0.0f;
objz=-1.0f;
break;

case 's':
case 'S':
objx=0.0f;
objy=0.0f;
objz=1.0f;
break;
}

} 

The Problem is glLoadIdentity(); if I place anywhere in code it is not showing both the room and solidcube.

Try this code. I also removed the drawing call where you specify the front left buffer, assuming you have a double buffered window (otherwise why would you call glutSwapBuffers?)


#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <GL/glew.h>
#include <GL/glut.h>

using namespace std;

float objx = 0.0f;
float objy = 0.0f;
float objz = 0.0f;

int width,height;


void checkError()
{
    const GLenum error = glGetError();
    if (error != GL_NO_ERROR)
    {
        const GLubyte* errorStr = gluErrorString( error );
        std::cerr << "Error: " << std::string( (char*)errorStr )
        << std::endl;
    }
}

void cleanExit()
{
    exit(0);
}

void changeSize(int w, int h)
{

    width  = w;
    height = h;

    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, (float)width / (float)height, 0.1, 1000.0);
}

void renderScene(void)
{

    glColor3d(1, 1, 1);
    glClearColor(1,1,1,1);//set the background color to black
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(
        0.0, 0.0, 10.0, // eye location
        0.0, 0.0, 5.0, // center location
        0.0, 1.0, 1.0); // up vector

    glBegin(GL_QUADS);
    glColor3d(1.0, 0.0, 0.0);
    glVertex2d(0.0, 0.0);
    glVertex2d(0.4, -0.35);
    glVertex2d(0.45, 0.5);
    glVertex2d(0.0, 0.7);
    glEnd();


    glBegin(GL_QUADS);
    glColor3d(0.0, 1.0, 0.0);
    glVertex2d(-0.5, -0.2);
    glVertex2d(0.0, 0.0);
    glVertex2d(0.0, 0.7);
    glVertex2d(-0.5, 0.5);
    glEnd();


    glBegin(GL_QUADS);
    glColor3d(0.0, 0.0, 0.0);
    glVertex2d(-0.2, -0.65);
    glVertex2d(0.4, -0.35);
    glVertex2d(0.0,0.0);
    glVertex2d(-0.5, -0.2);
    glEnd();


    glPushMatrix();
    glTranslatef(-objx,-objy,-objz);
    glutSolidCube (0.1); //use the premade glut function to draw a wire cube
    glPopMatrix();

	checkError();

    glutSwapBuffers();

    glutPostRedisplay();
}

void processNormalKeys(unsigned char key, int x, int y)
{

    switch (key)
    {
    case 'a':
    case 'A':
        objx=1.0f;
        objy=0.0f;
        objz=0.0f;
        break;

    case 'd':
    case 'D':
        objx=-1.0f;
        objy=0.0f;
        objz=0.0f;
        break;

    case 'w':
    case 'W':
        objx=0.0f;
        objy=0.0f;
        objz=-1.0f;
        break;

    case 's':
    case 'S':
        objx=0.0f;
        objy=0.0f;
        objz=1.0f;
        break;
    }
    glutPostRedisplay();
}

int main(int argc, char **argv)
{


    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(320,320);
    glutCreateWindow("GLSL");

    glutDisplayFunc(renderScene);
    glutReshapeFunc(changeSize);
    glutKeyboardFunc(processNormalKeys);

    glewInit();

    glutMainLoop();

    return 0;
}