OpenGL构建简单物体

1.几何图形类
1.1点
1.2平面圆
1.3圆柱体
2.物体构建器
2.1用三角扇(GL_TRIANGLE_FAN)构造圆
2.2用三角形(GL_TRIANGLE_STRIP)构造圆柱体侧面
3.将要生成的物体封装成各自类
3.1Puck
3.2Mallet
3.3Table
4.简单的矩阵层次结构
4.1投影矩阵:即三维空间在屏幕上的显示方式(一般onSurfaceChanged中作设置)
4.2视图矩阵:即摄像头相关设置(一般onSurfaceChanged中作设置)
4.3模型矩阵:即旋转、缩放、移动操作(一般onDrawFrame中作设置)
4.4三者矩阵组合(相乘)后传递给着色器矩阵,以这种方式把事物分开,使操作场景和物体变得更加容易。
5.setLookAtM(rm, rmOffset, eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
rm:存储视图矩阵的目标矩阵
rmOffset:从rm的偏移量rmOffset开始存储矩阵数据
eyeX, eyeY, eyeZ:摄像头(眼睛)位置
centerX, centerY, centerZ:摄像头面向的中心位置,即屏幕中心显示位置
upX, upY, upZ:摄像头(眼睛)正上方
6.渲染器代码

package com.example.firstopengl;

import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
import static android.opengl.GLES20.glClear;
import static android.opengl.GLES20.glClearColor;
import static android.opengl.GLES20.glViewport;
import static android.opengl.Matrix.multiplyMM;
import static android.opengl.Matrix.perspectiveM;
import static android.opengl.Matrix.rotateM;
import static android.opengl.Matrix.setIdentityM;
import static android.opengl.Matrix.setLookAtM;
import static android.opengl.Matrix.translateM;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import com.example.firstopengl.objs.Mallet;
import com.example.firstopengl.objs.Puck;
import com.example.firstopengl.objs.Table;
import com.example.firstopengl.programs.ColorShaderProgram;
import com.example.firstopengl.programs.TextureShaderProgram;
import com.example.firstopengl.util.TextureHelper;

import android.content.Context;
import android.opengl.GLSurfaceView.Renderer;

public class MyRenderer implements Renderer {
    private final Context context;

    //投影矩阵,即三维空间在屏幕上的显示方式
    private final float[] projectionMatrix = new float[16]; 
    //模型矩阵,即旋转、缩放、移动操作
    private final float[] modelMatrix = new float[16];  
    //视图矩阵,即摄像头相关设置
    private final float[] viewMatrix = new float[16];
    //视图投影矩阵,即 视图矩阵*投影矩阵
    private final float[] viewProjectionMatrix = new float[16];
    //模型视图投影矩阵,该矩阵最后传递给着色器,即 模型矩阵*视图矩阵*投影矩阵 
    private final float[] modelViewProjectionMatrix = new float[16];

    //着色器程序
    private TextureShaderProgram textureProgram;
    private ColorShaderProgram colorProgram;
    //纹理
    private int texture;

    //objs
    private Table table;
    private Puck puck;
    private Mallet mallet;

    public MyRenderer(Context context) {
        // TODO Auto-generated constructor stub
        this.context = context;
    }

    // 绘制每一帧时,GLSurfaceView调用(suface创建后)
    @Override
    public void onDrawFrame(GL10 gl) {
        // TODO Auto-generated method stub
        // 清除屏幕颜色
        glClear(GL_COLOR_BUFFER_BIT);

        //绘制table
        positionTableInScene();
        textureProgram.useProgram();
        textureProgram.setUniforms(modelViewProjectionMatrix, texture);
        table.bindData(textureProgram);
        table.draw();

        //绘制mallet
        positionObjInScene(0f, mallet.height/2f, -0.4f);
        colorProgram.useProgram();
        colorProgram.setUniforms(modelViewProjectionMatrix, 1f, 0f, 0f);
        mallet.bindData(colorProgram);
        mallet.draw();

        positionObjInScene(0f, mallet.height/2f, 0.4f);
        colorProgram.setUniforms(modelViewProjectionMatrix, 0f, 0f, 1f);
        mallet.draw();

        //绘制puck
        positionObjInScene(0f, mallet.height/2f, 0f);
        colorProgram.setUniforms(modelViewProjectionMatrix, 0.8f, 0.8f, 1f);
        puck.bindData(colorProgram);
        puck.draw();
    }

    // suface视图大小改变时,GLSurfaceView调用(suface创建后)
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // TODO Auto-generated method stub
        // 设置视图大小
        glViewport(0, 0, width, height);
        //创建透视投影矩阵
        perspectiveM(projectionMatrix, 0, 
                45,                         //摄像头焦距,即观察视野大小
                (float)width/(float)height, //屏幕的宽高比
                1f, 10f);                   //摄像头到近远平面的距离
        //创建视图矩阵,即摄像头相关设置
        setLookAtM(viewMatrix, 0, 
                0f, 1.2f, 2.2f, //摄像头位置
                0f, 0f, 0f,     //观察点
                0f, 1f, 0f);    //摄像头正上方
        //视图投影矩阵  = 投影矩阵 * 视图矩阵
        multiplyMM(viewProjectionMatrix, 0, projectionMatrix, 0, viewMatrix, 0);
    }

    // suface创建时,GLSurfaceView调用
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // TODO Auto-generated method stub
        // 清空屏幕的颜色
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

        mallet = new Mallet(0.08f, 0.15f, 32);
        puck = new Puck(0.06f, 0.02f, 32);
        table = new Table();

        textureProgram = new TextureShaderProgram(context);
        colorProgram = new ColorShaderProgram(context);

        texture = TextureHelper.loadTexture(context, R.drawable.ic_launcher);
    }

    /**
     * table坐标作模型矩阵变换,即绕x轴旋转-90度       
     * 模型视图投影矩阵 = 模型矩阵*视图矩阵*投影矩阵
     */
    private void positionTableInScene(){
        setIdentityM(modelMatrix, 0);
        rotateM(modelMatrix, 0, -90f, 1f, 0f, 0f);
        multiplyMM(modelViewProjectionMatrix, 0, viewProjectionMatrix, 0,
                modelMatrix, 0);
    }

    /**
     * 物体坐标作模型矩阵变换,即在前者modelMatrix矩阵上再作移动操作来确定下面物体绘制的位置
     * 模型视图投影矩阵 = 模型矩阵*视图矩阵*投影矩阵
     * @param x
     * @param y
     * @param z
     */
    private void positionObjInScene(float x, float y, float z){
        setIdentityM(modelMatrix, 0);
        translateM(modelMatrix, 0, x, y, z);
        multiplyMM(modelViewProjectionMatrix, 0, viewProjectionMatrix, 0,
                modelMatrix, 0);
    }
}

7.源码:https://github.com/HQlin/ShaderOpenGL/commits/master

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值