用opengl库在mfc 对话框程序中创建简单的opengl程序。
步骤:
1.用vs2010创建mfc dialog对话框程序
直接点击完成,创建工程结束。
2.删掉对话框上面的lable,及button按钮
3.打开对话框页,并选择“”项目“中的 ”添加类向导“ 打开添加类向导对话框,添加WM_CLOSE .
4.打开Dlg_OpenGLDlg.h文件,修改如下代码:
public:
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnClose();
HDC m_dc;
void DrawFunc();
在OnInitDialog()函数里面添加
{
m_dc = ::GetDC(m_hWnd);
PIXELFORMATDESCRIPTOR pfd;
pfd.nVersion = 1;
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.cColorBits = 32;
pfd.cDepthBits = 24;
pfd.cStencilBits = 8;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.iLayerType = PFD_MAIN_PLANE;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
int nPixelFormat = ChoosePixelFormat(m_dc, &pfd);
SetPixelFormat(m_dc, nPixelFormat, &pfd);
HGLRC rc = wglCreateContext(m_dc);
wglMakeCurrent(m_dc, rc);
glMatrixMode(GL_PROJECTION);
gluPerspective(50, 800/600, 0.1f, 1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
Texture texture;
texture.Init("test.bmp");//init opengl texture
glBindTexture(GL_TEXTURE_2D, texture.mTextureID);
SetTimer(0, 50, NULL);
其他实现函数:
void COpenGLDlg::DrawFunc()
{
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
{
glBegin(GL_TRIANGLES);//start to draw something
//glNormal3f(0.0f,1.0f,0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -0.5f, -2.0f);
//glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(2.0f, 0.0f);
glVertex3f(1.0f, -0.5f, -2.0f);
//glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0, 2.0f);
glVertex3f(-1.0f, -0.5f, -3.0f);
//glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(2.0f, 0.0f);
glVertex3f(1.0f, -0.5f, -2.0f);
//glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(2.0f, 2.0f);
glVertex3f(1.0f, -0.5f, -3.0f);
//glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0, 2.0f);
glVertex3f(-1.0f, -0.5f, -3.0f);
glEnd();//end
}
SwapBuffers(m_dc);
}
void COpenGLDlg::OnTimer(UINT_PTR nIDEvent)
{
DrawFunc();
CDialogEx::OnTimer(nIDEvent);
}
void COpenGLDlg::OnClose()
{
KillTimer(0);
::ReleaseDC(m_hWnd, m_dc);
CDialogEx::OnClose();
}
读取bmp并去掉bmp头:utils.h
#pragma once
#include <stdio.h>
unsigned char* LoadFileContent(const char*filePath);
utils.cpp
#include "utils.h"
unsigned char* LoadFileContent(const char*filePath)
{
unsigned char* fileContent = nullptr;
FILE*pFile = fopen(filePath, "rb");
if (pFile)
{
//read
fseek(pFile,0,SEEK_END);
int nLen = ftell(pFile);
if (nLen>0)
{
rewind(pFile);
fileContent = new unsigned char[nLen+1];
fread(fileContent,sizeof(unsigned char),nLen,pFile);
fileContent[nLen]='\0';
}
fclose(pFile);
}
return fileContent;
}
texture.h
#pragma once
#include <windows.h>
#include <gl/GL.h>
class Texture
{
public:
GLuint mTextureID;//gpu
void Init(const char*imagePath);
};
texture.cpp
#include "texture.h"
#include "utils.h"
unsigned char* DecodeBMP(unsigned char*bmpFileData, int&width, int&height)
{
if (0x4D42==*((unsigned short*)bmpFileData))
{
int pixelDataOffset = *((int*)(bmpFileData + 10));
width = *((int*)(bmpFileData+18));
height = *((int*)(bmpFileData + 22));
unsigned char*pixelData = bmpFileData + pixelDataOffset;
//bgr bgr bgr ....
//rgb rgb rgb
for (int i=0;i<width*height*3;i+=3)
{
unsigned char temp = pixelData[i];
pixelData[i] = pixelData[i+2];
pixelData[i+2]=temp;
}
return pixelData;
}
else
{
return nullptr;
}
}
void Texture::Init(const char*imagePath)
{
//load image file from disk to memory
unsigned char*imageFileContent = LoadFileContent(imagePath);
//decode image
int width = 0, height = 0;
unsigned char* pixelData = DecodeBMP(imageFileContent, width, height);
//generate an opengl texture
glGenTextures(1, &mTextureID);
glBindTexture(GL_TEXTURE_2D, mTextureID);
//operation on current texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixelData);
glBindTexture(GL_TEXTURE_2D, 0);
delete imageFileContent;
}
OpenGL——纹理过滤函数glTexParameteri()
图象从纹理图象空间映射到帧缓冲图象空间(映射需要重新构造纹理图像,这样就会造成应用到多边形上的图像失真),这时就可用glTexParmeteri()函数来确定如何把纹理象素映射成像素.
部分参数功能说明如下:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
GL_TEXTURE_2D: 操作2D纹理.
GL_TEXTURE_WRAP_S: S方向上的贴图模式.
GL_CLAMP: 将纹理坐标限制在0.0,1.0的范围之内.如果超出了会如何呢.不会错误,只是会边缘拉伸填充.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
这里同上,只是它是T方向
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
这是纹理过滤
GL_TEXTURE_MAG_FILTER: 放大过滤
GL_LINEAR: 线性过滤, 使用距离当前渲染像素中心最近的4个纹素加权平均值.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
GL_TEXTURE_MIN_FILTER: 缩小过滤
GL_LINEAR_MIPMAP_NEAREST: 使用GL_NEAREST对最接近当前多边形的解析度的两个层级贴图进行采样,然后用这两个值进行线性插值.
部分参数功能说明如下:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
GL_TEXTURE_2D: 操作2D纹理.
GL_TEXTURE_WRAP_S: S方向上的贴图模式.
GL_CLAMP: 将纹理坐标限制在0.0,1.0的范围之内.如果超出了会如何呢.不会错误,只是会边缘拉伸填充.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
这里同上,只是它是T方向
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
这是纹理过滤
GL_TEXTURE_MAG_FILTER: 放大过滤
GL_LINEAR: 线性过滤, 使用距离当前渲染像素中心最近的4个纹素加权平均值.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
GL_TEXTURE_MIN_FILTER: 缩小过滤
GL_LINEAR_MIPMAP_NEAREST: 使用GL_NEAREST对最接近当前多边形的解析度的两个层级贴图进行采样,然后用这两个值进行线性插值.
demo下载地址:http://download.csdn.net/detail/sz76211822/9761124