OpenGL显示中文和旋转立方体贴图

18 篇文章 0 订阅
11 篇文章 0 订阅

显示文字的 "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;
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值