OpenGL ES: 画球
来源:互联网 发布:网络拓扑图的简要描述 编辑:程序博客网 时间:2024/06/04 00:44
画球
球坐标公式
球坐标可以用如下公式表示:
在Eclipse中新建工程DrawBall, 新建Ball类, 添加成员方法初始化顶点数组,获取球坐标代码如下:
/** * 初始化顶点数组 * ANGLE_SPAN角度进行划分 * p3 p2 (beta + ANGLE_SPAN) * p0 p1 (alpha + ANGLE_SPAN) * 画两个三角形 p0p1p2, p0p2p3 */ private void initVertex() { vertex = new ArrayList<Float>(); for (int alpha = 0; alpha <= 360; alpha += ANGLE_SPAN) { for (int beta = -90; beta <= 90; beta += ANGLE_SPAN) { // 第一个点的坐标 float x0 = (float) (RADIAN * Math.cos(Math.toRadians(alpha)) * Math.cos(Math.toRadians(beta))); float y0 = (float) (RADIAN * Math.sin(Math.toRadians(alpha)) * Math.cos(Math.toRadians(beta))); float z0 = (float) (RADIAN * Math.sin(Math.toRadians(beta))); // 第二个点的坐标 float x1 = (float) (RADIAN * Math.cos(Math.toRadians(alpha + ANGLE_SPAN)) * Math.cos(Math.toRadians(beta))); float y1 = (float) (RADIAN * Math.sin(Math.toRadians(alpha + ANGLE_SPAN)) * Math.cos(Math.toRadians(beta))); float z1 = (float) (RADIAN * Math.sin(Math.toRadians(beta))); // 第三个点的坐标 float x2 = (float) (RADIAN * Math.cos(Math.toRadians(alpha + ANGLE_SPAN)) * Math.cos(Math.toRadians(beta + ANGLE_SPAN))); float y2 = (float) (RADIAN * Math.sin(Math.toRadians(alpha + ANGLE_SPAN)) * Math.cos(Math.toRadians(beta + ANGLE_SPAN))); float z2 = (float) (RADIAN * Math.sin(Math.toRadians(beta + ANGLE_SPAN))); // 第三个点的坐标 float x3 = (float) (RADIAN * Math.cos(Math.toRadians(alpha)) * Math.cos(Math.toRadians(beta + ANGLE_SPAN))); float y3 = (float) (RADIAN * Math.sin(Math.toRadians(alpha)) * Math.cos(Math.toRadians(beta + ANGLE_SPAN))); float z3 = (float) (RADIAN * Math.sin(Math.toRadians(beta + ANGLE_SPAN))); vertex.add(x0); vertex.add(y0); vertex.add(z0); vertex.add(x1); vertex.add(y1); vertex.add(z1); vertex.add(x2); vertex.add(y2); vertex.add(z2); vertex.add(x0); vertex.add(y0); vertex.add(z0); vertex.add(x2); vertex.add(y2); vertex.add(z2); vertex.add(x3); vertex.add(y3); vertex.add(z3); } } numVertex = vertex.size(); }
顶点着色器、片段着色器
新建顶点着色器和片段着色器
res/raw/vertex_shader.glsl
attribute vec4 aPosition;uniform mat4 vMatrix;void main() { gl_Position = vMatrix * aPosition;}
res/raw/fragment_shader.glsl
uniform vec4 uColor;void main(){ gl_FragColor = uColor;}
给Ball类添加构造函数,编译链接程序,
package com.example.drawball;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import java.util.ArrayList;import com.example.drawball.utils.BufferHelper;import com.example.drawball.utils.Logit;import com.example.drawball.utils.MatrixState;import com.example.drawball.utils.ShaderHelper;import com.example.drawball.utils.TextResourceReader;import com.example.drawcircle.R;import android.content.Context;import android.opengl.GLES30;public class Ball { private static final String TAG = "Circle"; private Context context; private FloatBuffer vertexBuffer; private FloatBuffer colorBuffer; private static final int BYTES_PER_FLOAT = 4; //浮点字节个数 private static final int COORS_PER_VERTEX = 3; // 顶点坐标分量个数 private static final int ANGLE_SPAN = 10; // 圆周划分角度10度 private static final float RADIANS = 0.5f; private int numVertex; private ArrayList<Float> vertex; private int program; //应用程序句柄 private static final String A_POSITION = "aPosition"; private static final String U_COLOR = "uColor"; private static final String V_MATRIX = "vMatrix"; private int vMatrixLocation; public Ball(Context context) { this.context = context; initVertex(); vertexBuffer = BufferHelper.getFloatBuffer(vertex); getProgram(); int aPositionLocation = GLES30.glGetAttribLocation(program, A_POSITION); // 对应于 vertex_shader.glsl 中 attribute属性 Logit.d(TAG, "aPosition location: " + aPositionLocation); GLES30.glVertexAttribPointer(aPositionLocation, COORS_PER_VERTEX, GLES30.GL_FLOAT, false, 0, vertexBuffer); // 区别glVertexAttribIPointer GLES30.glEnableVertexAttribArray(aPositionLocation); //启用顶点属性数组 int uColorLocation = GLES30.glGetUniformLocation(program, U_COLOR); // 对应与 fragment_shader 中uniform属性 Logit.d(TAG, "uColor Location: " + uColorLocation); GLES30.glUniform4f(uColorLocation, 1, 0, 0, 1); // 设置着色器中变量的值 vMatrixLocation = GLES30.glGetUniformLocation(program, V_MATRIX); } /** * 初始化顶点数组 * angleSpan角度进行划分 * point3 point2 (beta + angleSpan) * point0 point1 (alpha + angleSpan) */ private void initVertex() { vertex = new ArrayList<Float>(); for (int alpha = 0; alpha <= 360; alpha += ANGLE_SPAN) { for (int beta = -90; beta <= 90; beta += ANGLE_SPAN) { // 第一个点的坐标 float x0 = (float) (RADIANS * Math.cos(Math.toRadians(alpha)) * Math.cos(Math.toRadians(beta))); float y0 = (float) (RADIANS * Math.sin(Math.toRadians(alpha)) * Math.cos(Math.toRadians(beta))); float z0 = (float) (RADIANS * Math.sin(Math.toRadians(beta))); // 第二个点的坐标 float x1 = (float) (RADIANS * Math.cos(Math.toRadians(alpha + ANGLE_SPAN)) * Math.cos(Math.toRadians(beta))); float y1 = (float) (RADIANS * Math.sin(Math.toRadians(alpha + ANGLE_SPAN)) * Math.cos(Math.toRadians(beta))); float z1 = (float) (RADIANS * Math.sin(Math.toRadians(beta))); // 第三个点的坐标 float x2 = (float) (RADIANS * Math.cos(Math.toRadians(alpha + ANGLE_SPAN)) * Math.cos(Math.toRadians(beta + ANGLE_SPAN))); float y2 = (float) (RADIANS * Math.sin(Math.toRadians(alpha + ANGLE_SPAN)) * Math.cos(Math.toRadians(beta + ANGLE_SPAN))); float z2 = (float) (RADIANS * Math.sin(Math.toRadians(beta + ANGLE_SPAN))); // 第三个点的坐标 float x3 = (float) (RADIANS * Math.cos(Math.toRadians(alpha)) * Math.cos(Math.toRadians(beta + ANGLE_SPAN))); float y3 = (float) (RADIANS * Math.sin(Math.toRadians(alpha)) * Math.cos(Math.toRadians(beta + ANGLE_SPAN))); float z3 = (float) (RADIANS * Math.sin(Math.toRadians(beta + ANGLE_SPAN))); vertex.add(x0); vertex.add(y0); vertex.add(z0); vertex.add(x1); vertex.add(y1); vertex.add(z1); vertex.add(x2); vertex.add(y2); vertex.add(z2); vertex.add(x0); vertex.add(y0); vertex.add(z0); vertex.add(x2); vertex.add(y2); vertex.add(z2); vertex.add(x3); vertex.add(y3); vertex.add(z3); } } numVertex = vertex.size(); } private void getProgram() { String vertexSource = TextResourceReader.readTextFileFromResource(context, R.raw.vertex_shader); String fragmentSource = TextResourceReader.readTextFileFromResource(context, R.raw.fragment_shader);// int vertexShader = ShaderHelper.compileVertexShader(vertexSource);// int fragmentShader = ShaderHelper.compileFragmentShader(fragmentSource); //获取program的id program = ShaderHelper.buildProgram(vertexSource, fragmentSource); Logit.d(TAG, "program: " + program); GLES30.glUseProgram(program); // 不要忘记设置,否则不会起作用 } public void draw() {// GLES30.glUniform4f(2, 1, 0, 1, 0);// GLES30.glDrawElements(GLES30.GL_TRIANGLES, 3, GLES30.GL_FLOAT, vertexBuffer); GLES30.glUniformMatrix4fv(vMatrixLocation, 1, false, MatrixState.getFinalMatrix(), 0); GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, numVertex); }}
设置相机位置和透视投影
添加BallRenderer类,设置相机和透视投影
src/com/example/drawball/BallRenderer.java
package com.example.drawball;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.content.Context;import android.opengl.GLES30;import android.opengl.GLSurfaceView.Renderer;import com.example.drawball.utils.Logit;import com.example.drawball.utils.MatrixState;public class BallRenderer implements Renderer{ private static final String TAG = "CircleRenderer"; private Ball ball; private Context context; public BallRenderer(Context context) { // TODO Auto-generated constructor stub this.context = context; } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // TODO Auto-generated method stub Logit.d(TAG, "onSurfaceCreated."); ball = new Ball(context); GLES30.glClearColor(1, 1, 1, 1); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { // TODO Auto-generated method stub Logit.d(TAG, "onSurfaceChanded...");// GLES30.glViewport(0, 0, width, height); float ratio = 1.0f * width / height;//先转换成浮点数再做运算 MatrixState.setCamera(0, 0, 7, 0, 0, 0, 0, 1, 0); MatrixState.setProjectOrtho(-ratio, ratio, -1, 1, 5, 9); } @Override public void onDrawFrame(GL10 gl) { // TODO Auto-generated method stub Logit.d(TAG, "onDrawFrame"); GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT); ball.draw(); }}
package com.example.drawball;import android.app.Activity;import android.content.Context;import android.opengl.GLSurfaceView;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;public class BallActivity extends Activity { private GLSurfaceView mTriGLView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);// setContentView(R.layout.activity_tri); mTriGLView = new CircleGLSurfaceView(this); setContentView(mTriGLView); } static class CircleGLSurfaceView extends GLSurfaceView { public CircleGLSurfaceView(Context context) { super(context); setEGLContextClientVersion(3); setRenderer(new BallRenderer(context)); setRenderMode(RENDERMODE_WHEN_DIRTY); } }}
运行结果
渐变色球
将顶点位置作为颜色值传给片段着色器颜色值来绘制, 顶点着色器中添加varying 变量vColor存储顶点位置,传递给片段着色器, 如下:
顶点着色器、片段着色器
res/raw/vertex_shader1.glsl
attribute vec4 aPosition;uniform mat4 vMatrix;varying vec3 vColor;void main() { gl_Position = vMatrix * aPosition; vColor = aPosition.xyz;}
res/raw/fragment_shader1.glsl
uniform vec4 uColor;varying vec3 vColor;void main(){ gl_FragColor = vec4(vColor, 1.0);}
运行结果:
下载DrawBall
LaTeX公式编辑器
阅读全文
0 0
- openGL ES 画球
- openGL ES 画球
- OpenGL ES 画球
- OpenGL ES: 画球
- OPENGL ES
- OpenGL ES
- OpenGL ES
- opengl es
- OpenGL ES
- OpenGL ES
- opengl es
- OpenGL ES
- OpenGL ES
- OpenGL ES
- opengl ES
- openGL ES
- opengl es
- OpenGL ES
- 使VirtualBox支持安装64位系统的解决办法
- Ubuntu16.04: CUDA编程及CMakeLists.txt编写
- IDA动态调试dump加固的Dex文件(Dalvik4.4--)
- 在Eclipse中安装hibernate tools for eclipse plugins
- sql语句类型
- OpenGL ES: 画球
- 类似于expect的java 程序
- 设计师看过来:怎样让你的UI作品集脱颖而出?
- Jquery中each的三种遍历方法
- 【CIO早班车】解锁混合云的超能力,你还得get这几点
- osgEarth GLSL图像调色 17.glsl_filter.earth
- Kotlin 笔记
- 戴尔携手中央电化教育馆 共推中国教育信息化
- 条件运算符和错误防范