=OpenGL 3D Graphics in Liberty BASIC= ==Lesson Seven: Texture mapping== //by Robert McAllister// Texture mapping applies an image to a set of coordinates instead of a color. The program is setup to use 24-bit bitmaps, though other formats can be used. The bitmaps must be sized to a power of 2 in order to work properly with OpenGL, 2x2, 4x4, 8x8, 16x16, etc.... In my own experience 256x256 gives pretty good results. In this first sample, the call to ‘CreateBMPTexture’ loads the bitmap and gives it the name “1”. ‘glEnable GL.TEXTURE.2D’ tells OpenGL that we will be working with textures. And ‘glBindTexture GL.TEXTURE.2D , Texture’ sets texture 1 as the one we will be applying to the triangle. In the TextureVertex calls, the first two values specify the x,y position of the bitmap to use. The remaining three are the X,Y,Z coordinates of the triangle. For the bitmap coordinates, (0,0) is the bottom left, (0,1) is the top left, (1,1) is the top right and (1,0)is the bottom right. The photo below shows the x,y bitmap coordinates used for the triangle. [[code format="vbnet"]] 'triangle with partial bitmap texture CALL glClearColor .9 , .9 , .9 , 1 CALL ClearView eyeX , eyeY , eyeZ , centerX , centerY , centerZ , upX , upY , upZ Texture = 1 CALL CreateBMPTexture "OpenGL_Logo.bmp" , Texture CALL glEnable GL.TEXTURE.2D CALL glBindTexture GL.TEXTURE.2D , Texture CALL glBegin GL.TRIANGLES CALL TextureVertex .1 , .1 , -1 , -1 , 0 CALL TextureVertex .5 , .9 , 0 , 1 , 0 CALL TextureVertex .9 , .1 , 1 , -1 , 0 CALL glEnd CALL RefreshView CALL glDisable GL.TEXTURE.2D WAIT [[code]] [[Image:http://cabinetplanner.com/images/triangle.PNG]][[image:http://cabinetplanner.com/images/triangle.PNG]] These next two examples build a textured cube and a textured cylinder with the normals applied. The cylinder example shows how to apply a texture to a Quad-strip. [[code format="vbnet"]] 'cube with bitmap texture CALL ClearView eyeX , eyeY , eyeZ , centerX , centerY , centerZ , upX , upY , upZ CALL glClearColor .8 , .8 , .8 , 1 Texture = 1 CALL CreateBMPTexture "OpenGL_Logo.bmp" , Texture ' load bitmap and put in Texture #1 Width = 1.5 Height = 1.5 Depth = 1.5 CubeCenterX = 0 CubeCenterY = 0 CubeCenterZ = 0 CALL glGenLists 1 CALL glNewList 1 , 4865 CALL BuildTextureCube Width , Height , Depth , CubeCenterX , CubeCenterY , CubeCenterZ , Texture CALL glEndList FOR a = 1 TO 360 CALL ClearView eyeX , eyeY , eyeZ , centerX , centerY , centerZ , upX , upY , upZ CALL glRotatef a , 1 , 0 , 0 'CALL glRotatef a , 0 , 1 , 0 CALL glRotatef a , 0 , 0 , 1 CALL glCallList 1 CALL RefreshView CALL Pause 15 NEXT a WAIT SUB BuildTextureCube W , H , D , cX , cY , cZ , tex GL.QUADS=7 GL.TEXTURE.2D = 3553 CALL glEnable GL.TEXTURE.2D CALL glBindTexture GL.TEXTURE.2D , tex tc=1 ' change to a value greater than 1 to have the texture tiled 'front CALL glBegin GL.QUADS CALL glNormal cX-(W/2)cX-(W/2),cY-(H/2),cZ+(D/2) , cY-(H/2)cX-(W/2),cY+(H/2),cZ+(D/2) , cZ+(D/2) , cX-(W/2) , cY+(H/2) , cZ+(D/2) , cX+(W/2) , cY+(H/2) , cZ+(D/2)cX+(W/2),cY+(H/2),cZ+(D/2) CALL TextureVertex 0 , tc , cX-(W/2) , cY+(H/2) , cZ+(D/2) CALL TextureVertex tc , tc , cX+(W/2) , cY+(H/2) , cZ+(D/2) CALL TextureVertex tc , 0 , cX+(W/2) , cY-(H/2) , cZ+(D/2) CALL TextureVertex 0 , 0 , cX-(W/2) , cY-(H/2) , cZ+(D/2) CALL glEnd 'back CALL glBegin GL.QUADS CALL glNormal cX+(W/2)cX+(W/2),cY+(H/2),cZ-(D/2) , cY+(H/2)cX-(W/2),cY+(H/2),cZ-(D/2) , cZ-(D/2) , cX-(W/2) , cY+(H/2) , cZ-(D/2) , cX-(W/2) , cY-(H/2) , cZ-(D/2)cX-(W/2),cY-(H/2),cZ-(D/2) CALL TextureVertex 0 , tc , cX+(W/2) , cY+(H/2) , cZ-(D/2) CALL TextureVertex tc , tc , cX-(W/2) , cY+(H/2) , cZ-(D/2) CALL TextureVertex tc , 0 , cX-(W/2) , cY-(H/2) , cZ-(D/2) CALL TextureVertex 0 , 0 , cX+(W/2) , cY-(H/2) , cZ-(D/2) CALL glEnd 'left CALL glBegin GL.QUADS CALL glNormal cX-(W/2)cX-(W/2),cY+(H/2),cZ-(D/2) , cY+(H/2)cX-(W/2),cY+(H/2),cZ+(D/2) , cZ-(D/2) , cX-(W/2) , cY+(H/2) , cZ+(D/2) , cX-(W/2) , cY-(H/2) , cZ+(D/2)cX-(W/2),cY-(H/2),cZ+(D/2) CALL TextureVertex 0 , tc , cX-(W/2) , cY+(H/2) , cZ-(D/2) CALL TextureVertex tc , tc , cX-(W/2) , cY+(H/2) , cZ+(D/2) CALL TextureVertex tc , 0 , cX-(W/2) , cY-(H/2) , cZ+(D/2) CALL TextureVertex 0 , 0 , cX-(W/2) , cY-(H/2) , cZ-(D/2) CALL glEnd 'right CALL glBegin GL.QUADS CALL glNormal cX+(W/2)cX+(W/2),cY+(H/2),cZ+(D/2) , cY+(H/2)cX+(W/2),cY+(H/2),cZ-(D/2) , cZ+(D/2) , cX+(W/2) , cY+(H/2) , cZ-(D/2) , cX+(W/2) , cY-(H/2) , cZ-(D/2)cX+(W/2),cY-(H/2),cZ-(D/2) CALL TextureVertex 0 , tc , cX+(W/2) , cY+(H/2) , cZ+(D/2) CALL TextureVertex tc , tc , cX+(W/2) , cY+(H/2) , cZ-(D/2) CALL TextureVertex tc , 0 , cX+(W/2) , cY-(H/2) , cZ-(D/2) CALL TextureVertex 0 , 0 , cX+(W/2) , cY-(H/2) , cZ+(D/2) CALL glEnd 'top CALL glBegin GL.QUADS CALL glNormal cX-(W/2)cX-(W/2),cY+(H/2),cZ+(D/2) , cY+(H/2)cX-(W/2),cY+(H/2),cZ-(D/2) , cZ+(D/2) , cX-(W/2) , cY+(H/2) , cZ-(D/2) , cX+(W/2) , cY+(H/2) , cZ-(D/2)cX+(W/2),cY+(H/2),cZ-(D/2) CALL TextureVertex 0 , tc , cX-(W/2) , cY+(H/2) , cZ+(D/2) CALL TextureVertex tc , tc , cX-(W/2) , cY+(H/2) , cZ-(D/2) CALL TextureVertex tc , 0 , cX+(W/2) , cY+(H/2) , cZ-(D/2) CALL TextureVertex 0 , 0 , cX+(W/2) , cY+(H/2) , cZ+(D/2) CALL glEnd 'bottom CALL glBegin GL.QUADS CALL glNormal cX-(W/2)cX-(W/2),cY-(H/2),cZ+(D/2) , cY-(H/2)cX+(W/2),cY-(H/2),cZ+(D/2) , cZ+(D/2) , cX+(W/2) , cY-(H/2) , cZ+(D/2) , cX+(W/2) , cY-(H/2) , cZ-(D/2)cX+(W/2),cY-(H/2),cZ-(D/2) CALL TextureVertex 0 , tc , cX-(W/2) , cY-(H/2) , cZ+(D/2) CALL TextureVertex tc , tc , cX+(W/2) , cY-(H/2) , cZ+(D/2) CALL TextureVertex tc , 0 , cX+(W/2) , cY-(H/2) , cZ-(D/2) CALL TextureVertex 0 , 0 , cX-(W/2) , cY-(H/2) , cZ-(D/2) CALL glEnd CALL glDisable GL.TEXTURE.2D END SUB [[code]] [[code format="vbnet"]] ' build a textured cylinder CALL ClearView eyeX , eyeY , eyeZ , centerX , centerY , centerZ , upX , upY , upZ CALL glClearColor .8 , .8 , .8 , 1 Texture = 1 CALL CreateBMPTexture "OpenGL_Logo.bmp" , Texture ' load texture and put it in texture #1 Angle = 110 Width = .5 Depth = .5 Height = 2 cX = 0 cY = 0 cZ = 0 Red = .5 Green = 0 Blue = 0 Sides = 200 CALL glGenLists 1 CALL glNewList 1 , 4865 CALL BuildTextureCylinder Angle , Width , Depth , Height , cX , cY , cZ , Texture , Sides CALL glEndList FOR a = 1 TO 360 CALL ClearView eyeX , eyeY , eyeZ , centerX , centerY , centerZ , upX , upY , upZ CALL glRotatef a , 1 , 0 , 0 CALL glRotatef a , 0 , 1 , 0 'CALL glRotatef a , 0 , 0 , 1 CALL glCallList 1 CALL RefreshView CALL Pause 15 NEXT a WAIT SUB BuildTextureCylinder Angle , W , D , H , cX , cY , cZ , tex , Sides GL.QUAD.STRIP = 8 GL.TEXTURE.2D = 3553 CALL glEnable GL.TEXTURE.2D CALL glBindTexture GL.TEXTURE.2D , tex PI = 3.14159265 sin.angle = Sin(Angle * PI / 180) cos.angle = Cos(Angle * PI / 180) theta = 0 dtheta = 2 * PI / Sides TexCoordinate=1 XOval = W * Cos(theta) YOval = D * Sin(theta) X1 = cX + XOval * cos.angle - YOval * sin.angle Z1 = cZ - XOval * sin.angle - YOval * cos.angle ' X2 , Z2 values for the first glNormal call XOval = W * Cos(dtheta) YOval = D * Sin(dtheta) X2 = cX + XOval * cos.angle - YOval * sin.angle Z2 = cZ - XOval * sin.angle - YOval * cos.angle CALL glBegin GL.QUAD.STRIP WHILE theta < 2 * PI CALL glNormal X1 , cY+(H/2) , Z1 , X2 , cY+(H/2) , Z2 , X1 , cY-(H/2) , Z1 CALL TextureVertex TexCoordinate , 1 , X1 , cY+(H/2) , Z1 CALL TextureVertex TexCoordinate , 0 , X1 , cY-(H/2) , Z1 theta = theta + dtheta XOval = W * Cos(theta) YOval = D * Sin(theta) X2 = X1 Z2 = Z1 X1 = cX + XOval * cos.angle + YOval * sin.angle Z1 = cZ - XOval * sin.angle + YOval * cos.angle TexCoordinate = TexCoordinate - (1/Sides) WEND CALL glNormal X1 , cY+(H/2) , Z1 , X2 , cY+(H/2) , Z2 , X1 , cY-(H/2) , Z1 CALL TextureVertex TexC , 1 , X1 , cY+(H/2) , Z1 CALL TextureVertex TexC , 0 , X1 , cY-(H/2) , Z1 CALL glEnd END SUB [[code]] Next we will be creating "Transparent surfaces and fog"