当前位置:  编程技术>移动开发
本页文章导读:
    ▪从零开始学习OpenGL ES之5 – 材质        从零开始学习OpenGL ES之五 – 材质 在 上一篇文章,我们讨论了光效的设定以及光效的各种属性。我们还讨论了光的三要素:散射光, 环境光 和高光。如果你还不是完全清楚,那么我们来.........
    ▪ UITabBarController 批改背景        UITabBarController 修改背景 第一:彻底自定义,但对于setHidesBottomBarWhenPushed不起作用。原因明确,但是现在没有时间来修改此bug。 UITabBarController的自定义方法,以下只能修改背景色,而不能修.........
    ▪ Activity 中动态增多控件       Activity 中动态增加控件 静态: layout/*.xml 布局 UI  。通过(ControlType)findViewById(R.id.name)来实例化。 动态: 通过 Java code 增加, ControlType control = new ControlType control 来实例化。   动态增加控件的基.........

[1]从零开始学习OpenGL ES之5 – 材质
    来源: 互联网  发布时间: 2014-02-18
从零开始学习OpenGL ES之五 – 材质

在 上一篇文章,我们讨论了光效的设定以及光效的各种属性。我们还讨论了光的三要素:散射光, 环境光 和高光。如果你还不是完全清楚,那么我们来复习一下,在定义材质时大量的用到这些要素。


 

作为本文的起点,我们使用了原文中球体绘制 的项目文件。我们不再使用二十面体而是转向球体是因为球体是展示光和材质不同要素之间相互作用的最佳形状。

 

 

颜色是什么

 

这可能是对小学美术课的复习。为什么现实世界会有颜色?是什么造成的?

 

我们看得见的光被称为 光的可见频谱 。根据不同的波长我们可以感知到不同的颜色。在可见光谱的一端是低波长高频率的紫色和蓝色,而在另一端是低频高波长的橘色和红色:

 

电磁波在这个范围之外,因此不是“可见光”,尽管这只是人工的区分方法,它们的唯一不同在频率和波长,在于人眼的感知。尽管有各种方法感知各种电磁波的能力,但从OpenGL的角度出发,我们只关心可见光谱。

 

“白色光”包括等量的所有波长。换言之,白光之所以是白色的是因为它包括了所有(或至少大部分)可见光的频率。如果你曾经做过棱镜试验,那么你可能看过如下效果:

 

棱镜反射白光,各种波长被分离出来。这就是彩虹产生的原理。

 

如果你看到一个物体呈蓝色,那么实际上是该物体吸收了大部分可见光谱低频部分。它吸收了红,橘,黄和绿光。根据蓝色的不同色度,它还可能吸收一些紫色和蓝色。

 

但大部分蓝色的波长都被反射到你的眼睛。因为一些可见光被吸收了,由于它不再包括可见光谱中的所有波长所以反射到你眼中的光不再是白色。

 

简单吧?让我们看看这些是怎样运用在OpenGL的。

 

OpenGL 材质

 

我们通过定义材质的反射光来定义OpenGL ES中的材质,正如现实世界中一样。如果一个材质定义为反射红光,那么在正常的白光下,它将显示红色。

 

在OpenGL中 (至少在使用光滑着色处理和光效时),材质是没有颜色的。OpenGL具有分别定义材质是怎样反射OpenGL光效三要素(环境,散射和高光)的能力。另外,它还具有指定材质 自发光(emissive) 属性的能力,关于这点我们稍后再讨论。

 

指定材质

 

要在OpenGL创建一个材质,我们需要一次或多次调用 glMaterialf() 或者 glMaterialfv()。类似于上一篇文章中光效的定义,由于各属性或元素需要分别通过这些调用了指定,所以我们通常必须多次调用这些函数以完全定义材质。所有未定义的元素或属性默认值为0,或者以颜色来说为黑色。

 

传递给 glMaterialf() 或者 glMaterialfv() 的第一个参数总是用于指定是否材质影响多边形的前,后或两者的GL_ENUM。实际上除了为了与OpenGL兼容,第一个参数在OpenGL ES中没有什么意义,因为只有一个有效的选项: GL_FRONT_AND_BACK,它简单地表示材质适用于任何绘制的多边形。如果你还记得第一部分,那么你应该知道三角形的正面和背面是由winding(顶点的绘制次序)决定的。默认情况下,只有三角形的正面被绘制出来,但是有可能让OpenGL也绘制背面,或甚至只绘制背面,常规 OpenGL 允许你通过传递GL_FRONT,GL_BACK, 或者 GL_FRONT_AND_BACK来为正面和背面指定不同的材质。但是OpenGL ES仅支持GL_FRONT_AND_BACK。

 

glMaterialf() 或 glMaterialfv()的第二个参数是指示正在设定材质的哪个元素或属性的 GL_ENUM。它们像传递给glLightfv()的值一样,比如 GL_AMBIENT ,另外还有些新的值我们稍后再谈。

 

最终值是 GL_FLOAT或包括了实际属性或元素的GL_FLOAT数组的指针。

 

材质的最重要元素是环境光和散射光,因为它们决定了材质是怎样反射大量光线的。我们今天使用的项目代码定义了正如太阳光或白炽灯产生的白色,它具有平均分布的各种波长和颜色的光。如果光不是白色,球体看上去会有不同的外观。例如,反射至红色材质的蓝光将产生紫色阴影。简单起见,我们只使用白色光。当然,你可以随意改变光的颜色进行试验看看光和材质是怎样交互作用的。大部分时候,它们在OpenGL ES中的表示与现实生活中完全一样。

 

下面是项目在添加材质前运行时的样子:

 

如你所见,它具有一些环境光和更为显著的散射光。

 

环境光和散射光

 

当讨论OpenGL的材质时,我们需要同时讨论环境光和散射光,这是因为这两个元素是一起工作从而决定物体被感知的颜色的。记住,散射光处于本文第一个图片中球体的顶部(亮黄色),环境光则是下方的暗黄色。材质怎样反射这两个元素决定了物体被感知的颜色。上图的效果可以通过不止一种方法获得。同样地,黄色球以同样比例反射环境光和散射光,但是场景中具有较少的环境光。

 

大约 90% 或更多的情况下,将材质的环境光和散射光参数设定成一样。这样做,使它们成为决定物体阴影和外观的因素。实际上,有一种方法通过一个调用glMaterialfv()同时设定材质环境光和散射光。下面是定义材质为蓝色的示例:

    GLfloat ambientAndDiffuse[] = {0.0, 0.1, 0.9, 1.0};
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, ambientAndDiffuse);

 

正如 glColor4f(), 设置材质指示随后所有物体绘制的方式直到另一个材质被指定。如果将上叙代码放置于我们的绘制代码之前,那么运行时你将看到球体变为蓝色。由于环境光没有散射光强,其下方只是稍暗。

 

 

有时你希望更多地控制并希望分别设定材质对环境光和散射光的反射方式。例如,下例中,材质从环境光反射蓝色,从散射光反射红色:

    GLfloat ambient[] = {0.0, 0.1, 0.9, 1.0};
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
    GLfloat diffuse[] = {0.9, 0.0, 0.1, 1.0};
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);

 

运行结果:

 

在此情况下,它看上去像我们投射了有色光到球体上,实际上却不是这样。原因是我们反射了与环境光不一样的定向光线。

 

大部分情况下,如果你希望产生彩色光的效果,你只需创建彩色光线然后使用GL_AMBIENT_AND_DIFFUSE来指定材质颜色。但是有时却希望分别设置它们产生特殊效果或在不引起创建额外光线开销的情况下假造一个分离的彩色点光源。记住:你每增加一个光源,也就增加了每秒钟的运算量,所以有时候欺骗并不完全是一件坏事。

 

高光和光泽

 

你还可以单独设置场景中高光元素的反射方式,从而控制高光“热点”的亮度。一个叫 GL_SHININESS的参数与材质的高光元素一起定义了高光热点的大小。如果你设定了材质的 GL_SPECULAR 值,你还应该定义其反光度。反光度越高,高光反射越小,所以默认值 0.0 几乎完全淹没了散射光,因此看上去很糟糕。

 

让我们回到蓝色球体,增加高光热点:

    GLfloat ambientAndDiffuse[] = {0.0, 0.1, 0.9, 1.0};
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, ambientAndDiffuse);
    GLfloat specular[] = {0.3, 0.3, 0.3, 1.0};
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 25.0);

 

我们使用了一个较暗的白色作为球体的高光值。这个值看上去有些小,但就是这么小的值也能产生显著的效果。光线高光元素的值与材质的高光元素相乘所产生的光集中在材质反光度指定的区域。下面是上叙代码产生的结果:

 

 

现在,球体上有一个小的区域具有更强的反射光。我们可以通过增强光或光的高光元素,或者通过增加材质的反光度使这个点更亮。我们还可以通过调整反光度改变高光的大小。材质反光度越高,高光越集中。例如,如果我们将反光度从25.0 改为 50.0,我们将得到一个更小的热点,它使得球体显得更具有光泽。

 

 

但是,有一点要小心。本文之所以改为使用球体的部分原因以及为什么球体使用较高的顶点数目的原因是高光在一个低面数的物体上看上去实在糟糕。注意一下,如果我减少球体的顶点数会发生什么:

                                                                         

低面片

 

高光使三角形边缘突出,高光通常在我们的游戏中经常使用的低面片的物体上表现不佳。在常规OpenGL中,有一个称为 着色器(shader) 的机制可以用来为低面片物体产生较为理想的结果,但目前iPhone上的OpenGL ES并不支持此功能(译者注:iPhone 3GS支持OpenGL ES 2.0,有shader功能。但有一个问题就是OpenGL ES 1.1与OpenGL ES 2.0并不完全兼容)在游戏中如果你想使低面片物体漂亮的唯一方法就是完全摒弃高光元素而使用纹理映射,这将在下一篇文章中谈到。

 

自发光

 

还剩最后一个材质的重要属性,它称为自发光元素。通过设定自发光元素,使得材质看上去会发射我们指定的颜色。它并不是真正在发光。例如,其周边物体并不会被发射的光线影响。如果你希望一个物体像灯泡一样发光照亮其他物体,由于在OpenGL ES中只有光源会发光(听上去像废话),你需要将自发光元素和与物体同一位置处的实际光源结合起来。但是自发光元素可以使物体漂亮地发光。

 

例如,我们可以为蓝色球体添加绿色的光泽:

    GLfloat emission[] = {0.0, 0.4, 0.0, 1.0};
    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission);

 

结果如下:

 

自发光元素影响整个材质,因此 GL_EMISSION的值将与落入物体指定区域的任何类型的光相叠加。请注意,甚至上图中的高光部分也成了一点蓝-绿色而不是纯白色。在高光点处其效果是很微小的,但在只有环境光被反射的底部效果更为明显。它实际影响整个物体。

 


    
[2] UITabBarController 批改背景
    来源: 互联网  发布时间: 2014-02-18
UITabBarController 修改背景

第一:彻底自定义,但对于setHidesBottomBarWhenPushed不起作用。原因明确,但是现在没有时间来修改此bug。

UITabBarController的自定义方法,以下只能修改背景色,而不能修改选中时的颜色,后续会将代码公布,正在修改之中,敬请关注。
完全自定义已经更改完成,地址:点击这里哦



第二:只是修改背景其他的属性元素都不改变。

代码如下:为什么索引是1,你自己想去。tabbar_Bg.png即为背景图片。


    
[3] Activity 中动态增多控件
    来源: 互联网  发布时间: 2014-02-18
Activity 中动态增加控件

静态: layout/*.xml 布局 UI  。通过(ControlType)findViewById(R.id.name)来实例化。

动态: 通过 Java code 增加, ControlType control = new ControlType control 来实例化。

 

动态增加控件的基本思路就是:实例化控件-> 布局.addView(控件) -> OnCreat中绑定布局控件 setContentView(布局)

 

例1:在LinearLayout中动态增加Button,EditText等控件,并且点击Button后,动态增加EditText等控件。

 

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		final LinearLayout linearLayout=new LinearLayout(this);  
		linearLayout.setOrientation(LinearLayout.VERTICAL);
		
		LinearLayout linearLayout1 = new LinearLayout(this);
		linearLayout1.setOrientation(LinearLayout.VERTICAL);
		
		Button button1= new Button(this);
		button1.setText("增加新项目");
		
		Button button2 = new Button(this);
		button2.setText("增加新组");
		
		linearLayout.addView(button1);
		linearLayout.addView(button2);
		
		//设定按钮单击监听器,动态增加控件.
		button2.setOnClickListener(new Button.OnClickListener(){
			public void onClick(View v) {
				Context context = v.getContext();
				LinearLayout linearLayout2 = new LinearLayout(context);
				linearLayout2.setOrientation(LinearLayout.HORIZONTAL);
				
				EditText groupNameEditText = new EditText(context);
				//设置控件大小.
				groupNameEditText.setWidth(160);
				
				ImageButton imagebutton1 = new ImageButton(context);
				Button saveButton = new Button(context);
				Button exitButton = new Button(context);
				
				linearLayout2.addView(groupNameEditText);
				linearLayout2.addView(imagebutton1);
				linearLayout2.addView(saveButton);
				linearLayout2.addView(exitButton);
				linearLayout.addView(linearLayout2);
				
			}
		});
		
		setContentView(linearLayout);
	}
	

 


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3