转发,请保持地址:http://blog.csdn.net/stalendp/article/details/11492525
OpenGL是原理性和实践性比较强的一门技术,在学习的时候,如果能够跟着书中的例子,一边调试一边学习,效果将很好(这属于实验的一种类型吧,能够吧知识形象化,有助于学习兴趣的提高)。市面上有许多深入浅出的书籍讲的很好,比如《OpenGL SuperBible 5th Edition》、《OpenGL 4 Shanding Language Cookbook》等(前者的例子代码写的非常好,后者把OpenGL的原理讲的比较深入)。不过要把这些书中的代码要跑在特定的系统上,还是需要花一些代价的(比如在mac上,SLGL只支持到1.2,很多例子中的代码就需要改了;而且配置环境也是比较麻烦的)。在探寻了很久之后,发现Unity3D提供了很好的OpenGL的学习环境,并且还有一些很好的资料可以参考。本文将介绍怎么在Unity3D上学习SLGL(关于OpenGL的pipeLine、VBO、PBO等其他一些,可以参考上面推荐的两本书,特别是把《OpenGL SuperBible 5th Edition》的那套工具类搞懂,就非常OK了)。这片文章源于对Minimal Shader的一个翻译和整理。
一、配置启动项(只有windows上需要)"C:\Program Files\Unity\Editor\Unity.exe" -force-opengl
Shader "GLSL basic shader" { // defines the name of the shader SubShader { // Unity chooses the subshader that fits the GPU best Pass { // some shaders require multiple passes GLSLPROGRAM // here begins the part in Unity's GLSL #ifdef VERTEX // here begins the vertex shader void main() // all vertex shaders define a main() function { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; // this line transforms the predefined attribute // gl_Vertex of type vec4 with the predefined // uniform gl_ModelViewProjectionMatrix of type mat4 // and stores the result in the predefined output // variable gl_Position of type vec4. } #endif // here ends the definition of the vertex shader #ifdef FRAGMENT // here begins the fragment shader void main() // all fragment shaders define a main() function { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // this fragment shader just sets the output color // to opaque red (red = 1.0, green = 0.0, blue = 0.0, // alpha = 1.0) } #endif // here ends the definition of the fragment shader ENDGLSL // here ends the part in GLSL } } }这样Shader就编辑好了。观察一下发现,这里一个文件中包含了Vertex Shader和Fragment Shader,这个有别于GLSL,不过其他就没有变化了(以后可能会有些优化,比如varying变量,在传统的GLSL中,需要在Vertex和Fragment中都定义一下,而且变量名称要一致,在Unity中可以把varying变量起到前面,写一份就可以了,减少了代码编写和错误的发生)
Shader "GLSL basic shader" { // defines the name of the shader SubShader { // Unity chooses the subshader that fits the GPU best 。。。。。四、把材质赋予游戏物体
不能操作系统的文件,因为没有root权限。
不是单独是使用循环完成,而是单独的使用一个异步处理器完成。
准备三张图片,名字分别为:file、folder_close和folder_open。
在main.xml中:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000"
android:orientation="vertical"
android:gravity="center_horizontal">
<ListView
android:id="@+id/list"
android:layout_gravity="center_horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
新建布局文件file_list.xml:
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000"
android:orientation="vertical">
<TableRow
android:gravity="center_vertical">
<ImageView
android:id="@+id/img"
android:layout_margin="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"/>
</TableRow>
</TableLayout>
在MyAsyncTaskListFileDemo.java中:
package com.li.asynctasklistfiledemo;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class MyAsyncTaskListFileDemo extends Activity {
private List<Map<String,Object>> allFileItems = new ArrayList<Map<String,Object>>() ;
private SimpleAdapter simple = null ;
private ListView list = null ;
private ListFileThread ft = null ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main);
this.list = (ListView) super.findViewById(R.id.list) ;
File filePath = new File(java.io.File.separator); // 从根目录下开始列出
this.list.setOnItemClickListener(new OnItemClickListenerImpl()) ;
this.ft = new ListFileThread() ;
this.ft.execute(filePath) ;
}
private class OnItemClickListenerImpl implements OnItemClickListener{
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
File currFile = (File) MyAsyncTaskListFileDemo.this.allFileItems
.get(position).get("name");
if (currFile.isDirectory()) { // 当前是一个目录
MyAsyncTaskListFileDemo.this.allFileItems = new ArrayList<Map<String,Object>>() ;
MyAsyncTaskListFileDemo.this.ft = new ListFileThread() ;
MyAsyncTaskListFileDemo.this.ft.execute(currFile) ;
}
}
}
private class ListFileThread extends AsyncTask<File, File, String> {
@Override
protected void onProgressUpdate(File... values) {
Map<String,Object> fileItem = new HashMap<String,Object>() ; // 表示可以返回
if (values[0].isDirectory()) {
fileItem.put("img", R.drawable.folder_close); // 文件夹
} else { // 是文件
fileItem.put("img",R.drawable.file) ;
}
fileItem.put("name", values[0]) ;
MyAsyncTaskListFileDemo.this.allFileItems.add(fileItem) ;
MyAsyncTaskListFileDemo.this.simple = new SimpleAdapter(
MyAsyncTaskListFileDemo.this,
MyAsyncTaskListFileDemo.this.allFileItems,
R.layout.file_list, new String[] { "img", "name" },
new int[] { R.id.img, R.id.name });
MyAsyncTaskListFileDemo.this.list
.setAdapter(MyAsyncTaskListFileDemo.this.simple);
}
@Override
protected String doInBackground(File... params) {
if (!params[0].getPath().equals(java.io.File.separator)) { // 不是根目录
Map<String,Object> fileItem = new HashMap<String,Object>() ; // 表示可以返回
fileItem.put("img",R.drawable.folder_open) ; // 可以返回
fileItem.put("name", params[0].getParentFile()) ;
MyAsyncTaskListFileDemo.this.allFileItems.add(fileItem) ;
}
if (params[0].isDirectory()) { // 是文件夹
File tempFile [] = params[0].listFiles() ;
if(tempFile != null) {
for (int x = 0; x < tempFile.length; x++) {
this.publishProgress(tempFile[x]) ;
}
}
}
return "文件已列出";
}
}
}
Service与Activity的最大区别就是一有界面,一个没有界面。 如果某些程序操作很消耗时间,那么可以将这些程序定义在Service之中,这样就可以完成程序的后台运行, 其实Service就是一个没有界面的Activity,执行跨进程访问也可以使用Service完成。 Service是一个没有UI界面的操作组件,主要功能是为Activity程序提供一些必要的支持,例如:手机 中的Mp3播放软件,当回到桌面的时候这些组件依然在运行,这就属于Service的功能,Service也有 自己的生命周期方法。 Service的生命周期控制方法:
方法及常量
类型
描述
1
START_CONTINUATION_MASK
常量
解析执行Service
2
START_STICKY
常量
用于显示启动和停止Service
3
IBinder onBind(Intent intent)
普通
设置Activity和Service之间的绑定
4
onCreate()
普通
当一个Service创建时调用
5
onStartCommand(Intent intent,int flags,int startId)
普通
启动Service,由startService()方法触发
6
onDestroy()
普通
Service销毁时调用,由stopService()方法触发
Service基本组成
1、单击“启动Serivce”按钮得下图:
2、再单击“启动Serivce”按钮得下图:
3、单击“停止Serivce”按钮得下图:
如果不退出Service,按Home键回到桌面,再找到任务管理器,可以发现Service还在运行,
所以说Service是运行在后台的。
在main.xml中:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000"
android:gravity="center_horizontal">
<Button
android:id="@+id/start"
android:layout_margin="30dp"
android:layout_width="100dp"
android:layout_height="40dp"
android:background="#3399ff"
android:textColor="#ffffff"
android:text="启动Service" />
<Button
android:id="@+id/stop"
android:layout_margin="30dp"
android:layout_width="100dp"
android:layout_height="40dp"
android:background="#3399ff"
android:textColor="#ffffff"
android:text="停止Service" />
</LinearLayout>
在MyServiceDemo.java中:
package com.li.service;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MyServiceDemo extends Activity {
private Button start ;
private Button stop ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main);
this.start = (Button) super.findViewById(R.id.start) ;
this.stop = (Button) super.findViewById(R.id.stop) ;
this.start.setOnClickListener(new StartOnClickListenerImpl()) ;
this.stop.setOnClickListener(new StopOnClickListenerImpl()) ;
}
private class StartOnClickListenerImpl implements OnClickListener{
public void onClick(View v) {
MyServiceDemo.this.startService(new Intent(MyServiceDemo.this,MyServiceUtil.class)) ;
}
}
private class StopOnClickListenerImpl implements OnClickListener{
public void onClick(View v) {
MyServiceDemo.this.stopService(new Intent(MyServiceDemo.this,MyServiceUtil.class)) ;
}
}
}
在MyServiceUtil.java中:
package com.li.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyServiceUtil extends Service {
@Override
public IBinder onBind(Intent intent) {
return null; // 此处暂时不做任何的处理
}
@Override
public void onCreate() {
System.out.println("*** Service onCreate()") ;
}
@Override
public void onDestroy() {
System.out.println("*** Service onDestroy()") ;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("*** Service onStartCommand") ;
return Service.START_CONTINUATION_MASK; // 继续执行
}
}
修改AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.li.service"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MyServiceDemo"
android:label="@string/title_activity_my_service_demo" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyServiceUtil" />
</application>
</manifest>