OpenGL: 纹理模拟球体漫反射

先看下面的效果图:

 

 

 

 

没有灯光,没有设置材质属性,没有绘制球体,更加没有设置球体的漫反射系数。。。其实是将一个特殊的纹理映射到一个圆上的结果。

纹理生成函数,类似棋盘函数,所以只需将红皮书上棋盘函数稍作修改:

int fakeSphere(int i, int j)
{
	float s = (float)i / checkImageWidth;
	float t = (float)j / checkImageHeight;

	float r = sqrt( (s-0.5)*(s-0.5) + (t-0.5)*(t-0.5) );
	if( r<0.5 )
		return (int)( (1-r/0.5)*255 );

	return (int)(0.2*255);
}

void makeCheckImage(void)
{
	int i, j, c;

	for (i = 0; i < checkImageHeight; i++) {
		for (j = 0; j < checkImageWidth; j++) {
			//c = ((((i&0x8)==0)^((j&0x8))==0))*255;
			c = fakeSphere(i, j);
			checkImage[i][j][0] = (GLubyte) c;
			checkImage[i][j][1] = (GLubyte) c;
			checkImage[i][j][2] = (GLubyte) c;
			checkImage[i][j][3] = (GLubyte) 255;
		}
	}
}

就可以生成下图中的贴图。

 

 

如上图左图:在纹理坐标系中,圆形区域的半径为0.5。

x =  ( cos (theta*i)+1 ) * 0.5;

y =  ( sin  (theta*i)+1 ) * 0.5;

可以取得圆形区域的所有的纹理坐标值。而且满足( 0<=x<=1,  0<=y<=1)

然后将圆形区域映射到一个圆形区域上。

代码如下:

GLvoid draw_circle(const GLfloat radius,const GLuint num_vertex)
{
	GLfloat vertex[4]; 
	GLfloat texcoord[2];

	const GLfloat delta_angle = 2.0*M_PI/num_vertex;

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D,texName);
	glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
	glBegin(GL_TRIANGLE_FAN);

	//draw the vertex at the center of the circle
	texcoord[0] = 0.5;
	texcoord[1] = 0.5;
	glTexCoord2fv(texcoord);
	vertex[0] = vertex[1] = vertex[2] = 0.0;
	vertex[3] = 1.0;        
	glVertex4fv(vertex);

	//draw the vertex on the contour of the circle
	for(int i = 0; i < num_vertex ; i++)
	{
		//纹理圆的纹理坐标空间为:直径为1的圆
		texcoord[0] = (std::cos(delta_angle*i) + 1.0)*0.5;
		texcoord[1] = (std::sin(delta_angle*i) + 1.0)*0.5;
		glTexCoord2fv(texcoord);

		vertex[0] = std::cos(delta_angle*i) * radius;
		vertex[1] = std::sin(delta_angle*i) * radius;
		vertex[2] = 0.0;
		vertex[3] = 1.0;
		glVertex4fv(vertex);
	}

	texcoord[0] = (1.0 + 1.0)*0.5;
	texcoord[1] = (0.0 + 1.0)*0.5;
	glTexCoord2fv(texcoord);

	vertex[0] = 1.0 * radius;
	vertex[1] = 0.0 * radius;
	vertex[2] = 0.0;
	vertex[3] = 1.0;
	glVertex4fv(vertex);
	glEnd();

	glDisable(GL_TEXTURE_2D);
}

通过调用函数draw_circle(2.0, 20); 即可实现图中的效果。

当然了改变颜色只需要修改函数makeCheckImage中的

//灰色

   checkImage[i][j][0] = (GLubyte) c;
   checkImage[i][j][1] = (GLubyte) c;
   checkImage[i][j][2] = (GLubyte) c;

//红色

   checkImage[i][j][0] = (GLubyte) c;
   checkImage[i][j][1] = (GLubyte) 0;
   checkImage[i][j][2] = (GLubyte) 0;

//绿色

  checkImage[i][j][0] = (GLubyte) 0;
   checkImage[i][j][1] = (GLubyte) c;
   checkImage[i][j][2] = (GLubyte) 0;

 

add by RYF 2013-1-25

本文主要函数纹理,结合该纹理,结合alpha融合 可以绘制抗锯齿的线条:http://answers.oreilly.com/topic/1669-how-to-render-anti-aliased-lines-with-textures-in-ios-4/


http://blog.csdn.net/ryfdizuo/article/details/4865754

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值