NeHe学习之基础二

代码都从框架的基础上添加

纹理:

使用到的函数

auxDIBImageLoadA(char* FileName);		//载入位图并返回其指针
glGenTextures(GLsizei n, GLuint *textures)	//生成纹理
glBindTexture(GLenum target, GLuint texture ); 	//将纹理和目标进行绑定
glTexImage2D(GLenum target, GLint level, GLenum internalformat,GLsizei width,
	GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels);	//根据指定的参数,生成一个2D纹理
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); //缩小过滤
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); //放大过滤

添加四个全局变量

GLfloat xrot;	//x的旋转量
GLfloat yrot;	//y的旋转量
GLfloat zrot;	//z的旋转量
GLuint texture[1];	//存储一个纹理
在WndProc的定义前加上以下代码
//载入位图
AUX_RGBImageRec* LoadBmp(char* Filename)
{
	FILE* File = NULL;
	if(!Filename){
		return NULL;
	}
	File = fopen(Filename,"r");
	if(File){
		fclose(File);
		return auxDIBImageLoadA(Filename);
	}
	return NULL;
}
//载入纹理
bool LoadGLTextures()
{
	bool Status = FALSE;
	AUX_RGBImageRec* TextureImage[1];	//纹理的存储空间
	memset(TextureImage,0,sizeof(void*)*1);
	if(TextureImage[0] = LoadBmp("Data/NeHe.bmp")){
		Status = true;
		glGenTextures(1,&texture[0]); 	//创建了一个纹理名
		glBindTexture(GL_TEXTURE_2D,texture[0]);
		glTexImage2D(GL_TEXTURE_2D,		//2D纹理
			0,							//图像的详细程度
			3,							//图像的成分数(eg:rgb 3)
			TextureImage[0]->sizeX,		//纹理的宽度
			TextureImage[0]->sizeY,		//纹理的高度
			0,							//边框值
			GL_RGB,						//颜色类型RGB
			GL_UNSIGNED_BYTE,			//数据类型无符号字节型
			TextureImage[0]->data		//纹理的数据
		);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);	//比原始纹理小,线形滤波
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);	//比原始纹理大,线形滤波
	}
	//释放空间
	if(TextureImage[0]){
		if(TextureImage[0]->data){
			free(TextureImage[0]->data);
		}
		free(TextureImage[0]);
	}

	return Status;
}
在initGL()中加上以下代码
if(!LoadGLTextures())
		return FALSE;
在DrawGLScene()中加上以下代码
glTranslatef(0.0f,0.0f,-5.0f);

	glRotatef(xrot,1.0f,0.0f,0.0f);
	glRotatef(yrot,0.0f,1.0f,0.0f);
	glRotatef(zrot,0.0f,0.0f,1.0f);

	glBindTexture(GL_TEXTURE_2D,texture[0]);

	glBegin(GL_QUADS);
	/*front-side*/
		glTexCoord2f(0.0f,0.0f);		//left_bottom
		glVertex3f(-1.0f,-1.0f, 1.0f);
		glTexCoord2f(1.0f,0.0f);		//right_bottom	
		glVertex3f( 1.0f,-1.0f, 1.0f);
		glTexCoord2f(1.0f,1.0f);		//right_top
		glVertex3f( 1.0f, 1.0f, 1.0f);
		glTexCoord2f(0.0f,1.0f);		//left_top
		glVertex3f(-1.0f, 1.0f, 1.0f);
	/*back-side*/
		glTexCoord2f(1.0f,0.0f);		//right_bottom
		glVertex3f(-1.0f,-1.0f,-1.0f);
		glTexCoord2f(1.0f,1.0f);		//right_top	
		glVertex3f(-1.0f, 1.0f,-1.0f);
		glTexCoord2f(0.0f,1.0f);		//left_top
		glVertex3f( 1.0f, 1.0f,-1.0f);
		glTexCoord2f(0.0f,0.0f);		//left_bottom
		glVertex3f( 1.0f,-1.0f,-1.0f);
	/*top-side*/
		glTexCoord2f(0.0f,1.0f);		//letf_top
		glVertex3f(-1.0f, 1.0f,-1.0f);
		glTexCoord2f(0.0f,0.0f);		//letf_bottom	
		glVertex3f(-1.0f, 1.0f, 1.0f);
		glTexCoord2f(1.0f,0.0f);		//right_bottom
		glVertex3f( 1.0f, 1.0f, 1.0f);
		glTexCoord2f(1.0f,1.0f);		//right_top
		glVertex3f( 1.0f, 1.0f,-1.0f);
	/*bottom-side*/
		glTexCoord2f(1.0f,1.0f);		//right_top
		glVertex3f(-1.0f,-1.0f,-1.0f);
		glTexCoord2f(0.0f,1.0f);		//left_top	
		glVertex3f( 1.0f,-1.0f,-1.0f);
		glTexCoord2f(0.0f,0.0f);		//left_bottom
		glVertex3f( 1.0f,-1.0f, 1.0f);
		glTexCoord2f(1.0f,0.0f);		//right_bottoms
		glVertex3f(-1.0f,-1.0f, 1.0f);
	/*right-side*/
		glTexCoord2f(1.0f,0.0f);		//right_bottom
		glVertex3f( 1.0f,-1.0f,-1.0f);
		glTexCoord2f(1.0f,1.0f);		//right_top	
		glVertex3f( 1.0f, 1.0f,-1.0f);
		glTexCoord2f(0.0f,1.0f);		//left_top
		glVertex3f( 1.0f, 1.0f, 1.0f);
		glTexCoord2f(0.0f,0.0f);		//left_bottoms
		glVertex3f( 1.0f,-1.0f, 1.0f);
	/*left-side*/
		glTexCoord2f(0.0f,0.0f);		//left_bottom
		glVertex3f(-1.0f,-1.0f,-1.0f);
		glTexCoord2f(1.0f,0.0f);		//right_bottom	
		glVertex3f(-1.0f,-1.0f, 1.0f);
		glTexCoord2f(1.0f,1.0f);		//right_top
		glVertex3f(-1.0f, 1.0f, 1.0f);
		glTexCoord2f(0.0f,1.0f);		//left_top
		glVertex3f(-1.0f, 1.0f,-1.0f);
	glEnd();

	xrot += 0.03f;
	yrot += 0.02f;
	zrot += 0.04f;
到了这里我们可以看到一个6各面都贴上图片的正方体在旋转。

光照,混合(透明)及键盘控制:

使用到的新的函数

int gluBuild2DMipmaps(GLenum target,GLint components,GLint width,GLint height,
	GLenumformat,GLenum type,const void *data); //和glTexImage2D(...)功能一样也是生成纹理

添加以下全局变量

<span style="font-family:SimSun;font-size:12px;">bool islight = false;	//光源的开/关
bool isblend = false;	//透明开/关
bool lp = false;		//L键的按下及弹起
bool fp = false;		//F键的按下及弹起
bool bp = false;		//B键的按下及弹起
GLfloat xrot;			//x 轴的偏转角度
GLfloat yrot;			//y 轴的偏转角度
GLfloat xspeed;			//x 轴的偏转步距
GLfloat yspeed;			//y 轴的偏转步距
GLfloat z=-5.0f;		//深入屏幕的距离
GLfloat LightAmbient[]={0.5f,0.5f,0.5f,1.0f};	//环境光参数
GLfloat LightDiffuse[]={1.0f,1.0f,1.0f,1.0f};	//漫射光参数
GLfloat LightPosition[]={0.0f,0.0f,2.0f,1.0f,};	//光源的位置
GLuint filter;			//滤波的类型
GLuint texture[3];		//3种纹理的存储空间</span>

添加以下代码

AUX_RGBImageRec* LoadBmp(char* Filename)
{
	FILE* File = NULL;
	if(!Filename){
		return NULL;
	}
	File = fopen(Filename,"r");
	if(File){
		fclose(File);
		return auxDIBImageLoadA(Filename);
	}
	return NULL;
}

bool LoadGLTextures()
{
	bool Status = false;
	AUX_RGBImageRec* TextureImage[1];
	memset(TextureImage,0,sizeof(void*)*1);
	if(TextureImage[0]=LoadBmp("Data/Glass.bmp"))
	{
		Status = true;
		glGenTextures(3,&texture[0]);

		//创建Nearest滤波贴图
		glBindTexture(GL_TEXTURE_2D,texture[0]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
		glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,
			TextureImage[0]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->data);

		//创建Linear滤波贴图
		glBindTexture(GL_TEXTURE_2D,texture[1]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,
			TextureImage[0]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->data);

		//创建Mipmapped滤波贴图
		glBindTexture(GL_TEXTURE_2D,texture[2]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		gluBuild2DMipmaps(GL_TEXTURE_2D,3,TextureImage[0]->sizeX,
			TextureImage[0]->sizeY,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->data);
	}
	
	if(TextureImage[0])
	{
		if(TextureImage[0]->data)
		{
			free(TextureImage[0]->data);
		}
		free(TextureImage[0]);
	}
	
	return Status;
}

在initGL()的最前面加上以下代码

<span style="white-space:pre">	</span>glColor4f(1.0f,1.0f,1.0f,0.5f);<span style="white-space:pre">		</span>//全亮,半透明
	glBlendFunc(GL_SRC_ALPHA,GL_ONE);<span style="white-space:pre">	</span>//基于源像素的Apha通道
	if(!LoadGLTextures())
		return FALSE;

在initGL()的最后加上以下代码

<span style="white-space:pre">	</span>glLightfv(GL_LIGHT1,GL_AMBIENT,LightAmbient);	//设置环境光
	glLightfv(GL_LIGHT1,GL_DIFFUSE,LightDiffuse);	//设置漫射光
	glLightfv(GL_LIGHT1,GL_POSITION,LightPosition);	//设置光源位置
	glEnable(GL_LIGHT1);	<span style="white-space:pre">			</span>//启用一号光源
在DrawGLScene()中加入以下代码
int wh_DrawGLScene(GLvoid)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
	glLoadIdentity();

	glTranslatef(0.0f,0.0f,z);
	glRotatef(xrot,1.0f,0.0f,0.0f);
	glRotatef(yrot,0.0f,1.0f,0.0f);
	glBindTexture(GL_TEXTURE_2D,texture[filter]);
	glBegin(GL_QUADS);
	/*front-side*/
		glNormal3f( 0.0f, 0.0f, 1.0f);
	
		glTexCoord2f(0.0f,0.0f);		//left_bottom
		glVertex3f(-1.0f,-1.0f, 1.0f);
		glTexCoord2f(1.0f,0.0f);		//right_bottom	
		glVertex3f( 1.0f,-1.0f, 1.0f);
		glTexCoord2f(1.0f,1.0f);		//right_top
		glVertex3f( 1.0f, 1.0f, 1.0f);
		glTexCoord2f(0.0f,1.0f);		//left_top
		glVertex3f(-1.0f, 1.0f, 1.0f);
	/*back-side*/
		glNormal3f( 0.0f, 0.0f,-1.0f);
	
		glTexCoord2f(1.0f,0.0f);		//right_bottom
		glVertex3f(-1.0f,-1.0f,-1.0f);
		glTexCoord2f(1.0f,1.0f);		//right_top	
		glVertex3f(-1.0f, 1.0f,-1.0f);
		glTexCoord2f(0.0f,1.0f);		//left_top
		glVertex3f( 1.0f, 1.0f,-1.0f);
		glTexCoord2f(0.0f,0.0f);		//left_bottom
		glVertex3f( 1.0f,-1.0f,-1.0f);
	/*top-side*/
		glNormal3f( 0.0f, 1.0f,0.0f);
	
		glTexCoord2f(0.0f,1.0f);		//letf_top
		glVertex3f(-1.0f, 1.0f,-1.0f);
		glTexCoord2f(0.0f,0.0f);		//letf_bottom	
		glVertex3f(-1.0f, 1.0f, 1.0f);
		glTexCoord2f(1.0f,0.0f);		//right_bottom
		glVertex3f( 1.0f, 1.0f, 1.0f);
		glTexCoord2f(1.0f,1.0f);		//right_top
		glVertex3f( 1.0f, 1.0f,-1.0f);
	/*bottom-side*/
		glNormal3f( 0.0f, -1.0f,0.0f);
	
		glTexCoord2f(1.0f,1.0f);		//right_top
		glVertex3f(-1.0f,-1.0f,-1.0f);
		glTexCoord2f(0.0f,1.0f);		//left_top	
		glVertex3f( 1.0f,-1.0f,-1.0f);
		glTexCoord2f(0.0f,0.0f);		//left_bottom
		glVertex3f( 1.0f,-1.0f, 1.0f);
		glTexCoord2f(1.0f,0.0f);		//right_bottoms
		glVertex3f(-1.0f,-1.0f, 1.0f);
	/*right-side*/
		glNormal3f( 1.0f, 0.0f,0.0f);
	
		glTexCoord2f(1.0f,0.0f);		//right_bottom
		glVertex3f( 1.0f,-1.0f,-1.0f);
		glTexCoord2f(1.0f,1.0f);		//right_top	
		glVertex3f( 1.0f, 1.0f,-1.0f);
		glTexCoord2f(0.0f,1.0f);		//left_top
		glVertex3f( 1.0f, 1.0f, 1.0f);
		glTexCoord2f(0.0f,0.0f);		//left_bottoms
		glVertex3f( 1.0f,-1.0f, 1.0f);
	/*left-side*/
		glNormal3f( -1.0f, 0.0f,0.0f);
	
		glTexCoord2f(0.0f,0.0f);		//left_bottom
		glVertex3f(-1.0f,-1.0f,-1.0f);
		glTexCoord2f(1.0f,0.0f);		//right_bottom	
		glVertex3f(-1.0f,-1.0f, 1.0f);
		glTexCoord2f(1.0f,1.0f);		//right_top
		glVertex3f(-1.0f, 1.0f, 1.0f);
		glTexCoord2f(0.0f,1.0f);		//left_top
		glVertex3f(-1.0f, 1.0f,-1.0f);
	glEnd();
	
	xrot += xspeed;
	xrot += yspeed;
	return true;
}

在WinMain()结尾处添加以下代码

SwapBuffers(wh_hDC); //交换缓存,双缓存可实现动画转换无闪烁
				//"L"
				if(wh_keys['L'] && !lp)
				{
					lp = true;
					islight = !islight;
				}
				if(!islight){
					glDisable(GL_LIGHTING);
				}else{
					glEnable(GL_LIGHTING);
				}
				if(!wh_keys['L']){
					lp = false;
				}
				//"F"
				if(wh_keys['F'] && !fp)
				{
					fp = true;
					filter++;
					if(filter>2){
						filter = 0;
					}
				}
				if(!wh_keys['F']){
					fp = false;
				}
				//"PageUp"
				if(wh_keys[VK_PRIOR]){
					z -= 0.02f;
				}
				//"PageDown"
				if(wh_keys[VK_NEXT]){
					z += 0.02f;
				}
				//"Up"
				if(wh_keys[VK_UP]){
					xspeed -= 0.01f;
				}
				//"Down"
				if(wh_keys[VK_DOWN]){
					xspeed += 0.01f;
				}
				//"Right"
				if(wh_keys[VK_RIGHT]){
					yspeed -= 0.01f;
				}
				//"Left"
				if(wh_keys[VK_LEFT]){
					yspeed += 0.01f;
				}
				//"B"
				if(wh_keys['B'] && !bp)
				{
					bp = true;
					isblend = !isblend;
					if(isblend){
						glEnable(GL_BLEND);
						glDisable(GL_DEPTH_TEST);
					}else{
						glDisable(GL_BLEND);
						glEnable(GL_DEPTH_TEST);
					}
				}
				if(!wh_keys['B'])
				{
					bp = false;
				}
这里我们可以按下B键可以看见透明的正方体,同时按PageUp or PageDown 可以拉近,拉远目标,上下左右可以调整正方体的旋转速度。按L可以开启光照,如果光照关闭了话,是看不到透明的效果的。按F键可以切换三种不同的滤波效果。【需要指出的是,其中加载纹理的方法不好,因为glaux库过时了,所以在网上我看到一篇文章通过SOIL库来载入纹理 SOIL库加载纹理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值