Code download
# Include "CELLWinApp. hpp"
# Include <gl/GLU. h>
# Include <assert. h>
# Include <math. h>
# Pragma comment (lib, "opengl32.lib ")
# Pragma comment (lib, "glu32.lib ")
# Pragma comment (lib, "winmm. lib ")
/**
* This example describes how to use
GlEnableClientState,
GlVertexPointer.
GlColorPointer,
GlTexCoordPointer,
GlDrawArrays
Draw Functions
In the preceding example, three buffers, fixed-point buffers, texture buffers, and color buffers are used.
* When there are more buffers, flexibility increases, but management is troublesome.
OpenGL also supports a separate buffer.
*/
Struct Vertex
{
Float x, y, z;
Float u, v;
Float r, g, B;
};
Vertex g_cubeVertices [] =
{
{-1.0f,-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f },
{1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f },
{1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f },
{-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f },
{-1.0f,-1.0f,-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f },
{-1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f },
{1.0f, 1.0f,-1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
{1.0f,-1.0f,-1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f },
{-1.0f, 1.0f,-1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
{-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f },
{1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f },
{1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f },
{-1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
{1.0f,-1.0f,-1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f },
{1.0f,-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f },
{-1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f },
{1.0f,-1.0f,-1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f },
{1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
{1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f },
{1.0f,-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
{-1.0f,-1.0f,-1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f },
{-1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f },
{-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f },
{-1.0f, 1.0f,-1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f}
};
Class Tutorial7: public CELL: Graphy: CELLWinApp
{
Public:
Tutorial7 (HINSTANCE hInstance)
: CELL: Graphy: CELLWinApp (hInstance)
{
_ LbtnDownFlag = false;
_ FSpinY = 0;
_ FSpinX = 0;
}
Virtual void render ()
{
Do
{
GlClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
GlMatrixMode (GL_MODELVIEW );
GlLoadIdentity ();
GlTranslatef (0.0f, 0.0f,-5.0f );
GlRotatef (-_ fSpinY, 1.0f, 0.0f, 0.0f );
GlRotatef (-_ fSpinX, 0.0f, 1.0f, 0.0f );
GlEnableClientState (GL_VERTEX_ARRAY );
Glableclientstate (GL_COLOR_ARRAY );
GlEnableClientState (GL_TEXTURE_COORD_ARRAY );
/**
* You can learn more about it here.
*/
Float * addrVertex = (float *) g_cubeVertices;
Float * uvAddress = (float *) & g_cubeVertices [0]. u;
Float * colorAddress = (float *) & g_cubeVertices [0]. r;
// -------------- Number of elements --- Element type --- memory offset between elements --- data address
// OpenGL calculates the position of the next element based on the memory offset between elements.
GlVertexPointer (3, GL_FLOAT, sizeof (Vertex), addrVertex );
GlColorPointer (3, GL_FLOAT, sizeof (Vertex), colorAddress );
GlTexCoordPointer (2, GL_FLOAT, sizeof (Vertex), uvAddress );
GlDrawArrays (GL_QUADS, 0, 24 );
GlDisableClientState (GL_VERTEX_ARRAY );
GlDisableClientState (GL_COLOR_ARRAY );
GlDisableClientState (GL_TEXTURE_COORD_ARRAY );
SwapBuffers (_ hDC );
} While (false );
}
/**
* Generate a projection matrix
* For reusability, We will write a special matrix class to complete a series of matrix polishing.
* This is very important. When you constantly learn about Opengl, you will find that many of them are related to mathematics.
*/
Void perspective (float fovy, float aspect, float zNear, float zFar, float matrix [4] [4])
{
Assert (aspect! = Float (0 ));
Assert (zFar! = ZNear );
# Define PI 3.14159265358979323f
Float rad = fovy * (PI/180 );
Float halfFovy = tan (rad/float (2 ));
Matrix [0] [0] = float (1)/(aspect * halfFovy );
Matrix [1] [1] = float (1)/(halfFovy );
Matrix [2] [2] =-(zFar + zNear)/(zFar-zNear );
Matrix [2] [3] =-float (1 );
Matrix [3] [2] =-(float (2) * zFar * zNear)/(zFar-zNear );
# Undef PI
}
Virtual void onInit ()
{
/**
* Call the function of the parent class.
*/
CELL: Graphy: CELLWinApp: onInit ();
GlMatrixMode (GL_PROJECTION );
GLfloat matrix [4] [4] =
{
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0
};
Perspective (45.0f, (GLfloat) _ winWidth/(GLfloat) _ winHeight, 0.1f, 1001_f, matrix );
GlLoadMatrixf (float *) matrix );
GlClearColor (0, 0, 0, 1 );
/**
* Add the following two sentences:
* GlEnable (GL_DEPTH_TEST); start the deep test. In this way, the masked computation will be overwritten.
* GlEnable (GL_TEXTURE_2D); starts the texture and supports texture textures to draw the texture.
*/
GlEnable (GL_DEPTH_TEST );
Glable (GL_TEXTURE_2D );
/**
* Read a bmp Image
*/
HBITMAP hBmp = (HBITMAP) LoadImageA (0, "1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
/**
* Obtain the image size.
*/
Bitmap bmp = {0 };
GetObject (hBmp, sizeof (bmp inf), & BMP inf );
/**
* Obtain the color data (r, g, B) of the image)
*/
Int size = BMP. bmHeight * BMP. bmWidth * 3;
Char * data = new char [size];
BITMAPINFO bi;
Bi. bmiHeader. biSize = sizeof (bi. bmiHeader );
Bi. bmiHeader. biWidth = BMP. bmWidth;
Bi. bmiHeader. biHeight = BMP. bmHeight;
Bi. bmiHeader. biPlanes = 1;
Bi. bmiHeader. biBitCount = 24;
Bi. bmiHeader. biCompression = BI_RGB;
Bi. bmiHeader. biSizeImage = size;
Bi. bmiHeader. biClrUsed = 0;
Bi. bmiHeader. biClrImportant = 0;
/**
* Obtain rgb data
*/
Int idata = GetDIBits (_ hDC, hBmp, 0, bi. bmiHeader. biHeight, data, & bi, DIB_RGB_COLORS );
/**
* Generate a texture Id, which can be considered as a texture handle. The subsequent operations will use this texture id.
*/
GlGenTextures (1, & _ textureId );
/**
* Use this texture id, or BIND (Associate)
*/
GlBindTexture (GL_TEXTURE_2D, _ textureId );
/**
* This parameter is used to zoom in or out the texture. The linear method is used, that is, the interpolation method when the image is enlarged.
*/
GlTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
GlTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
/**
* Upload the rgb data of the image to opengl.
*/
GlTexImage2D (
GL_TEXTURE_2D ,//! Specify a two-dimensional image
0 ,//! The first level is specified, and the texture can be used as the mipmap, that is, the level is large when it is near, and the smaller texture is used when it is far away.
GL_RGB ,//! Storage format used for texture
Bmp inf. bmWidth ,//! The width. Older graphics cards do not support irregular textures, that is, the width and height are not 2 ^ n.
Bmp inf. bmHeight ,//! The width. Older graphics cards do not support irregular textures, that is, the width and height are not 2 ^ n.
0 ,//! Edge?
GL_BGR_EXT ,//! Data format: the data stored in bmp, windows, and operating systems is in bgr format.
GL_UNSIGNED_BYTE ,//! 8-Bit Data
Data
);
Delete [] data;
/**
* Deleting an image
*/
DeleteObject (hBmp );
}
Virtual int events (unsigned msg, unsigned wParam, unsigned lParam)
{
Switch (msg)
{
Case WM_LBUTTONDOWN:
{
_ MousePos. x = LOWORD (lParam );
_ MousePos. y = HIWORD (lParam );
_ LbtnDownFlag = true;
SetCapture (_ hWnd );
}
Break;
Case WM_LBUTTONUP:
{
_ LbtnDownFlag = false;
ReleaseCapture ();
}
Break;
Case WM_MOUSEMOVE:
{
Int curX = LOWORD (lParam );
Int curY = HIWORD (lParam );
If (_ lbtnDownFlag)
{
_ FSpinX-= (curX-_ mousePos. x );
_ FSpinY-= (curY-_ mousePos. y );
}
_ MousePos. x = curX;
_ MousePos. y = curY;
}
Break;
}
Return _ super: events (msg, wParam, lParam );
}
Protected:
Unsigned _ primitiveType;
/**
* Save the texture Id
*/
Unsigned _ textureId;
Float _ fSpinX;
Float _ fSpinY;
POINT _ mousePos;
Bool _ lbtnDownFlag;
};
Int CALLBACK _ tWinMain (
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
Int nShowCmd
)
{
(Void *) hInstance;
(Void *) hPrevInstance;
(Void *) lpCmdLine;
(Void *) nShowCmd;
Tutorial7 winApp (hInstance );
WinApp. start (640,480 );
Return 0;
}