OpenGL 纹理映射 ---画三维de篱笆
以上是我今天练习的一段纹理贴图程序的效果图
今天是学习OpenGL第九天,一天一个小例子,写了九段程序了,一直以来都想着要为自己画得三维图 变得 真实一点。
这一个小程序算是向这一个小目标更加接近了一点。
但是也发现蛮多问题。 ------------希望能够得到 有经验的朋友指点
1.OpenGL的各种状态,在设置Projection状态的时候做了什么, 能做什么,
modelView 状态又能做什么?viewport是干嘛用的?这些状态搞不清楚 做什么事情的时候需要转变状态。设定错了出不来想要的 openGL也不会提示。真是无奈。
2.Projection状态时的坐标规则。view 状态。
3.gluPerspective 视线角稍微容易设定一点,可是 gluLookAt 这一大堆参数的用处倒是知道,只是自己设定的时候还是不知道设定 它 为自己想要的视点
4.设定glTexCoord2f 和 glVertex3f 是怎么对应,repeat 的
代码如下:
#include "windows.h"
#include "gl/gl.h"
#include "gl/glu.h"
#include "gl/glut.h"
#include <stdio.h>
#define BmpHeaderLength 54 //文件长度
#define WidthPosition 0x0012 //width值在文件中的位置
#define HeightPosition 0x0016 //height在文件中的位置
typedef struct{
char *filename; //文件名
FILE *fp; //文件指针
GLint width; //宽
GLint height; //高
GLubyte * pPixelData; //文件中 实际的像素信息
}FileDataInfo; //文件数据信息
GLuint texGround;
GLuint texWall;
FileDataInfo LoadBMP(char *filename)
{
FileDataInfo fileinfo;
fileinfo.filename = filename;
fileinfo.fp = fopen(fileinfo.filename,"rb");
fseek(fileinfo.fp,WidthPosition,SEEK_SET);
fread(&fileinfo.width,sizeof(fileinfo.width),1,fileinfo.fp);
fseek(fileinfo.fp,HeightPosition,SEEK_SET);
fread(&fileinfo.height,sizeof(fileinfo.height),1,fileinfo.fp);
fseek(fileinfo.fp,BmpHeaderLength,SEEK_SET);
int widthInBmpFile = fileinfo.width*3;
//因为微软的bmp格式文件宽度 像素值 是 4 整数倍,不是的话,会在后面补上,
//也就是说 (像素宽*3)*像素高 <= 文件大小-54; ---54是bmp文件头部大小。
//所以在读取文件的时候需要调整内存大小,而不是 直接的(width*3)*height ;
while(widthInBmpFile%4 != 0)
{
widthInBmpFile++;
}
int pixelDataLen = widthInBmpFile *fileinfo.height;
fileinfo.pPixelData = (GLubyte*)malloc(pixelDataLen);
if(fileinfo.pPixelData == 0)
{
printf("malloc() failed");
free(fileinfo.pPixelData);
exit(0);
}
fread(fileinfo.pPixelData,pixelDataLen,1,fileinfo.fp);
fclose(fileinfo.fp);
return fileinfo;
}
//释放资源
void destroy(FileDataInfo *p)
{
free(p->pPixelData);
fclose(p->fp);
}
int getTexture(FileDataInfo fileinfo)
{
GLuint last_texture_ID,texture_ID=0;
GLubyte * pTextureData;
GLubyte * newData ;
GLint max;
//OpenGL 低版本中,纹理大小不能超过 一定值。
glGetIntegerv(GL_MAX_TEXTURE_SIZE,&max);
//为保证openGL向低版本的兼容性,超过了的话,需要将其缩小。
if(fileinfo.width > max||fileinfo.height >max)
{
//最大宽 和 高
int maxWidth =256;
int maxHeight = 256;
int lines = (int)maxWidth*3;
if(lines % 4 != 0)
{
lines++;
}
int total = lines * maxHeight;
newData = (GLubyte*)malloc(total);
if(newData == 0)
{
printf("newData=malloc() failed");
return -1;
}
//缩小
gluScaleImage(GL_RGB,fileinfo.width,fileinfo.height,GL_UNSIGNED_BYTE,fileinfo.pPixelData,maxWidth,maxHeight,GL_UNSIGNED_BYTE,newData);
pTextureData = newData;
}
else
{
pTextureData = fileinfo.pPixelData;
}
//generate a texture ID
glGenTextures(1,&texture_ID);
if(texture_ID == 0)
{
free(pTextureData);
printf("get textureID failed !");
return -1;
}
glGetIntegerv(GL_TEXTURE_BINDING_2D,(GLint*)&last_texture_ID);
glBindTexture(GL_TEXTURE_2D,texture_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_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,fileinfo.width,fileinfo.height,0,GL_BGR_EXT,GL_UNSIGNED_BYTE,pTextureData);
glBindTexture(GL_TEXTURE_2D,last_texture_ID);
return texture_ID;
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65,1,1,21);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1,5,5,0,0,0,0,0,1);
//开始绑定地表图像 作为纹理
glBindTexture(GL_TEXTURE_2D,texGround);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f); glVertex3f(-8.0f,-8.0f,0.0f);
glTexCoord2f(0.0,5.0f); glVertex3f(-8.0f,8.0f,0.0f);
glTexCoord2f(5.0f,5.0f); glVertex3f(8.0f,8.0f,0.0f);
glTexCoord2f(5.0f,0.0f); glVertex3f(8.0f,-8.0f,0.0f);
glEnd();
// 使用“墙”纹理绘制栅栏
glBindTexture(GL_TEXTURE_2D, texWall);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-6.0f, -3.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-6.0f, -3.0f, 1.5f);
glTexCoord2f(5.0f, 1.0f); glVertex3f(6.0f, -3.0f, 1.5f);
glTexCoord2f(5.0f, 0.0f); glVertex3f(6.0f, -3.0f, 0.0f);
glEnd();
// 旋转后再绘制一个
glRotatef(-90, 0, 0, 1);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-6.0f, -3.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-6.0f, -3.0f, 1.5f);
glTexCoord2f(5.0f, 1.0f); glVertex3f(6.0f, -3.0f, 1.5f);
glTexCoord2f(5.0f, 0.0f); glVertex3f(6.0f, -3.0f, 0.0f);
glEnd();
// 交换缓冲区,并保存像素数据到文件
glutSwapBuffers();
}
int main(int argc, char ** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(500,500);
glutCreateWindow("Texture Image");
glutDisplayFunc(&display);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
FileDataInfo groundFileInfo = LoadBMP("ground.bmp");
texGround = getTexture(groundFileInfo);
FileDataInfo wallFileInfo = LoadBMP("wall.bmp");
texWall = getTexture(wallFileInfo);
glutMainLoop();
destroy(&groundFileInfo);
destroy(&wallFileInfo);
return 0;
}
ground.bmp
wall.bmp
//结果
作者:
fandyst
出处: http://www.cnblogs.com/todototry/
关注语言: python、javascript(node.js)、objective-C、java、R、C++
兴趣点: 互联网、大数据技术、大数据IO瓶颈、col-oriented DB、Key-Value DB、数据挖掘、模式识别、deep learning、开发与成本管理
产品:
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
出处: http://www.cnblogs.com/todototry/
关注语言: python、javascript(node.js)、objective-C、java、R、C++
兴趣点: 互联网、大数据技术、大数据IO瓶颈、col-oriented DB、Key-Value DB、数据挖掘、模式识别、deep learning、开发与成本管理
产品:
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。