显示文字的 "word.h":
#include"stdafx.h"
#define GLUT_DISABLE_ATEXIT_HACK
#include<stdlib.h>
#include<GL/GLUT.H>
#include <windows.h>
#define MAX_CHAR 128
void drawString(const char* str) //写出英文
{
static int isFirstCall = 1;
static GLuint lists;
if (isFirstCall) { // 如果是第一次调用,执行初始化
// 为每一个ASCII字符产生一个显示列表
isFirstCall = 0;
// 申请MAX_CHAR个连续的显示列表编号
lists = glGenLists(MAX_CHAR);
// 把每个字符的绘制命令都装到对应的显示列表中
wglUseFontBitmaps(wglGetCurrentDC(), 0, MAX_CHAR, lists);
}
// 调用每个字符对应的显示列表,绘制每个字符
for (; *str != '\0'; ++str)
glCallList(lists + *str);
}
void selectFont(int size, int charset, const char* face) {
HFONT hFont = CreateFontA(size, 0, 0, 0, FW_MEDIUM, 0, 0, 0,
charset, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, face);
HFONT hOldFont = (HFONT)SelectObject(wglGetCurrentDC(), hFont);
DeleteObject(hOldFont);
}
void drawCNString(const char* str) //写出中文
{
int len, i;
wchar_t* wstring;
HDC hDC = wglGetCurrentDC();
GLuint list = glGenLists(1);
// 计算字符的个数
// 如果是双字节字符的(比如中文字符),两个字节才算一个字符
// 否则一个字节算一个字符
len = 0;
for (i = 0; str[i] != '\0'; ++i)
{
if (IsDBCSLeadByte(str[i]))
++i;
++len;
}
// 将混合字符转化为宽字符
wstring = (wchar_t*)malloc((len + 1) * sizeof(wchar_t));
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstring, len);
wstring[len] = L'\0';
// 逐个输出字符
for (i = 0; i<len; ++i)
{
wglUseFontBitmapsW(hDC, wstring[i], 1, list);
glCallList(list);
}
// 回收所有临时资源
free(wstring);
glDeleteLists(list, 1);
}
void poem(void) {
glPushMatrix();
glTranslatef(-1.0f, -0.2f, -5.0f);
/*selectFont(48, ANSI_CHARSET, "Comic Sans MS");
glColor3f(1.0f, 0.0f, 0.0f);
glRasterPos2f(-0.7f, 0.4f);
drawString("Hello, World!");*/
selectFont(48, GB2312_CHARSET, "楷体_GB2312");
glColor3f(1.0f, 0.0f, 1.0f);
glRasterPos2f(-0.4f, 0.9f);
drawCNString("假如生活欺骗了你");
selectFont(24, DEFAULT_CHARSET, "华文新魏");
glColor3f(0.0f, 0.0f, 1.0f);
glRasterPos2f(0.2f, 0.7f);
drawCNString("普希金");
glColor3f(0.0f, 0.0f, 1.0f);
glRasterPos2f(-0.3f, 0.5f);
drawCNString(" 假如生活欺骗了你,");
glRasterPos2f(-0.3f, 0.4f);
drawCNString(" 不要悲伤,不要心急!");
glRasterPos2f(-0.3f, 0.3f);
drawCNString(" 忧郁的日子里需要镇静;");
glRasterPos2f(-0.3f, 0.2f);
drawCNString(" 相信吧,快乐的日子将会来临。");
glRasterPos2f(-0.3f, 0.1f);
drawCNString(" 心儿永远向往着未来;");
glRasterPos2f(-0.3f, 0.0f);
drawCNString(" 现在却常是忧郁。");
glRasterPos2f(-0.3f, -0.1f);
drawCNString(" 一切都是瞬息,");
glRasterPos2f(-0.3f, -0.2f);
drawCNString(" 一切都将会过去,");
glRasterPos2f(-0.3f, -0.3f);
drawCNString(" 而那过去了的,");
glRasterPos2f(-0.3f, -0.4f);
drawCNString(" 就会成为亲切的怀恋。");
glPopMatrix();
}
显示背景的"立方体贴图.cpp":
// 立方体贴图3.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include"word.h"
#define GLUT_DISABLE_ATEXIT_HACK
#pragma comment(lib, "glaux.lib")
#include <glaux.h>
#include <gl\glut.h>
GLuint g_texture = 0;
GLfloat xrot = 0;
GLfloat yrot = 0;
GLfloat zrot = 0; // Keep Going
//绘制一个立方体
void DrawCube(void)
{
glPushMatrix();
glTranslatef(1.0, 0.0, -5.0);
glScalef(0.3, 0.3, 0.3);
glBindTexture(GL_TEXTURE_2D, g_texture); //使用贴图纹理
glPushMatrix(); //压入变换矩阵
glRotatef(xrot, 1.0f, 0.0f, 0.0f); //旋转矩阵,这里绕x轴旋转。
glRotatef(yrot, 0.0f, 1.0f, 0.0f); //旋转矩阵,这里绕y轴旋转。
glRotatef(zrot, 0.0f, 0.0f, 1.0f); //绕z轴旋转,这里zrot是角度制的度数。
glBegin(GL_QUADS); //启用四边形带绘制模式绘制
// 绘制前面,这里开始确定纹理坐标,然后是确定点的位置
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// 绘制后面
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f);
// 上面
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f);
//底面
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// 右面
glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
// 左面
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glPopMatrix(); //弹出变换矩阵
glPopMatrix();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清楚颜色数据和深度数据(清屏)
glLoadIdentity();
DrawCube();
//glTranslatef(0.0, -1.0f, 0.0f);
poem();// Reset The View
glColor3f(1.0, 1.0, 1.0);
glutSwapBuffers(); //交换缓冲区。显示图形
}
//载入一个.bmp格式的贴图纹理
int LoadGLTextures(GLuint& unTexture, const char* chFileName)
{
AUX_RGBImageRec *TextureImage; //保存贴图数据的指针
TextureImage = auxDIBImageLoad(L"Data/tu.bmp"); //载入贴图数据
glGenTextures(1, &unTexture); // 创建一个纹理,unTexture
glBindTexture(GL_TEXTURE_2D, unTexture); //绑定纹理,然后对该纹理区添加纹理数据
//设置纹理的信息,
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage->sizeX, TextureImage->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage->data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //设置滤波为线性滤波
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //线性滤波
if (TextureImage) //释放资源
{
if (TextureImage->data)
{
free(TextureImage->data);
}
free(TextureImage);
}
return 1;
}
//初始化
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0); //清理颜色,为黑色,(也可认为是背景颜色)
glCullFace(GL_BACK); //背面裁剪(背面不可见)
glEnable(GL_CULL_FACE); //启用裁剪
glEnable(GL_TEXTURE_2D);
LoadGLTextures(g_texture, "Data/tu.bmp"); //载入纹理贴图
}
//当窗口大小改变时,会调用这个函数
void reshape(GLsizei w, GLsizei h)
{
//这里小说明一下:矩阵模式是不同的,他们各自有一个矩阵。投影相关
//只能用投影矩阵。(只是目前情况下哦,等我学多了可能就知道为什么了。)
glViewport(0, 0, w, h); //设置视口
glMatrixMode(GL_PROJECTION); //设置矩阵模式为投影变换矩阵,
glLoadIdentity(); //变为单位矩阵
gluPerspective(30, (GLfloat)w / h, 0, 1000); //设置投影矩阵
glMatrixMode(GL_MODELVIEW); //设置矩阵模式为视图矩阵(模型)
glLoadIdentity(); //变为单位矩阵
}
//闲置函数,当主循环空闲时就会调用这个函数
void MyIdle(void)
{
Sleep(10);
xrot += 0.3f; //增加旋转的角度。
yrot += 0.2f;
zrot += 0.4f;
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv); //Opnegl初始化
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); //设置显示模式为双缓冲,RGEBA
glutInitWindowSize(900, 700); //窗口大小
glutInitWindowPosition(100, 100); //窗口位置
glutCreateWindow("hello"); //创建一个标题为hello的窗口
init(); //初始化资源,这里一定要在创建窗口以后,不然会无效。
glutDisplayFunc(display); //窗口大小改变时的回调
glutReshapeFunc(reshape); //绘制图形时的回调
glutIdleFunc(MyIdle);
glutMainLoop(); //主循环。
return 0;
}