Jump to content
xisto Community
Sign in to follow this  
t3jem

Programming In Glut (lesson 5) Texture mapping and keyboard controls

Recommended Posts

Lesson 5 of 6. These are beginning to be more advanced tutorials. If you are not familiar with my previous tutorials you may need to go back and read them.

In this tutorial I am going to teach you how to texture map your polygons and implement basic keyboard control. There is alot of new material in this tutorial and I hope I have explained it enough.
Before you get started you will want to name a bmp file "image.bmp" or "image" depending on your computer settings (if one doesn't work then use the other) and place it in the same folder as your project.

Now to start we will be making a seperate header file where we will write our function to load a bitmap file. You should name it "bmpload.h". The code to write in it follows.


first we want to link to our openGL libraries, then include our windows then openGL header files.

#pragma comment(lib, "opengl32.lib")//Link to the OpenGL libraries #pragma comment(lib, "glu32.lib") #pragma comment(lib, "glaux.lib")   #include <windows.h>		// Header File For Windows #include <gl\gl.h>			// Header File For The OpenGL32 Library #include <gl\glu.h>			// Header File For The GLu32 Library #include <gl\glaux.h>		// Header File For The Glaux Library

this is our function that will load our bitmap images. The first parameter is storage for our texture array which will store our image. The second parameter is where you would tell the program where your file is located. and the third parameter is the column you want to store the image to in your array.
bool loadbmp(UINT textureArray[], LPSTR strFileName, int ID)//(NEW) the name of our function {

first we check if a filename was entered, if it wasnt then we exit the program.
if there was a filename then we load the image into a new variable for us to manipulate into a format that we want.
if(!strFileName)   return false;//If no file name was given then return a false value	 	 AUX_RGBImageRec *pBitMap = auxDIBImageLoad(strFileName); //Load the file into a new variable where we can then manipulate it into our texture array

we check to see if data was loaded, if not we exit, otherwise we generate our texture in our texture array.
if(pBitMap == NULL)	exit(0);// If no data was loaded then exit the program. 	 glGenTextures(1, &textureArray[ID]);// Generate one texture into our texture array in the slot defined

glBindTexture binds our image to textured objects, more about this later.
glTexParameteri() defines how the texture is filtered, the first parameter tells the program it is a 2D texture, next we define linear filtering when the texture is near the screen and same for when it is far. We will go farther into filtering in later tutorials.
glTexImage2D() finalizes our image as a texture in our array. First we tell the program our image is 2D, then we set the detail, which is usually set to 0, then how many components (red, green, blue), after that we have the program find the width and height, next we set the size of the border, then what type of image it is (in this case RGB), then the type of data it will be read in (unsigned bytes), and finally where to find the data.

after we finish creating the image we have to clear our variable to help prevent CPU clogging.
glBindTexture(GL_TEXTURE_2D, textureArray[ID]);//This binds the texture to a texture target	 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//set our filter	 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);	//set our filter	 glTexImage2D(GL_TEXTURE_2D, 0, 3, pBitMap->sizeX, pBitMap->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, pBitMap->data);//create our image  	 if (pBitMap)	//If pBitMap still has a value then we want to clear it.										 {		 if (pBitMap->data)										 {			 free(pBitMap->data);								 }		 free(pBitMap);										 }	 return true; }



This code first checks to make sure you entered a file location, it then creates a variable that stores the data from the file and then checks to make sure the file was loaded. Next it generates the texture and sets up filters for it. The only two values for the filters are GL_NEAREST and GL_LINEAR linear makes better looking textures, but nearest uses less CPU, keep this in mind when creating more textured polygons.


The next bit of code is your actual program that will load our new header file then the texture using the function we just created then it will draw the texture onto a square that we can rotate right and left using the 'r' and 'l' keys respectivly.

This time we include our new header file and set our texture array along with our rotation value. Our texture array is of type unsigned integer.
#include<glut.h> #include"bmpload.h"//(NEW) Load the new header file we created  GLuint	textures[1];//(NEW) Storage for one texture.  float rotation = 0;//(NEW) our variable for rotation

in our init function we call our function to load our image for the program.
void init() {	 glClearColor(0,0,0,0);	 gluOrtho2D(-5,5,-5,5); 	 loadbmp(textures, "image.bmp",0);// (NEW) Load our image using the function we created earlier }

In our display function we must enable 2D texturing with glEnable(GL_TEXTURE_2D); and then bind the texture to texture objects with glBindTexture(). Texture objects are created when you use the function glTexCoord2f(); which set which point of the texture to draw on an object. We use it to draw our texture onto a square.
void display() {	 glClear(GL_COLOR_BUFFER_BIT); 	 glEnable(GL_TEXTURE_2D);//(NEW) Enable 2D texturing	 glBindTexture(GL_TEXTURE_2D, textures[0]);// (NEW) used to select the texture you wanted to use 	 glPushMatrix(); 	 glRotatef(rotation, 0,0,1);//Rotate the square on the Z axis according to the rotation variable 	 glBegin(GL_QUADS);// Just create a simple square	 glTexCoord2f(0,1);//(NEW) This is the coordinate position on the texture we want to draw at this vertex (This is the upper left corner)	 glVertex2f(-4,4);//This is the upper left corner of the square	 glTexCoord2f(1,1);//This is the upper right corner of the bitmap	 glVertex2f(4,4);	 glTexCoord2f(1,0);//This is the lower right corner of the bitmap	 glVertex2f(4,-4);	 glTexCoord2f(0,0);//The lower left corner	 glVertex2f(-4,-4);	 glEnd(); 	 glPopMatrix(); 	 glDisable(GL_TEXTURE_2D);//(NEW) Disable 2D texturing 	 glFlush();	 glutPostRedisplay(); }

our next function is to deal with keyboard events. The first parameter is used to retrieve which key was pressed, the next to are the positions of the mouse pointer, but we will learn how to use the mouse in later tutorials.
We use a switch statement to reduce the amount of code needed for potentially hundreds of possible keys to be pressed.
//(NEW) our keyboard function void keyboard(unsigned char key, int x, int y) {	 switch(key)//(NEW) use a switch statement	 {	 case 'L':case'l'://(NEW) when L is pressed add to our rotation variable		 rotation += 20;		 break;	 case 'R':case'r'://Rotates the square to the right		 rotation -= 20;		 break;	 default:		 break;//Don't do anything if any other keys are pressed	 } }

we add glKeyboardFunc() to our main function to tell our program where to find our keyboard function.
void main(int argc, char ** argv) {	 glutInit(&argc, argv);	 glutInitWindowSize(800,600);	 glutInitWindowPosition(10,50);	 glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);	 glutCreateWindow("Lesson 5");	 init();	 glutDisplayFunc(display);	 glutKeyboardFunc(keyboard);//(NEW) This tells our program which function to send keyboard events to.	 glutMainLoop(); }

In the keyboard function you can use other keys than just the 'r' and 'l' keys, just use the quotes around the key you want to use. For special keys such as f3 or control I have listed what you should enter there below, you do not use quotes around the following items when using them.

I have not tested all of these and some may not work, I will post all of the possible values you can use. Again, I do not know which ones work and which ones don't, but if you want to test them and let me know which ones don't work I will take them down so I'm not giving out false information. I found these values in the windows code I did not test each of these and I do not know which keys they refer to unless the name is very obvious.

VK_LBUTTON
VK_RBUTTON
VK_CANCEL
VK_MBUTTON

VK_BACK
VK_TAB

VK_CLEAR
VK_RETURN

VK_SHIFT
VK_CONTROL
VK_MENU
VK_PAUSE
VK_CAPITAL

VK_KANA
VK_HANGEUL
VK_HANGUL
VK_JUNJA
VK_FINAL
VK_HANJA
VK_KANJI

VK_ESCAPE

VK_CONVERT
VK_NONCONVERT
VK_ACCEPT
VK_MODECHANGE

VK_SPACE
VK_PRIOR
VK_NEXT
VK_END
VK_HOME
VK_LEFT
VK_UP
VK_RIGHT
VK_DOWN
VK_SELECT
VK_PRINT
VK_EXECUTE
VK_SNAPSHOT
VK_INSERT
VK_DELETE
VK_HELP

VK_LWIN
VK_RWIN
VK_APPS

VK_NUMPAD0
VK_NUMPAD1
....
VK_NUMPAD9
VK_MULTIPLY
VK_ADD
VK_SEPARATOR
VK_SUBTRACT
VK_DECIMAL
VK_DIVIDE
VK_F1
VK_F2
.....
VK_F24

VK_NUMLOCK
VK_SCROLL

VK_LSHIFT
VK_RSHIFT
VK_LCONTROL
VK_RCONTROL
VK_LMENU
VK_RMENU

VK_ATTN
VK_CRSEL
VK_EXSEL
VK_EREOF
VK_ZOOM
VK_NONAME
VK_PA1
VK_OEM_CLEAR

Again, this was all from the code of the windows virtual key library. If you found some of the keys that don't work, please let me know and I will double check them and get rid of them. I hope this tutorial has been very informative and if there is anything I forgot to explain more please let me know, this was a bigger tutorial than the rest and the rest are just going to get bigger.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.