}
动态的三角形
package com.cardroid.opengl;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView;
public class GlRenderer implements GLSurfaceView.Renderer {
private static final String LOG_TAG = GlRenderer.class.getSimpleName();
private float _red = 0f;
private float _green = 0f;
private float _blue = 0f;
// a raw buffer to hold indices allowing a reuse of points.
private ShortBuffer _indexBuffer;
private ShortBuffer _indexBufferStatic;
// a raw buffer to hold the vertices
private FloatBuffer _vertexBuffer;
private FloatBuffer _vertexBufferStatic;
private FloatBuffer _colorBuffer;
private short[] _indicesArray = {0, 1, 2};
private int _nrOfVertices = 3;
private float _angle;
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// preparation
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
initTriangle();
initStaticTriangle();
}
@Override
public void onSurfaceChanged(GL10 gl, int w, int h) {
gl.glViewport(0, 0, w, h);
}
public void setAngle(float angle) {
_angle = angle;
}
@Override
public void onDrawFrame(GL10 gl) {
// define the color we want to be displayed as the "clipping wall"
gl.glClearColor(_red, _green, _blue, 1.0f);
// reset the matrix - good to fix the rotation to a static angle
gl.glLoadIdentity();
// clear the color buffer to show the ClearColor we called above...
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// 绘制静态三角形
gl.glColor4f(0f, 0.5f, 0f, 0.5f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBufferStatic);
gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBufferStatic);
// 设置非静态三角形的旋转
gl.glRotatef(_angle, 0f, 1f, 0f);
// gl.glColor4f(0.5f, 0f, 0f, 0.5f);
// gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer);
// gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, _colorBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer);
}
private void initTriangle() {
// float has 4 bytes
ByteBuffer vbb = ByteBuffer.allocateDirect(_nrOfVertices * 3 * 4);
vbb.order(ByteOrder.nativeOrder());
_vertexBuffer = vbb.asFloatBuffer();
// short has 2 bytes
ByteBuffer ibb = ByteBuffer.allocateDirect(_nrOfVertices * 2);
ibb.order(ByteOrder.nativeOrder());
_indexBuffer = ibb.asShortBuffer();
// float has 4 bytes, 4 colors (RGBA) * number of vertices * 4 bytes
ByteBuffer cbb = ByteBuffer.allocateDirect(4 * _nrOfVertices * 4);
cbb.order(ByteOrder.nativeOrder());
_colorBuffer = cbb.asFloatBuffer();
float[] coords = {
-0.5f, -0.5f, 0f, // (x1, y1, z1)
0.5f, -0.5f, 0f, // (x2, y2, z2)
0.5f, 0.5f, 0f // (x3, y3, z3)
};
float[] colors = {
1f, 0f, 0f, 1f, // point 1
0f, 1f, 0f, 1f, // point 2
0f, 0f, 1f, 1f, // point 3
};
_vertexBuffer.put(coords);
_indexBuffer.put(_indicesArray);
_colorBuffer.put(colors);
_vertexBuffer.position(0);
_indexBuffer.position(0);
_colorBuffer.position(0);
}
private void initStaticTriangle() {
// float has 4 bytes
ByteBuffer vbb = ByteBuffer.allocateDirect(_nrOfVertices * 3 * 4);
vbb.order(ByteOrder.nativeOrder());
_vertexBufferStatic = vbb.asFloatBuffer();
// short has 2 bytes
ByteBuffer ibb = ByteBuffer.allocateDirect(_nrOfVertices * 2);
ibb.order(ByteOrder.nativeOrder());
_indexBufferStatic = ibb.asShortBuffer();
float[] coords = {
-0.4f, -0.4f, 0f, // (x1, y1, z1)
0.4f, -0.4f, 0f, // (x2, y2, z2)
0f, 0.4f, 0f // (x3, y3, z3)
};
_vertexBufferStatic.put(coords);
_indexBufferStatic.put(_indicesArray);
_vertexBufferStatic.position(0);
_indexBufferStatic.position(0);
}
public void setColor(float r, float g, float b) {
_red = r;
_green = g;
_blue = b;
}
}
http://disanji.net/2010/11/12/android-3d-game-tutorial-part-vi436-html/
(1)glShadeModel : 选择阴影模式 flat( GL10.GL_FLAT) 或者 smooth shading ( GL10.GL_SMOOTH )
GL10.GL_FLAT : 平面阴影模式,对点、直线、多边形采用一种颜色进行绘制,整个图元的颜色就是它任何一点的颜色。
GL10.GL_SMOOTH: 平滑阴影模式,用多种颜色进行绘制,每个顶点有单独的颜色,Opengl为顶点填充合适的颜色,使相邻的颜色值非常接近,然后向其他顶点平滑均匀插值过度颜色,出现过度的渐变效果。
OpenGL图元需要进行明暗处理,处理得模式可以为平面明暗模式或光滑(Gouraud着色)明暗模式。光滑明暗模式时,多边形各个内部点的颜色是根据各顶点指定的颜色来插值得到的,这意味着两个顶点之间的颜色是从一顶点的颜色渐变到另一顶点的颜色。对于平面明暗模式,整个图元区域的颜色就是最后一个顶点指定的颜色。但要注意,如果激活了光照,计算到的顶点颜色都是光照后的结果颜色,若光照关闭,计算到的颜色就是指定顶点时的当前颜色。
(2)glClearColor :设置清除屏幕时所用的颜色
(3)glClearDepth函数设置深度缓冲区的,它的含义就在OpenGL窗口绘制的图形深入到屏幕中的程度,深度的意义就是在三维空间中的z坐标的数值,z取0时表示在平面上,你就看不到窗口中的图形了,所以负值越小,越远离窗口平面向里,说明窗口中的图形离我们观察者的距离变远了;
(4)glEnable(GL_DEPTH_TEST): 用来开启更新深度缓冲区的功能,也就是,如果通过比较后深度值发生变化了,会进行更新深度缓冲区的操作
(5)glDepthFunc:设置更新深度缓存的条件。只有调用gl.glEnable(GL10.GL_DEPTH_TEST)函数,即启用深度缓存的情况下,这个函数才能使用。
函数的参数func,即指定什么条件下更新深度值:
GL_LESS:深度更小的情况下,更新深度缓存进行渲染。
GL_EQUAL:深度相同情况下,更新深度缓存进行渲染。
GL_LEQUAL:深度更小或者相同,更新深度缓存进行渲染。
(6)glHint:在OpenGL中,许多细节的实现算法有所不同。这样,可以调用函数glHint()对图像质量和绘制速度之间的权衡作一些控制,但并非所有的实现都采用它。
参数target指定控制行为,接受GL_FOG_HINT , GL_GENERATE_MIPMAP_HINT , GL_LINE_SMOOTH_HINT , GL_PERSPECTIVE_CORRECTION_HINT, 和 GL_POINT_SMOOTH_HINT等常量。
参数mode指定期望的行为。接受GL_FASTEST(即给出最有效的选择)、GL_NICEST(即给出最高质量的选择)、GL_DONT_CARE(即没有选择)等常量。
二: 如果你的手持设备支持横屏和竖屏的切换,在切换过程中,你需要调用函数onSurfaceChanged来设置新的比率。
(1)glMatrixMode:设置矩阵的类型,有三个模式 GL_PROJECTION 投影, GL_MODELVIEW 模型视图, GL_TEXTURE 纹理.
投影矩阵:设置这个矩阵后就开始进行投影相关的操作,也就是将物体映射到2D空间上。设置投影矩阵并且重置用户坐标后,接下来就可以写和透视相关的操作,即创建视景体。例如glFrustum()或gluPerspective(),它们生成的矩阵会与当前的矩阵相互作用,生成透视的效果;或者调用glOrtho创建正交平行矩阵,和当前的矩阵作用,生成平投影的效果。
模型矩阵:设置这个矩阵用于旋转、移动、缩放场景中的物体。
纹理矩阵:纹理也是一个矩阵,需要修改纹理的时候,需要通过glMatrixMode切换到纹理矩阵才能修改。
(2)glViewport:设置场景
glFrustum、gluPerspective、glOrtho函数只是负责使用什么样的视景体来截取图像,并不负责使用某种规则把图像呈现在屏幕上。
glViewport负责把视景体截取的图像按照怎样的高和宽显示到屏幕上。
(3)glLoadIdentity:重置当前指定的矩阵为单位矩阵,类似复位的操作。
注释: 纹理就是位图,图片上的纹理就是花纹或者图案。纹理映射将图片作为纹理贴在一个矩形上。