OpenGL学习(2)基本图形绘制
继续OpenGL学习(1)基本概念
进行绘制基本图形
只需修改GLRender
package com.android.chapter3;
import java.nio.IntBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
public class GLRender implements Renderer
{
int one = 0x10000;
// 用于控制三角形和正方形旋转的角度
float rotateTri, rotateQuad;
//三角形三个顶点
private IntBuffer triggerBuffer = IntBuffer.wrap(new int[]{
0, one,0, //上顶点
-one,-one,0, //左下点
one,-one,0,}); //右下点
//正方形的4个顶点
private IntBuffer quaterBuffer = IntBuffer.wrap(new int[]{
one, one,0,
-one, one,0,
one,-one,0,
-one,-one,0});
//三角形的顶点颜色值(r,g,b,a)
private IntBuffer colorBuffer = IntBuffer.wrap(new int[]{
one, 0, 0,one,
0,one, 0,one,
0, 0,one,one,
});
@Override
public void onDrawFrame(GL10 gl)
{
// TODO Auto-generated method stub
// 首先清理屏幕
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 设置模型视图矩阵
gl.glMatrixMode(GL10.GL_MODELVIEW);
//重置矩阵
gl.glLoadIdentity();
// 视点变换
GLU.gluLookAt(gl, 0, 0, 3, 0, 0, 0, 0, 1, 0);
// 设置模型位置
gl.glTranslatef(-3.0f, 0.0f, -4.0f);
//设置旋转(y轴)
gl.glRotatef(rotateTri, 0.0f, 1.0f, 0.0f);
// 允许设置顶点
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// 允许设置颜色数组
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
//设置颜色数组
gl.glColorPointer(4, GL10.GL_FIXED, 0, colorBuffer);
// 设置三角形的顶点数据
gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer);
//放大三角形
gl.glScalef(2.0f, 2.0f, 2.0f);
//绘制三角形
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
//关闭颜色数组的设置
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
/*****正方形*****/
//设置正方形的颜色
gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
// 重置当前的模型观察矩阵
gl.glLoadIdentity();
// 设置模型位置
gl.glTranslatef(1.0f, 0.0f, -4.0f);
//设置旋转(x轴)
gl.glRotatef(rotateQuad, 1.0f, 0.0f, 0.0f);
//设置正方形顶点数组
gl.glVertexPointer(3, GL10.GL_FIXED, 0, quaterBuffer);
//绘制正方形
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
/* 绘制出来则是线框 */
//gl.glDrawArrays(GL10.GL_LINES, 0, 4);
// 取消顶点设置
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//改变旋转的角度
rotateTri += 0.5f;
rotateQuad -= 0.5f;
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
// TODO Auto-generated method stub
float ratio = (float) width / height;
// 设置视口(OpenGL场景的大小)
gl.glViewport(0, 0, width, height);
// 设置投影矩阵为透视投影
gl.glMatrixMode(GL10.GL_PROJECTION);
// 重置投影矩阵(置为单位矩阵)
gl.glLoadIdentity();
//创建一个透视投影矩阵(设置视口大小)
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
// TODO Auto-generated method stub
//告诉系统需要对透视进行修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
//设置清理屏幕的颜色
gl.glClearColor(0, 0, 0, 1);
//启用深度缓存
gl.glEnable(GL10.GL_DEPTH_TEST);
}
}
出现错误:
java.lang.IllegalArgumentException: Must use a native order direct Buffer异常。
最后发现不能通过这种方式创建顶点缓存数组。
package com.example.mychapter2;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView.Renderer;
import android.util.Log;
public class GLRender implements Renderer{
private String TAG = "GLRender";
float roateTri;//用于三角形的角度
float roateQuad;//用于四边形的角度
int one = 0x10000;
/*//三角形三个顶点
private IntBuffer triggerBuffer = IntBuffer.wrap(new int[]{
0,one,0,
-one,-one,0,
one,-one,0,
});
//四边形四个顶点
private IntBuffer quaterBuffer = IntBuffer.wrap(new int[]{
-one,one,0,
one,one,0,
one,-one,0,
-one,-one,0,
});*/
int [] colorArray = {
one,0,0,one,
0,one,0,one,
0,0,one,one,
};
int [] triggerArray ={
0,one,0,
-one,-one,0,
one,-one,0};
int [] quaterArray = {
one,one,0,
-one,one,0,
one,-one,0,
-one,-one,0
};
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
Log.i(TAG, "onSurfaceCreated");
//告诉系统对透视进行修正,会使透视图看起来好看点
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
//黑色背景
gl.glClearColor(0, 0, 0, 0);//红,绿,蓝,apaha
//启动阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
//设置深度缓存
gl.glClearDepthf(1.0f);
//启用深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);
//所做深度测试的类型
gl.glDepthFunc(GL10.GL_LEQUAL);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
Log.i(TAG, "onSurfaceChanged width:"+width+" height:"+height);//1920 944
float radio = (float)width/height;
//设置OpenGL场景的大小
gl.glViewport(0, 0, width, height);
//设置投影矩阵,投影矩阵负责为场景增加透视
gl.glMatrixMode(GL10.GL_PROJECTION);
//重置投影矩阵
gl.glLoadIdentity();
//设置视口的大小 前四个参数去顶窗口的大小,分别是左,右,下,上,后两个参数分别是在场景中所能绘制深度的起点和终点
gl.glFrustumf(-radio, radio, -1, 1, 1, 10);
//指明任何新的变换即那个会影响 模型观察矩阵
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
Log.i("GLRender", "onDrawFrame");
roateTri +=0.5f;
roateQuad-=0.5f;
//清除屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
// 重置当前的模型观察矩阵
gl.glLoadIdentity();
//移动当前中心点,左移1.5单位,并移入屏幕6.0,y不变
//注意:屏幕内移动的单位数必须小于前面我们通过
//glFrustumf方法所设置的最远距离,否则显示不出来。
//腰围OpenGL设置一个顶点数组,故需要告诉OpenGL要设置
//顶点这个功能。
//开启顶点设置功能
gl.glTranslatef(-1.5f, 0.0f, -6.0f);
//设置某无题沿着指定的轴旋转
//参数1:旋转的角度
//后三个参数共通决定旋转的方向
//注意:要在画图前,使用旋转
gl.glRotatef(roateTri, 0.0f, -1.0f, 0.0f);
//开启颜色渲染功能
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
//设置颜色,平滑着色
gl.glColorPointer(4, GL10.GL_FIXED, 0, bufferUtil(colorArray));
//允许设置顶点
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//设置三角形
//参数1:描述顶点的尺寸,本例中使用X,Y,Z坐标系,所以是3
//参数2:描述顶点的类型,本例中数据是固定的,所以使用了GL_FIXED表示固定顶点
//参数3:描述步长
//参数4:顶点缓存,即我们创建的顶点数组
gl.glVertexPointer(3, GL10.GL_FIXED, 0, bufferUtil(triggerArray));
//绘制三角形
//参数1:绘制模式,GL_TRIANGLES:表示绘制三角形
//参数2:开始位置
//参数3:要绘制的顶点计数
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
//重置当前的模型观察矩阵
gl.glLoadIdentity();
//关闭颜色渲染
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
//左移1.5单位,并移入屏幕6.0
gl.glTranslatef(1.5f, 0.0f, -6.0f);
gl.glRotatef(roateQuad, 1.0f, 0.0f, 0.0f);
//开启颜色渲染功能
gl.glEnableClientState(GL10.GL_COLOR_BUFFER_BIT);
//设置颜色,单调着色 (r,g,b,a)
gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
//设置和绘制正方形
gl.glVertexPointer(3, GL10.GL_FIXED, 0, bufferUtil(quaterArray));
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
//关闭颜色渲染
gl.glDisableClientState(GL10.GL_COLOR_BUFFER_BIT);
//取消顶点设置
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
/*
* OpenGL 是一个非常底层的画图接口,它所使用的缓冲区存储结构是和我们的 java 程序中不相同的。
* Java 是大端字节序(BigEdian),而 OpenGL 所需要的数据是小端字节序(LittleEdian)。
* 所以,我们在将 Java 的缓冲区转化为 OpenGL 可用的缓冲区时需要作一些工作。建立buff的方法如下
* */
public Buffer bufferUtil(int []arr){
IntBuffer mBuffer ;
//先初始化buffer,数组的长度*4,因为一个int占4个字节
ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);
//数组排列用nativeOrder
qbb.order(ByteOrder.nativeOrder());
mBuffer = qbb.asIntBuffer();
mBuffer.put(arr);
mBuffer.position(0);
return mBuffer;
}
}
作者:wuxintdrh 发表于2016/8/15 1:23:48 原文链接
阅读:188 评论:0 查看评论