暑假第三十三天,唯一的感觉就是时间过的好快,转眼间暑假一个月已经过去了,嗯,好快,好快哦!而自己自学android之路还有很长,虽然说:“前途是光明的,但是道路是崎岖的,生活是迷茫的,想家是必须滴... ...”。呵呵,好了废话不多说了,看看今天模仿的QQ空间的下拉更新个应用吧
首先看看布局
1.main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:drawableLeft="@drawable/write" android:lines="1" android:padding="5px" android:singleLine="true" android:text="写说说" /> <TabHost android:id="@+id/tabhost" android:background="@drawable/bg" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:id="@+id/linearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TabWidget android:id="@android:id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" > </TabWidget> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:id="@+id/tab1" android:layout_width="match_parent" android:layout_height="match_parent" > <com.wang.MyListView android:id="@+id/listView" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> <LinearLayout android:id="@+id/tab2" android:layout_width="match_parent" android:layout_height="match_parent" > </LinearLayout> <LinearLayout android:id="@+id/tab3" android:layout_width="match_parent" android:layout_height="match_parent" > </LinearLayout> </FrameLayout> </LinearLayout> </TabHost> </LinearLayout>2.list的条目布局list_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="horizontal" > <ImageView android:id="@+id/imageView_item" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:src="/blog_article/@drawable/icon/index.html" /> <TextView android:id="@+id/textView_item" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:textColor="#FFFFFF" /> </LinearLayout>
3, 刷新布局refresh.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" > <RelativeLayout android:id="@+id/head_contentLayout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="30dp" > <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" > <ImageView android:id="@+id/head_arrowImageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="/blog_article/@drawable/down/index.html" /> <ProgressBar android:id="@+id/head_progressBar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:visibility="gone" /> </FrameLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:gravity="center_horizontal" android:orientation="vertical" > <TextView android:id="@+id/head_tipsTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下拉可以刷新" android:textSize="15dp" /> <TextView android:id="@+id/head_lastUpdatedTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="上次更新时间:" android:textSize="12dp" /> </LinearLayout> </RelativeLayout> </LinearLayout>4.看看主活动实现的过程PullrefreshDemoActivity.xml
package com.wang; import java.util.LinkedList; import com.wang.MyListView.OnRefreshListener; import android.app.Activity; import android.content.res.Resources; import android.os.AsyncTask; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.BaseAdapter; import android.widget.TabHost; import android.widget.TextView; public class PullrefreshDemoActivity extends Activity { private LinkedList<String> data; private BaseAdapter adapter; public void onCreate(Bundle savedInstanceState) { // 去除标题栏 requestWindowFeature(Window.FEATURE_NO_TITLE); // 设置全屏,取消状态栏 this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); super.onCreate(savedInstanceState); setContentView(R.layout.main); TabHost tabhost=(TabHost)findViewById(R.id.tabhost); tabhost.setup(); tabhost.addTab(tabhost.newTabSpec("tab1").setIndicator("好友动态").setContent(R.id.tab1)); tabhost.addTab(tabhost.newTabSpec("tab2").setIndicator("我的动态").setContent(R.id.tab2)); tabhost.addTab(tabhost.newTabSpec("tab3").setIndicator("我的应用").setContent(R.id.tab3)); data = new LinkedList<String>(); for (int i = 30; i < 40; i++) { // 输出list——item上的数据 data.add(String.valueOf("暑假第" + i + "天,我们一直很宅,想家ing ...")); } final MyListView listView = (MyListView) findViewById(R.id.listView); adapter = new BaseAdapter() { // 得到一个视图,显示在指定位置上的数据在数据集,可以创建一个视图从XML布局文件 public View getView(int position, View convertView, ViewGroup parent) { // 上下文全局应用程序对象 convertView = LayoutInflater.from(getApplicationContext()) .inflate(R.layout.list_item, null); // 实例化组件 TextView textView = (TextView) convertView .findViewById(R.id.textView_item); // 设置文本本内容 textView.setText(data.get(position)); return convertView; } // 得到行相关联id列表中指定的位置。 public long getItemId(int position) { return position; } // 获得相关的数据项中的指定位置的数据集 public Object getItem(int position) { return data.get(position); } // 获得项目在数据集适配器的个数。 public int getCount() { return data.size(); } }; listView.setAdapter(adapter); listView.setonRefreshListener(new OnRefreshListener() { public void onRefresh() { new AsyncTask<Void, Void, Void>() { // ...b表示多个参数 protected Void doInBackground(Void... params) { try { // Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } // 增加一条数据到list中 data.addFirst("刷新后内容:每天都是新的一天!!!,親!要努力奋斗哦!!!"); return null; } protected void onPostExecute(Void result) { adapter.notifyDataSetChanged(); listView.onRefreshComplete(); } }.execute(null); } }); } }
5.接着是列表实现个过程MyListView.xml
package com.wang; import java.text.SimpleDateFormat; import java.util.Date; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.LinearInterpolator; import android.view.animation.RotateAnimation; import android.widget.AbsListView; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ProgressBar; import android.widget.TextView; public class MyListView extends ListView implements OnScrollListener { private static final String TAG = "listview"; private final static int RELEASE_To_REFRESH = 0; private final static int PULL_To_REFRESH = 1; private final static int REFRESHING = 2; private final static int DONE = 3; private final static int LOADING = 4; // 实际的padding的距离与界面上偏移距离的比例 private final static int RATIO = 3; private LayoutInflater inflater; private LinearLayout headView; private TextView tipsTextview; private TextView lastUpdatedTextView; private ImageView arrowImageView; private ProgressBar progressBar; private RotateAnimation animation; private RotateAnimation reverseAnimation; // 用于保证startY的值在一个完整的touch事件中只被记录一次 private boolean isRecored; private int headContentWidth; private int headContentHeight; private int startY; private int firstItemIndex; private int state; private boolean isBack; private OnRefreshListener refreshListener; private boolean isRefreshable; public MyListView(Context context) { super(context); // 调用下面初始化的函数 init(context); } public MyListView(Context context, AttributeSet attrs) { super(context, attrs); // 调用下面初始化的函数 init(context); } private void init(Context context) { // 获得LayoutInflater从给定的上下文。 inflater = LayoutInflater.from(context); // 实例化布局XML文件转换成相应的视图对象。 headView = (LinearLayout) inflater.inflate(R.layout.refresh, null); arrowImageView = (ImageView) headView .findViewById(R.id.head_arrowImageView); // 设置最小宽度 和高度 arrowImageView.setMinimumWidth(70); arrowImageView.setMinimumHeight(50); // 实例化布局XML文件转换成相应的视图对象。 progressBar = (ProgressBar) headView .findViewById(R.id.head_progressBar); tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView); lastUpdatedTextView = (TextView) headView .findViewById(R.id.head_lastUpdatedTextView); // 调用下拉刷新的方法 measureView(headView); // d得到原始高度和宽度 headContentHeight = headView.getMeasuredHeight(); headContentWidth = headView.getMeasuredWidth(); // 设置填充。视图可能添加的空间要求显示滚动条,这取决于风格和知名度的滚动条 headView.setPadding(0, -1 * headContentHeight, 0, 0); headView.invalidate(); // 标签用来识别一个日志消息的来源。标识类或活动日志调用发生 Log.v("size", "width:" + headContentWidth + " height:" + headContentHeight); // 添加一个固定视图出现在列表的顶部 addHeaderView(headView, null, false); // 设置监听事件 setOnScrollListener(this); // 动画效果实现下拉和松开时候图片的 180度 旋转 注意0, -180,和他是有区别的 -180, 0, animation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); // 设置加速度曲线为这个动画。默认值为一个线性插值。 animation.setInterpolator(new LinearInterpolator()); animation.setDuration(300); // 如果fillAfter是真的,转换,该动画执行完成时将会持续下去 animation.setFillAfter(true); reverseAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); // 设置加速度曲线为这个动画。默认值为一个线性插值。 reverseAnimation.setInterpolator(new LinearInterpolator()); reverseAnimation.setDuration(300); // 如果fillAfter是真的,转换,该动画执行完成时将会持续下去 reverseAnimation.setFillAfter(true); // 设置状态 state = DONE; // 设置不可刷新状态 isRefreshable = false; } // 回调方法时要调用的列表或网格已经滚动。这将完成之后调用的滚动方法 public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2, int arg3) { firstItemIndex = firstVisiableItem; } /* * 回调方法调用而列表视图或网格视图被滚动。 如果这个视图被滚动,将调用此方法在接下来的一局画卷的呈现 * */ public void onScrollStateChanged(AbsListView arg0, int arg1) { } // 触摸事件监听 public boolean onTouchEvent(MotionEvent event) { // 判断是否可以刷新 if (isRefreshable) { // 根据动作相应不同的方法 switch (event.getAction()) { // 当按住屏幕向下拉屏幕的时候 case MotionEvent.ACTION_DOWN: if (firstItemIndex == 0 && !isRecored) { isRecored = true; startY = (int) event.getY(); Log.v(TAG, "在下拉的时候记录当前位置‘"); } break; // 当按住屏幕向上松屏幕的时候 case MotionEvent.ACTION_UP: if (state != REFRESHING && state != LOADING) { if (state == DONE) { } if (state == PULL_To_REFRESH) { state = DONE; changeHeaderViewByState(); Log.v(TAG, "由下拉刷新状态,到done状态"); } if (state == RELEASE_To_REFRESH) { state = REFRESHING; changeHeaderViewByState(); onRefresh(); Log.v(TAG, "由松开刷新状态,到done状态"); } } isRecored = false; isBack = false; break; // 当按住屏幕移动时候 case MotionEvent.ACTION_MOVE: int tempY = (int) event.getY(); if (!isRecored && firstItemIndex == 0) { Log.v(TAG, "在move时候记录下位置"); isRecored = true; startY = tempY; } if (state != REFRESHING && isRecored && state != LOADING) { /*** * , 当前的位置一直是在head,否则如果当列表超出屏幕的话, 当在上推的时候,列表会同时进行滚动 */ // 可以松手去刷新了 if (state == RELEASE_To_REFRESH) { setSelection(0); // 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步 if (((tempY - startY) / RATIO < headContentHeight) && (tempY - startY) > 0) { state = PULL_To_REFRESH; changeHeaderViewByState(); Log.v(TAG, "由松开刷新状态转变到下拉刷新状态"); } // 一下子推到顶了 else if (tempY - startY <= 0) { state = DONE; // 调用改变时候的方法,更新UI changeHeaderViewByState(); Log.v(TAG, "由松开刷新状态转变到done状态"); } else { } } // 还没有到达显示松开刷新的时候 if (state == PULL_To_REFRESH) { setSelection(0); // 下拉到可以进入RELEASE_TO_REFRESH的状态 if ((tempY - startY) / RATIO >= headContentHeight) { state = RELEASE_To_REFRESH; isBack = true; // 调用改变时候的方法,更新UI changeHeaderViewByState(); Log.v(TAG, "由done或者下拉刷新状态转变到松开刷新"); } // 上推到顶了 else if (tempY - startY <= 0) { state = DONE; // 调用改变时候的方法,更新UI changeHeaderViewByState(); Log.v(TAG, "由DOne或者下拉刷新状态转变到done状态"); } } // done状态下 if (state == DONE) { if (tempY - startY > 0) { state = PULL_To_REFRESH; // 调用改变时候的方法,更新UI changeHeaderViewByState(); } } // 更新headView的size if (state == PULL_To_REFRESH) { headView.setPadding(0, -1 * headContentHeight + (tempY - startY) / RATIO, 0, 0); } // 更新headView的paddingTop if (state == RELEASE_To_REFRESH) { headView.setPadding(0, (tempY - startY) / RATIO - headContentHeight, 0, 0); } } break; } } return super.onTouchEvent(event); } // 当状态改变时候,调用该方法,以更新界面 private void changeHeaderViewByState() { // 根据当前的状态进行判断 switch (state) { // 下拉时候,松开既可刷新 case RELEASE_To_REFRESH: // 设置视图 VISIBLE 可见 ,GONE 不可见 arrowImageView.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); tipsTextview.setVisibility(View.VISIBLE); lastUpdatedTextView.setVisibility(View.VISIBLE); // 现在开始指定的动画。 arrowImageView.clearAnimation(); arrowImageView.startAnimation(animation); tipsTextview.setText("松开既可刷新"); Log.v(TAG, "当前状态,松开即可刷新"); break; // 开始时候,下拉刷新 case PULL_To_REFRESH: // 设置视图 VISIBLE 可见 ,GONE 不可见 progressBar.setVisibility(View.GONE); tipsTextview.setVisibility(View.VISIBLE); lastUpdatedTextView.setVisibility(View.VISIBLE); // 现在开始指定的动画。 arrowImageView.clearAnimation(); arrowImageView.setVisibility(View.VISIBLE); if (isBack) { isBack = false; // 现在开始指定的动画。 arrowImageView.clearAnimation(); arrowImageView.startAnimation(reverseAnimation); tipsTextview.setText("下拉刷新"); } else { tipsTextview.setText("下拉刷新"); } Log.v(TAG, "当前状态,下拉刷新"); break; case REFRESHING: headView.setPadding(0, 0, 0, 0); // 设置视图 VISIBLE 可见 ,GONE 不可见 progressBar.setVisibility(View.VISIBLE); // 现在开始指定的动画。 arrowImageView.clearAnimation(); arrowImageView.setVisibility(View.GONE); tipsTextview.setText("正在刷新..."); lastUpdatedTextView.setVisibility(View.VISIBLE); Log.v(TAG, "当前状态,正在刷新..."); break; case DONE: // 设置填充。视图可能添加的空间要求显示滚动条 headView.setPadding(0, -1 * headContentHeight, 0, 0); // 设置视图 VISIBLE 可见 ,GONE 不可见 progressBar.setVisibility(View.GONE); // 现在开始指定的动画。 arrowImageView.clearAnimation(); arrowImageView.setImageResource(R.drawable.down); tipsTextview.setText("下拉刷新"); lastUpdatedTextView.setVisibility(View.VISIBLE); Log.v(TAG, "当前状态"); break; } } public void setonRefreshListener(OnRefreshListener refreshListener) { this.refreshListener = refreshListener; isRefreshable = true; } public interface OnRefreshListener { public void onRefresh(); } // 设置更新时间 public void onRefreshComplete() { state = DONE; // SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm"); String date = format.format(new Date()); lastUpdatedTextView.setText("最近更新:" + date); changeHeaderViewByState(); } private void onRefresh() { if (refreshListener != null) { refreshListener.onRefresh(); } } // 下拉刷新的 private void measureView(View child) { // v这组布局参数宽度和高度 ViewGroup.LayoutParams p = child.getLayoutParams(); if (p == null) { // 创建一个新组布局参数指定的宽度(填充)和高度(包裹)。 p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); } // d得到childWidthSpec(高度或宽度)的子视图 int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width); int lpHeight = p.height; int childHeightSpec; if (lpHeight > 0) { // 创建一个测量规范基于所提供的大小和模式 childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); } else { childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } // 找出一个视图应该多大。父供应约束信息在宽度和高度参数 child.measure(childWidthSpec, childHeightSpec); } public void setAdapter(BaseAdapter adapter) { // 设置最近刷新的时间 SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm"); String date = format.format(new Date()); lastUpdatedTextView.setText("最近更新:" + date); super.setAdapter(adapter); } }
1、帧缓存:一般指保存我们正在渲染图像的那块内存。渲染可以在显示器屏幕上进行,一个文件上进行,一个AVI中的一帧,或者是一张纹理上。
The frame buffer is the memory of the graphics display device, which means the image is displayed on your screen.
OpenGL does not render (draw) these primitives directly on the screen. Instead, rendering is done in a buffer, which is later swapped to the screen. We refer to these two buffers as thefront(the screen) and
back color buffers. By default, OpenGL commands are rendered into the back buffer, and when you call glutSwapBuffers (or your operating system–specific buffer swap function), the front and back buffers are swapped so that
you can see the rendering results. You can, however, render directly into the front buffer if you want. (glDrawBuffer)
When you do single-buffered rendering, it is important to call either
glFlush or glFinish whenever you want to see the results actually drawn to screen. A buffer swap implicitly performs a flush of the pipeline and waits for rendering to complete before the swap actually occurs.
2、3D中,水平方向上的缩放值和垂直方向上的比例要适中,否则图像将会变形。一般情况下,这个比例要和显示图像的窗口的水平方向和垂直方向的大小比例保持一致。
3、object space = modeling space = local space ------------ model transformation
camera space = eye space
clip space = canonical view volume space -------------- clip transformation
4、Two principal tasks are required to create an image of a three-dimensional scene: modeling and rendering. The modeling task generates a model, which is the description of an object that is going to be used by the graphics system. Models must be created for every object in a scene; they should accurately capture the geometric shape and appearance of the object. Some or all of this task commonly occurs when the application is being developed, by creating and storing model descriptions as part of the application’s data.
The second task, rendering, takes models as input and generates pixel values for the final image. OpenGL is principally concerned with object rendering; it does not provide explicit support for creating object models. The model input data is left to the application to provide. The OpenGL architecture is focused primarily on rendering polygonal models; it doesn’t directly support more complex object descriptions, such as implicit surfaces.
To provide accurate rendering of a model’s appearance or surface shading, the modeler may also have to determine color values, shading normals, and texture coordinates for the model’s vertices and faces.
5、To smoothly shade an object, a given vertex normal should be used by all polygons that share that vertex. Ideally, this vertex normal is the same as the surface normal at the corresponding point on the original surface. However, if the true surface normal isn’t available, the simplest way to approximate one is to add all (normalized) normals from the common facets then renormalize the result (Gouraud, 1971). This provides reasonable results for surfaces that are fairly smooth, but does not look good for surfaces with sharp edges.
6、Since the polygon winding may be used to cull back or front-facing triangles, for performance reasons it is important that models are made consistent; a polygon wound inconsistently with its neighbors should have its vertex order reversed. A good way to accomplish this is to find all common edges and verify that neighboring polygon edges are drawn in the opposite order.
To ensure that the rewound model is oriented properly (i.e., all polygons are wound so that their front faces are on the outside surface of the object), the algorithm begins by choosing and properly orienting the seed polygon. One way to do this is to find
the geometric center of the object: compute the object’s bounding box, then compute its mid-point. Next, select a vertex that is the maximum distance from the center point and compute a (normalized) out vector from the center point to this vertex. One of the
polygons using that vertex is chosen as the seed. Compute the normal of the seed polygon, then compute the dot product of the normalwith the out vector. A positive result indicates that seed is oriented correctly. A negative result indicates the polygon’s
normal is facing inward. If the seed polygon is backward, reverse its winding before using it to rewind the rest of the model.
7、vertex buffer objects
In OpenGL 1.5, vertex buffer objects were added to the specification to enable the same server placement optimizations that are used with display lists. Vertex buffer objects allow the application to allocate vertex data storage that is managed by the OpenGL
implementation and can be allocated from accelerator memory. The application can store vertex data to the buffer using an explicit transfer command (glBufferData), or by mapping the buffer (glMapBuffer). The vertex buffer data can also be examined by the application
allowing dynamic modification of the data, though it may be slower if the buffer storage is now in the accelerator. Having dynamic read-write access allows geometric data to be modified each frame, without requiring the application to maintain a separate copy
of the data or explicitly copy it to and from the accelerator. Vertex buffer objects are used with the vertex array drawing commands by binding a vertex buffer object to the appropriate array binding point (vertex, color, normal, texture coordinate) using
the array point commands (for example, glNormalPointer). When an array has a bound buffer object, the array pointer is interpreted relative to the buffer object storage rather than application memory addresses.
8、The OpenGL transformation pipeline can be thought of as a series of cartesian coordinate spaces connected by transformations that can be directly set by the application. Five spaces are used: object space, which starts with the application’s coordinates, eye space, where the scene is assembled, clip space, which defines the geometry that will be visible in the scene, NDC space, the canonical space resulting from perspective division, and window space, which maps to the framebuffer’s pixel locations.
The pipeline begins with texture, vertex, and light position coordinates, along with normal vectors, sent down from the application. These untransformed values are said to be in object space. If the application has enabled the generation of object space
texture coordinates, they are created here from untransformed vertex positions.
The modelview matrix is typically used to assemble a series of objects into a coherent scene viewed from a particular vantage.
An important use of the modelview matrix is modifying the parameters of OpenGL light sources. When a light position is issued using the glLight() command, the position or direction of the light is transformed by the current modelview matrix before being
stored. The transformed position is used in the lighting computations until it’s updated with a new call to glLight().
The eye space coordinate system is where object lighting is applied and eye-space texture coordinate generation occurs. OpenGL makes certain assumptions about eye space. The viewer position is defined to be at the origin of the eye-space coordinate system.
The direction of view is assumed to be the negative z-axis, and the viewer’s up position is the y-axis.
Normals are consumed by the pipeline in eye space. If lighting is enabled, they are used by the lighting equation—along with eye position and light positions—to modify the current vertex color. The projection transform transforms the remaining vertex and
texture coordinates into clip space. If the projection transform has perspective elements in it, the w values of the transformed vertices are modified.
If new vertices are generated as a result of clipping, the new vertices will have texture coordinates and colors interpolated to match the new vertex positions. The exact shape of the viewvolume depends on the type of projection transform; a perspective
transformation results in a frustum (a pyramid with the tip cut off), while an orthographic projection will create a parallelepiped volume.
9. Render: Rendering is the act of taking a geometric description of a three-dimensional object and turning it into an image of that object onscreen.
10. Perspective: Perspective refers to the angles between lines that lend the illusion of three dimensions.
11. You expect the front of an object to obscure the back of the object from view. For solid surfaces, we call this hidden surface removal.
12. This technique of applying an image to a polygon to supply additional detail is called texture mapping. The image you supply is called a texture, and the individual elements of the texture are called texels. Finally, the process of stretching or compressing the texels over the surface of an object is called filtering.
13. Blending(混合) is the combination of colors or objects on the screen. By varying the amount each object is blended with the scene, you can make objects look transparent such that you see the object and what is behind it (such as glass or a ghost image).
14. By carefully blending the lines with the back-ground color, you can eliminate the jagged edges and give the lines a smooth appearance, This blending technique is called antialiasing. 简单的说也就是将图像边缘及其两侧的像素颜色进行混合,然后用新生成的具有混合特性的点来替换原来位置上的点以达到柔化物体外形、消除锯齿的效果。
15. With both immediate mode and retained mode, new commands have no effect on rendering commands that have already been executed.
16. A window is measured physically in terms of pixels. Before you can start plotting points, lines, and shapes in a window, you must tell OpenGL how to translate specified coordinate pairs into screen coordinates. You do this by specifying the region of Cartesian space that occupies the window; this region is known as the clipping region.
17. Viewports: Mapping Drawing Coordinates to Window Coordinates. Rarely will your clipping area width and height exactly match the width and height of the window in pixels. The coordinate system must therefore be mapped
from logical Cartesian coordinates to
physical screen pixel coordinates. This mapping is specified by a setting
known as the viewport. The viewport is the region within the window’s client area that is used for drawing the clipping area. The viewport simply maps the clipping area to a region of the window. Usually, the viewport is defined
as the entire window, but this is not strictly necessary; for instance, you might want to draw only in the lower half of the window.
18. The Vertex—A Position in Space. A vertex is nothing more than a coordinate in 2D or 3D space.
19. Primitives are one- or two-dimensional entities or surfaces such as points, lines, and polygons (a flat, multisided shape) that are assembled in 3D space to create 3D objects.
20. OpenGL is a procedural rather than a descriptive graphics API. Instead of describing the scene and how it should appear, the programmer actually prescribes the steps necessary to achieve a certain appearance or effect.
These “steps” involve calls to the many OpenGL commands. These commands are used to draw graphics primitives such as points, lines, and polygons in three dimensions. In addition, OpenGL supports lighting and shading, texture mapping, blending, transparency,
animation, and many other special effects and capabilities.
21. OpenGL的数据类型
- GLenum: 用于GL枚举的无符号整型。通常用于通知OpenGL由指针传递的存储于数组中数据的类型(例如,GL_FLOAT用于指示数组由GLfloat组成)。
- GLboolean: 用于单布尔值。OpenGL ES还定义了其自己的“真”和“假”值(GL_TRUE和GL_FALSE)以避免平台和语言的差别。当向OpenGL传递布尔值时,请使用这些值而不是使用YES或NO(尽管由于它们的定义实际没有区别,即使你不小心使用了YES或NO。但是,使用GL-定义值是一个好的习惯。)
- GLbitfield: 用于将多个布尔值(最多32个)打包到单个使用位操作变量的四字节整型。
- GLbyte: 有符号单字节整型,包含数值从-128 到 127
- GLshort: 有符号双字节整型,包含数值从−32,768 到 32,767
- GLint: 有符号四字节整型,包含数值从−2,147,483,648 到 2,147,483,647
- GLsizei: 有符号四字节整型,用于代表数据的尺寸(字节),类似于C中的size_t
- GLubyte: 无符号单字节整型,包含数值从0 到 255。
- GLushort: 无符号双字节整型,包含数值从0 到 65,535
- GLuint: 无符号四字节整型,包含数值从0 到 4,294,967,295
- GLfloat: 四字节精度IEEE 754-1985 浮点数
- GLclampf: 这也是四字节精度浮点数,但OpenGL使用GLclampf特别表示数值为0.0 到 1.0
- GLvoid: void值用于指示一个函数没有返回值,或没有参数
- GLfixed: 定点数 使用整型数存储实数。由于大部分计算机处理器在处理整型数比处理浮点数快很多,这通常是对3D系统的优化方式。
- GLclampx: 另一种定点型,用于使用定点运算来表示0.0 到 1.0之间的实数。
- 22. OpenGL uses floats internally, and using anything other than the single-precision floating-point functions adds a performance bottleneck because the values are converted to floats anyhow before being processed by OpenGL.
- 23. GLUT_SINGLE: A single-buffered window means that all drawing commands are performed on the window displayed. An alternative is adouble-buffered window, where the drawing commands are actually executed on an offscreen buffer and then quickly swapped into view on the window. This method is often used to produce animation effects.
-
Double buffering can serve two purposes. The first is that some complex drawings might take a long time to draw, and you might not want each step of the image composition to be visible. Using double buffering, you can compose an image and display it only after
it is complete. The user never sees a partial image; only after the entire image is ready is it shown onscreen. A second use for double buffering is animation. Each frame is drawn in the offscreen buffer and then swapped quickly to the screen when ready.
The GLUT library supports double-buffered windows.
- 24. alpha component, which is used for blending and special effects such as transparency. Transparency refers to an object’s capability to allow light to pass through it. Suppose you would like to create a piece of red stained glass, and a blue light happens to be shining behind it. The blue light affects the appearance of the red in the glass (blue + red = purple). You can use the alpha component value to generate a red color that is semitransparent so that it works like a sheet of glass—an object behind it shows through.
- 25. A buffer is a storage area for image information. The red, green, and blue components of a drawing are usually collectively referred to as the color buffer or pixel buffer. More than one kind of buffer (color, depth, stencil, and accumulation) is available in OpenGL. You will also see the term framebuffer, which refers to all these buffers collectively since they work in tandem.
- 26. The aspect ratio is the ratio of the number of pixels along a unit of length in the vertical direction to the number of pixels along the same unit of length in the horizontal direction. In English, this just means the width of the window divided by the height.
-
27. Rotation: To rotate an object about one of the three coordinate axes, or indeed any arbitrary vector, you have to devise a rotation matrix. Again, a high-level function comes to the rescue: glRotatef(GLfloat angle, GLfloat x,
GLfloat y, GLfloat z); Here, we perform a rotation around the vector specified by the x, y, and z arguments. The
angle of rotation is in the counterclockwise direction measured in degrees and specified by the argumentangle.
Gstreamer解决什么问题?
Gstreamer基础
Gstreamer Core,是gstreamer框架的骨干和核心。它提供的功能有:
(一)提供一些组件类型的基类的实现,以及这些组件之间的通信规则;
(二)提供给应用程序创建媒体实例的API,以及保证实例运行的各种机制API.
Gstreamer Core的本质是不在乎媒体文件是什么类型或什么格式的(media-agnostic),因为它不关心媒体编解码等具体细节。可以认为它是一个最高级的管理者和组织者,它提供了一个流媒体程序框架或者叫做蓝图,下属人员可以通过领会它的旨意去具体开展工作;你也可以理解它为一个服务供应商,提供了一切多媒体应用程序可能需要的元件,开发人员可以利用它来去实现自己的专属程序。Gstreamer在初始化时只注册了核心元件,包括bin和pipeline,用户需要以此为基础,实现自己的多样化的多媒体管道程序。多媒体应用程序的实现,需要用户自己利用好gstreamer,然后实现自己的东东。
Smith先生版权所有,如需转载,请注明出处:http://blog.csdn.net/acs713/article/details/7777946
否者,保留追究其法律责任的权利