下面是我的源代码:
#include<windows.h>
#include<gl/gl.h>
#include<gl/glu.h>
#include<stdio.h>#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")HINSTANCE hInst=NULL;
HWND hWnd=NULL;
HDC hdc=NULL;
HGLRC hglrc=NULL;
BITMAPINFO *pbmpInfo=NULL;
PBYTE pbmpData=NULL;
char *file="opengl.bmp";ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hInstance);
BOOL InitGL();
BOOL Resize(int height,int width);
BOOL Render();
BOOL Recycle();
HRESULT MsgLoop();
HRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
BOOL Loadbmp(char *file);int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine,int nCmdShow)
{
HRESULT hResult;
if(!MyRegisterClass(hInstance))
{
return FALSE;
}
if(!InitInstance(hInstance))
{
Recycle();
return FALSE;
}
if(!InitGL())
{
Recycle();
return FALSE;
}
if(!Loadbmp(file))
{
Recycle();
return FALSE;
}
MoveWindow(hWnd,10,10,600,450,true);
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
hResult=MsgLoop();
Recycle();
return hResult;
}ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize=sizeof(WNDCLASSEX);
wcex.style=CS_HREDRAW|CS_VREDRAW;
wcex.lpfnWndProc=(WNDPROC)WndProc;
wcex.cbClsExtra=0;
wcex.cbWndExtra=0;
wcex.hInstance=hInstance;
wcex.hIcon=LoadIcon(NULL,IDI_WINLOGO);
wcex.hCursor=LoadCursor(NULL,IDC_ARROW);
wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName=NULL;
wcex.lpszClassName="OpenGL";
wcex.hIconSm=NULL;
return RegisterClassEx(&wcex);
}BOOL InitInstance(HINSTANCE hInstance)
{
hInst=hInstance;
hWnd=CreateWindow("OpenGL","OpenGL",WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);
if(!hWnd)
{
return FALSE;
}
return TRUE;
}HRESULT MsgLoop()
{
MSG msg;
while(TRUE)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message==WM_QUIT)
{
return FALSE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
//idle
}
}
}LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
PAINTSTRUCT ps;
switch(message)
{
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
//
Render();
EndPaint(hWnd,&ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SIZE:
if(wParam==SIZE_RESTORED||wParam==SIZE_MAXIMIZED)
{
Resize((int)LOWORD(lParam),(int)HIWORD(lParam));
}
break;
case WM_ERASEBKGND:
return TRUE;
break;
default:
return DefWindowProc(hWnd,message,wParam,lParam);
}
return 0;
}BOOL Recycle()
{
if(hglrc!=NULL)
{
wglMakeCurrent(NULL,NULL);
wglDeleteContext(hglrc);
hglrc=NULL;
}
if(hdc!=NULL)
{
DeleteDC(hdc);
hdc=NULL;
}
if(pbmpData!=NULL)
{
free(pbmpData);
pbmpData=NULL;
}
if(pbmpInfo!=NULL)
{
free(pbmpInfo);
pbmpInfo=NULL;
}
if(hWnd!=NULL)
{
DestroyWindow(hWnd);
hWnd=NULL;
}
UnregisterClass("OpenGL",hInst);
return TRUE;
}BOOL InitGL()
{
int iPixelFormat;
hdc=GetDC(hWnd);
if(hdc==NULL)
{
return FALSE;
}
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
24, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
}; iPixelFormat = ChoosePixelFormat(hdc, &pfd);
if(iPixelFormat==0)
{
return FALSE;
}
if(!SetPixelFormat(hdc, iPixelFormat, &pfd))
{
return FALSE;
}
hglrc=wglCreateContext(hdc);
if(hglrc==NULL)
{
return FALSE;
}
if(!wglMakeCurrent(hdc,hglrc))
{
return FALSE;
}
return TRUE;
}BOOL Resize(int width,int height)
{
if(width<=0||height<=0)
{
return FALSE;
}
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0,400.0,0.0,300.0,-1.0,1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0,0.0,0.0,0.0);
return TRUE;
}BOOL Render()
{
RECT rect;
GLfloat xZoom,yZoom,minZoom;
GLfloat xoffset,yoffset;
GetClientRect(hWnd,&rect);
xZoom=(GLfloat)(rect.right-rect.left)/pbmpInfo->bmiHeader.biWidth;
yZoom=(GLfloat)(rect.bottom-rect.top)/pbmpInfo->bmiHeader.biHeight;
minZoom=xZoom>yZoom?yZoom:xZoom;
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPixelStorei(GL_UNPACK_ALIGNMENT,4);
glPixelZoom(minZoom,minZoom);
if (xZoom>yZoom)
{
xoffset=((GLfloat)(rect.right-rect.left)-(GLfloat)pbmpInfo->bmiHeader.biWidth*minZoom)*0.5;
glRasterPos2f(xoffset,0.0);
}
else
{
yoffset=((GLfloat)(rect.bottom-rect.top)-(GLfloat)pbmpInfo->bmiHeader.biHeight*minZoom)*0.5;
glRasterPos2f(0.0,yoffset);
} glDrawPixels(pbmpInfo->bmiHeader.biWidth,pbmpInfo->bmiHeader.biHeight,GL_BGR_EXT,GL_UNSIGNED_BYTE,pbmpData);
SwapBuffers(hdc);
return TRUE;
}BOOL Loadbmp(char *file)
{
BITMAPFILEHEADER bfh;
PBITMAPINFO bmpinfo=NULL; //infoheader
DWORD dwBytes;//infoheadersize
FILE *f=fopen(file,"rb");
if(f==NULL)
{
return FALSE;
}
if(fread(&bfh,1,sizeof(BITMAPFILEHEADER),f)!=sizeof(BITMAPFILEHEADER))
{
fclose(f);
return FALSE;
}
if(bfh.bfType!=0x4d42)//BM
{
fclose(f);
return FALSE;
}
dwBytes=bfh.bfOffBits-sizeof(BITMAPFILEHEADER);
bmpinfo=(PBITMAPINFO)malloc(dwBytes);
if(dwBytes==NULL)
{
fclose(f);
return FALSE;
}
if(fread(bmpinfo,1,dwBytes,f)!=dwBytes)
{
free(bmpinfo);
bmpinfo=NULL;
fclose(f);
return FALSE;
}
if(bmpinfo->bmiHeader.biBitCount<24)
{
free(bmpinfo);
bmpinfo=NULL;
fclose(f);
return FALSE;
}
if(bmpinfo->bmiHeader.biSizeImage==0)
{
bmpinfo->bmiHeader.biSizeImage=bmpinfo->bmiHeader.biWidth*
bmpinfo->bmiHeader.biHeight*
((bmpinfo->bmiHeader.biBitCount+7)/8);
}
pbmpInfo=bmpinfo;
pbmpData=(PBYTE)malloc(bmpinfo->bmiHeader.biSizeImage);
if(pbmpData==NULL)
{
fclose(f);
return FALSE;
}
if(fread(pbmpData,1,bmpinfo->bmiHeader.biSizeImage,f)!=bmpinfo->bmiHeader.biSizeImage)
{
fclose(f);
return FALSE;
}
fclose(f);
return TRUE;
}
图片显示出来,就是没有办法居中(这是我想达到的效果)。我想是Render()函数写得不对,请高手指点一下,怎么改,谢谢!
代码有点长,请各位高手见谅!
#include<windows.h>
#include<gl/gl.h>
#include<gl/glu.h>
#include<stdio.h>#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")HINSTANCE hInst=NULL;
HWND hWnd=NULL;
HDC hdc=NULL;
HGLRC hglrc=NULL;
BITMAPINFO *pbmpInfo=NULL;
PBYTE pbmpData=NULL;
char *file="opengl.bmp";ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hInstance);
BOOL InitGL();
BOOL Resize(int height,int width);
BOOL Render();
BOOL Recycle();
HRESULT MsgLoop();
HRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
BOOL Loadbmp(char *file);int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine,int nCmdShow)
{
HRESULT hResult;
if(!MyRegisterClass(hInstance))
{
return FALSE;
}
if(!InitInstance(hInstance))
{
Recycle();
return FALSE;
}
if(!InitGL())
{
Recycle();
return FALSE;
}
if(!Loadbmp(file))
{
Recycle();
return FALSE;
}
MoveWindow(hWnd,10,10,600,450,true);
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
hResult=MsgLoop();
Recycle();
return hResult;
}ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize=sizeof(WNDCLASSEX);
wcex.style=CS_HREDRAW|CS_VREDRAW;
wcex.lpfnWndProc=(WNDPROC)WndProc;
wcex.cbClsExtra=0;
wcex.cbWndExtra=0;
wcex.hInstance=hInstance;
wcex.hIcon=LoadIcon(NULL,IDI_WINLOGO);
wcex.hCursor=LoadCursor(NULL,IDC_ARROW);
wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName=NULL;
wcex.lpszClassName="OpenGL";
wcex.hIconSm=NULL;
return RegisterClassEx(&wcex);
}BOOL InitInstance(HINSTANCE hInstance)
{
hInst=hInstance;
hWnd=CreateWindow("OpenGL","OpenGL",WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);
if(!hWnd)
{
return FALSE;
}
return TRUE;
}HRESULT MsgLoop()
{
MSG msg;
while(TRUE)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message==WM_QUIT)
{
return FALSE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
//idle
}
}
}LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
PAINTSTRUCT ps;
switch(message)
{
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
//
Render();
EndPaint(hWnd,&ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SIZE:
if(wParam==SIZE_RESTORED||wParam==SIZE_MAXIMIZED)
{
Resize((int)LOWORD(lParam),(int)HIWORD(lParam));
}
break;
case WM_ERASEBKGND:
return TRUE;
break;
default:
return DefWindowProc(hWnd,message,wParam,lParam);
}
return 0;
}BOOL Recycle()
{
if(hglrc!=NULL)
{
wglMakeCurrent(NULL,NULL);
wglDeleteContext(hglrc);
hglrc=NULL;
}
if(hdc!=NULL)
{
DeleteDC(hdc);
hdc=NULL;
}
if(pbmpData!=NULL)
{
free(pbmpData);
pbmpData=NULL;
}
if(pbmpInfo!=NULL)
{
free(pbmpInfo);
pbmpInfo=NULL;
}
if(hWnd!=NULL)
{
DestroyWindow(hWnd);
hWnd=NULL;
}
UnregisterClass("OpenGL",hInst);
return TRUE;
}BOOL InitGL()
{
int iPixelFormat;
hdc=GetDC(hWnd);
if(hdc==NULL)
{
return FALSE;
}
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
24, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
}; iPixelFormat = ChoosePixelFormat(hdc, &pfd);
if(iPixelFormat==0)
{
return FALSE;
}
if(!SetPixelFormat(hdc, iPixelFormat, &pfd))
{
return FALSE;
}
hglrc=wglCreateContext(hdc);
if(hglrc==NULL)
{
return FALSE;
}
if(!wglMakeCurrent(hdc,hglrc))
{
return FALSE;
}
return TRUE;
}BOOL Resize(int width,int height)
{
if(width<=0||height<=0)
{
return FALSE;
}
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0,400.0,0.0,300.0,-1.0,1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0,0.0,0.0,0.0);
return TRUE;
}BOOL Render()
{
RECT rect;
GLfloat xZoom,yZoom,minZoom;
GLfloat xoffset,yoffset;
GetClientRect(hWnd,&rect);
xZoom=(GLfloat)(rect.right-rect.left)/pbmpInfo->bmiHeader.biWidth;
yZoom=(GLfloat)(rect.bottom-rect.top)/pbmpInfo->bmiHeader.biHeight;
minZoom=xZoom>yZoom?yZoom:xZoom;
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPixelStorei(GL_UNPACK_ALIGNMENT,4);
glPixelZoom(minZoom,minZoom);
if (xZoom>yZoom)
{
xoffset=((GLfloat)(rect.right-rect.left)-(GLfloat)pbmpInfo->bmiHeader.biWidth*minZoom)*0.5;
glRasterPos2f(xoffset,0.0);
}
else
{
yoffset=((GLfloat)(rect.bottom-rect.top)-(GLfloat)pbmpInfo->bmiHeader.biHeight*minZoom)*0.5;
glRasterPos2f(0.0,yoffset);
} glDrawPixels(pbmpInfo->bmiHeader.biWidth,pbmpInfo->bmiHeader.biHeight,GL_BGR_EXT,GL_UNSIGNED_BYTE,pbmpData);
SwapBuffers(hdc);
return TRUE;
}BOOL Loadbmp(char *file)
{
BITMAPFILEHEADER bfh;
PBITMAPINFO bmpinfo=NULL; //infoheader
DWORD dwBytes;//infoheadersize
FILE *f=fopen(file,"rb");
if(f==NULL)
{
return FALSE;
}
if(fread(&bfh,1,sizeof(BITMAPFILEHEADER),f)!=sizeof(BITMAPFILEHEADER))
{
fclose(f);
return FALSE;
}
if(bfh.bfType!=0x4d42)//BM
{
fclose(f);
return FALSE;
}
dwBytes=bfh.bfOffBits-sizeof(BITMAPFILEHEADER);
bmpinfo=(PBITMAPINFO)malloc(dwBytes);
if(dwBytes==NULL)
{
fclose(f);
return FALSE;
}
if(fread(bmpinfo,1,dwBytes,f)!=dwBytes)
{
free(bmpinfo);
bmpinfo=NULL;
fclose(f);
return FALSE;
}
if(bmpinfo->bmiHeader.biBitCount<24)
{
free(bmpinfo);
bmpinfo=NULL;
fclose(f);
return FALSE;
}
if(bmpinfo->bmiHeader.biSizeImage==0)
{
bmpinfo->bmiHeader.biSizeImage=bmpinfo->bmiHeader.biWidth*
bmpinfo->bmiHeader.biHeight*
((bmpinfo->bmiHeader.biBitCount+7)/8);
}
pbmpInfo=bmpinfo;
pbmpData=(PBYTE)malloc(bmpinfo->bmiHeader.biSizeImage);
if(pbmpData==NULL)
{
fclose(f);
return FALSE;
}
if(fread(pbmpData,1,bmpinfo->bmiHeader.biSizeImage,f)!=bmpinfo->bmiHeader.biSizeImage)
{
fclose(f);
return FALSE;
}
fclose(f);
return TRUE;
}
图片显示出来,就是没有办法居中(这是我想达到的效果)。我想是Render()函数写得不对,请高手指点一下,怎么改,谢谢!
代码有点长,请各位高手见谅!
我帮你看看,我以前做过一些opengl的课题,可以帮你试试
比如将名字改为opengl.cpp,那么可以这样编译:
cl opengl.cpp(你的计算机上面要安装有visual C++才行)
再找一张位图,24位深度的(目前只支持24位深度的,这样的位图文件没有压缩,容易操作),将名字改为opengl.bmp,再运行编译好的exe文件,你就能看到效果了。