OpenGL织梦之旅【第三章】第2节.循环显示图片
来源:互联网 发布:苗立杰wnba数据 编辑:程序博客网 时间:2024/06/05 02:41
这节我们将读取几个图片,生成一个纹理集,然后让程序循环显示图片。
为了方便,我直接把图片的数量和每个图片的名字保存在一个txt文档里面,方便程序地读取。
如:
在init函数中,打开data.txt,读取图片的数量和图片的名字,然后调用LoadBitmap函数,把所生成的纹理保存在一个容器vector中,然后在Update函数中,控制显示的图片id,从而达到循环显示。
具体的实现很简单,所以就不多说了~
vector<unsigned int> V_ID; //用来保存生成的纹理idint now,cnt; //now是当前所使用的纹理在vector中的下标//cnt是用来计时的变量void Update(){cnt++;if (cnt >= 100) //当cnt加到的时候,换下一张图片{now++;now%=V_ID.size(); //保证now值的正确性cnt=0; //将cnt值置,开始下一个图片的显示} glutPostRedisplay();}void init(){int n,i;char str[100],file[100];V_ID.clear(); //清空容器FILE *fp;fp=fopen("data/data.txt","r");fscanf(fp,"%d",&n);while (n--){fscanf(fp,"%s",str);sprintf(file,"data/%s",str); i=LoadBitmap(file);if (i == -1) //读取图片失败continue;else V_ID.push_back(i); //把图片的id放到V_ID的末尾保存起来}fclose(fp);now=0;}
图片实现了循环以后呢,我还希望图片在交替的时候,有一个淡入淡出的效果。怎么做呢?
还记得glColor3f函数吧,这个函数有一个可以带4个参数的形式:glColor4f。
这里的第四个参数,也就是alpha值。我们通过OpenGL提供的颜色混合功能,使用alpha值来实现这个效果。
在生活中,如果把两张照片(不透明)叠在一起,很明显,我们只能看见在最顶上的那张照片。如果一张照片被处理了,变成了透明的,那么我们就可以看见两张照片了。在OpenGL中,如果我们在一个区域画了一个绿色的矩形,随后在同样的区域画了一个黄色的矩形,那么我们就只能看见黄色的矩形,因为新画得黄矩形把原来那个覆盖了。如果我们想看见两个不同颜色矩形叠加在一起的效果,通过alpha混合就可以创建半透明的图像片段。
要使用alpha值,首先要开启混合功能。调用glEnable(GL_BLEND);
然后就是glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);这个函数是指定了两个图像片断混合的方式,在绘制图片之前,我们先调用glColor4f(1.0,1.0,1.0,alpha);
其中alpha值是[0,1]之间的,如果定为1,就是不透明,定为0就是,完全透明。淡入淡出的实现其实就是让这个值在[0,1]之间浮动即可。
所以,根据cnt值的变化,进行如下的操作:
if (cnt <= 50) glColor4f(1.0,1.0,1.0,(float)cnt/50.0); else glColor4f(1.0,1.0,1.0,1.0-((float)cnt-50.0)/50.0);
至于为什么前面的RGB为什么是,1,1,1,你可以尝试把某个改成0,看看效果^_^。
附本节代码:
#include <GL/glut.h>#include <stdio.h>#include <math.h>#include <time.h>#include <stdlib.h>#include <windows.h>#include <vector>#include <iostream>#define PI 3.1415926#define BITMAP_ID 0x4D42float h,m,s;using std::vector;using std::cout;using std::endl;int LoadBitmap(const char *file){unsigned int ID; //纹理的idint width,height,i; byte *image,t; //接受图像数据FILE *fp; //文件指针BITMAPFILEHEADER FileHeader; //接受位图文件头BITMAPINFOHEADER InfoHeader; //接受位图信息头fp=fopen(file,"rb");if (fp == NULL){perror("LoadBitmap"); //打开文件失败return -1;}fread(&FileHeader, sizeof(BITMAPFILEHEADER), 1, fp);if(FileHeader.bfType != BITMAP_ID) //确保文件是一个位图文件,效验文件类型{ printf("Error: This file is not a bmp file!");fclose(fp);return -1;}fread(&InfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);width=InfoHeader.biWidth; height=InfoHeader.biHeight;if (InfoHeader.biSizeImage == 0) //确保图像数据的大小 { InfoHeader.biSizeImage = width*height*3;}fseek(fp, FileHeader.bfOffBits, SEEK_SET); //将文件指针移动到实际图像数据处image=(byte *)malloc(sizeof(byte)*InfoHeader.biSizeImage); //申请空间if (image == NULL){free(image);printf("Error: No enough space!");return -1;}fread(image, 1, InfoHeader.biSizeImage, fp);for(i=0; i<InfoHeader.biSizeImage; i+=3){ t=image[i]; image[i]=image[i+2]; image[i+2]=t;}fclose(fp); glGenTextures(1, &ID); glBindTexture(GL_TEXTURE_2D, ID);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);return ID; }vector<unsigned int> V_ID; //用来保存生成的纹理idint now,cnt; //now是当前所使用的纹理在vector中的下标//cnt是用来计时的变量void Draw(){ glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, V_ID[now]);glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);if (cnt <= 50)glColor4f(1.0,1.0,1.0,(float)cnt/50.0);elseglColor4f(1.0,1.0,1.0,1.0-((float)cnt-50.0)/50.0);glBegin(GL_QUADS);glTexCoord2f(0.0f, 0.0f);glVertex2f(-1,-1);glTexCoord2f(1.0f, 0.0f);glVertex2f(1,-1);glTexCoord2f(1.0f, 1.0f);glVertex2f(1,1);glTexCoord2f(0.0f, 1.0f);glVertex2f(-1,1);glEnd();glDisable(GL_TEXTURE_2D); glutSwapBuffers();}void Update(){cnt++;if (cnt >= 100) //当cnt加到100的时候,换下一张图片{now++;now%=V_ID.size(); //保证now值的正确性cnt=0; //将cnt值置0,开始下一个图片的显示} glutPostRedisplay();}void Reshape(int w,int h){ w=w>h?h:w; glViewport(0,0,(GLsizei)w,(GLsizei)w);}void init(){int n,i;char str[100],file[100];V_ID.clear(); //清空容器FILE *fp;fp=fopen("data/data.txt","r");fscanf(fp,"%d",&n);while (n--){fscanf(fp,"%s",str);sprintf(file,"data/%s",str); i=LoadBitmap(file);if (i == -1) //读取图片失败continue;else V_ID.push_back(i); //把图片的id放到V_ID的末尾保存起来}fclose(fp);now=0;}int main(int argc, char *argv[]){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutInitWindowPosition(100, 100); glutInitWindowSize(400, 400); glutCreateWindow("HelloOpenGL"); glutReshapeFunc(&Reshape); glutIdleFunc(&Update); glutDisplayFunc(&Draw);init(); glutMainLoop(); return 0;}
- OpenGL织梦之旅【第三章】第2节.循环显示图片
- OpenGL织梦之旅【第三章】编写一个显示图片的程序
- OpenGL织梦之旅【第三章】第1节.纹理贴图
- OpenGL织梦之旅【第三章】第3节.实现截图功能
- OpenGL织梦之旅【第三章】第4节.glut键盘鼠标响应
- OpenGL织梦之旅【第二章】第2节.实现动画
- OpenGL织梦之旅【第四章】第2节.简单的3D动画
- OpenGL织梦之旅【第0章】前言
- OpenGL织梦之旅【第二章】第1节.绘制基本的几何图形
- OpenGL织梦之旅【第二章】第3节.指定颜色以及定义视口
- OpenGL织梦之旅【第四章】第1节.设置视点函数gluLookAt
- A3第三章第1节For循环入门
- OpenGL显示图片
- OpenGL显示图片
- OpenGL: 显示图片
- OpenGL显示图片
- 织梦循环中图片不显示的问题
- OpenGl第三章后续,纹理,绘制图片,文字
- struts
- 【2012级新生请猛击】NEW COMER FIRST BLOOD 完全题解及代码
- 存储过程在数据库中的作用是什么
- 栈帧&溢出
- NEFU要崛起——第8场
- OpenGL织梦之旅【第三章】第2节.循环显示图片
- gopherlib.py
- 给SPECsfs2008的数据画个图(图中少了个字母s)
- windows phone 实现mjpeg流视频的人脸识别
- 初识mybatis
- 3G版和Wi-Fi版iPad 2有什么区别?
- vim的折叠功能
- 求助 Exception in thread "main" java.lang.NoClassDefFoundError:
- “集群和负载均衡”等的通俗解释