[置顶] 自己动手实现OpenGL-OpenGL原来如此简单(二)

来源:互联网 发布:linux搭建telnet服务 编辑:程序博客网 时间:2024/05/22 23:48

上篇对glViewPort的实现可见一斑。但是并没有提及其中的思路所在。本篇主要是简短地介绍一下WGL的实现思路。

由于OpenGL是一个状态机,既然是状态机,那么肯定有一系列的状态需要保存。OpenGL的状态对应的是功能的实现。我们这个简单的OpenGL不需要大而全的功能,那么需要哪些功能呢?

1.绘制一个立方体或者长方体。

2.长方体或者立方体可以旋转

3.用上面的长方体代表太阳,地球,月亮。模拟其运行周期。

好吧,就上面三个功能。那么说我们上面的三个功能需要保存哪些状态呢?其实就以下三个状态就够了:

1. 矩阵管理

2. 颜色管理

3. 绘制线框

这么简单!

好吧,那么就定义几个变量吧!

1.矩阵管理

   矩阵管理,那么就必须有矩阵,那么我的矩阵是这样的:

  

/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.example.simulateopengl;import java.nio.FloatBuffer;import android.util.Log;/**  *  * A 4x4 float matrix * */public class M4 {public float[][] m = new float[4][4];public M4() {this.setIdentity();}@Overrideprotected Object clone() throws CloneNotSupportedException {// TODO Auto-generated method stubM4 other = new M4();for(int i = 0; i < 4; ++ i){for(int j = 0; j < 4; ++ j){other.m[i][j] = m[i][j];}}return other;}public M4(M4 other) {for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {m[i][j] = other.m[i][j];}}}public void project(GLVertex src, GLVertex dest) {GLVertex srcCopy = new GLVertex(src.x, src.y, src.z, src.w);dest.x = (float)(srcCopy.x * m[0][0] + srcCopy.y * m[0][1] + srcCopy.z * m[0][2] + m[0][3]*srcCopy.w);dest.y = (float)(srcCopy.x * m[1][0] + srcCopy.y * m[1][1] + srcCopy.z * m[1][2] + m[1][3]*srcCopy.w);dest.z = (float)(srcCopy.x * m[2][0] + srcCopy.y * m[2][1] + srcCopy.z * m[2][2] + m[2][3]*srcCopy.w);dest.w = (float)(srcCopy.x * m[3][0] + srcCopy.y * m[3][1] + srcCopy.z * m[3][2] + m[3][3]*srcCopy.w);}public static void normalize(GLVertex verVertex){verVertex.x = verVertex.x/verVertex.w;verVertex.y = verVertex.y/verVertex.w;verVertex.z = verVertex.z/verVertex.w;verVertex.w = verVertex.w/verVertex.w;}public static M4 frustum(float left, float right, float bottom, float top,            float near, float far){float[][]  matrix = new float[4][4];       if (left == right) {            throw new IllegalArgumentException("left == right");        }        if (top == bottom) {            throw new IllegalArgumentException("top == bottom");        }        if (near == far) {            throw new IllegalArgumentException("near == far");        }        if (near <= 0.0f) {            throw new IllegalArgumentException("near <= 0.0f");        }        if (far <= 0.0f) {            throw new IllegalArgumentException("far <= 0.0f");        }        final float r_width  = 1.0f / (right - left);        final float r_height = 1.0f / (top - bottom);        final float r_depth  = 1.0f / (near - far);        final float x = mul2f(near/(right - left));//00        final float y = mul2f(near * r_height);//11        final float A = (right + left) * r_width;//02        final float B = (top + bottom) * r_height;//12        final float C = (far + near) * r_depth;//22        final float D =  mul2f(far * near * r_depth);//23        matrix[0][0] = x;matrix[0][1] = 0.0f;matrix[0][2] = A;matrix[0][3] = 0.0f;         matrix[1][0] = 0.0f;matrix[1][1] = y; matrix[1][2] = B;  matrix[1][3] = 0.0f;        matrix[2][0] = 0.0f; matrix[2][1] = 0.0f;  matrix[2][2] = C; matrix[2][3] = D;         matrix[3][0] = 0.0f;matrix[3][2] = -1.0f; matrix[3][1] = 0.0f; matrix[3][3] = 0.0f;        M4 m4 = new M4();        m4.m = matrix;        return m4;       }public static int toFixed(float x) {return Float.floatToIntBits(x);}public static float toFloatBytes(int fx){return Float.intBitsToFloat(fx);}static Float addExpf(Float v, int e) {    int i = toFixed(v);    if (i<<1 != 0) {      i += (e)<<23;    }    return toFloatBytes(i);}static Float minusExpf(Float v, int e) {    int i = toFixed(v);    if (i<<1 != 0) {      i -= (e)<<23;    }    return toFloatBytes(i);}static float mul2f(float v) {    return addExpf(v, 1);}static float mul2fn(float v, int n) {    return addExpf(v, n);}static float divide2fn(float v, int n) {    return minusExpf(v, n);}public M4 multiply(M4 other) {M4 result = new M4();float[][] m1 = m;float[][] m2 = other.m;for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {result.m[i][j] = m1[i][0]*m2[0][j] + m1[i][1]*m2[1][j] + m1[i][2]*m2[2][j] + m1[i][3]*m2[3][j];}}return result;}public void setIdentity() {for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {m[i][j] = (i == j ? 1f : 0f);}}}public void setIntArray(int[] src){float[][] dst = new float[4][4];int i = 0, m, n;for(n = 0; n < dst[0].length; ++ n){for(m = 0; m < dst.length ; ++ m){dst[m][n] = Int2Float(src[i ++]);}}this.m = dst;}public float Int2Float(int fx){return divide2fn((float)fx, 16);}@Overridepublic String toString() {StringBuilder builder = new StringBuilder("[ ");for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {builder.append(m[i][j]);builder.append(" ");}builder.append("\n  ");}builder.append(" ]");return builder.toString();}@Overridepublic boolean equals(Object o) {//float[][] otherM = ((M4)o).m;Log.e("---", "wsgl: " + this.toString());Log.e("---", "systm gl: " + o.toString());return o.toString().equals(this.toString());}    public static void translateM(    float[][] m, float x, float y, float z) {        for (int i=0 ; i<4 ; i++) {            int mi = i;            m[mi][3] += m[mi][0] * x + m[mi][1] * y + m[mi][2] * z;        }    }}

 然后,定义几个变量用来保存:

    

    public static Stack<M4> mModelViewMatrixStack = new Stack<M4>();    public static Stack<M4> mProjectionMatrixStack = new Stack<M4>();    public static M4 mCurrentModelViewMatrix = new M4();    public static M4 mCurrentProjectionMatrix = new M4();    public static M4 mCurrentViewPortMatrix = new M4();    public static int  mMatrixMode = GL10.GL_MODELVIEW;

2. 颜色管理

  

/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.example.simulateopengl;public class GLColor {    public  int red;    public  int green;    public  int blue;    public  int alpha;    public GLColor(int red, int green, int blue, int alpha) {        this.red = red;        this.green = green;        this.blue = blue;        this.alpha = alpha;    }    public GLColor(int red, int green, int blue) {        this.red = red;        this.green = green;        this.blue = blue;        this.alpha = 0x10000;    }    @Override    public boolean equals(Object other) {        if (other instanceof GLColor) {            GLColor color = (GLColor)other;            return (red == color.red &&                    green == color.green &&                    blue == color.blue &&                    alpha == color.alpha);        }        return false;    }}
   public static  GLColor mVertexColor = new GLColor(0, 0, 0);

 3.  绘制管理。我们这里只按照三角形绘制:

  

/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.example.simulateopengl;import java.nio.IntBuffer;public class GLVertex {    public double x;    public double y;    public double z;    public double w = 1.0f;    public short index; // index in vertex table    GLColor color;    GLVertex() {        this.x = 0;        this.y = 0;        this.z = 0;        this.w = 1.0f;                this.index = -1;    }    GLVertex(double x, double y, double z, double w) {        this.x = x;        this.y = y;        this.z = z;        this.w = w;    }    @Override    public boolean equals(Object other) {        if (other instanceof GLVertex) {            GLVertex v = (GLVertex)other;            return (x == v.x && y == v.y && z == v.z);        }        return false;    }//    static public int toFixed(float x) {//        return (int)(x * 65536.0f);//    }//    public void put(IntBuffer vertexBuffer, IntBuffer colorBuffer) {//        vertexBuffer.put(toFixed(x));//        vertexBuffer.put(toFixed(y));//        vertexBuffer.put(toFixed(z));//        if (color == null) {//            colorBuffer.put(0);//            colorBuffer.put(0);//            colorBuffer.put(0);//            colorBuffer.put(0);//        } else {//            colorBuffer.put(color.red);//            colorBuffer.put(color.green);//            colorBuffer.put(color.blue);//            colorBuffer.put(color.alpha);//        }//    }////    public void update(IntBuffer vertexBuffer, M4 transform) {//        // skip to location of vertex in mVertex buffer//        vertexBuffer.position(index * 3);////        if (transform == null) {//            vertexBuffer.put(toFixed(x));//            vertexBuffer.put(toFixed(y));//            vertexBuffer.put(toFixed(z));//        } else {//            GLVertex temp = new GLVertex();//            transform.project(this, temp);//            vertexBuffer.put(toFixed(temp.x));//            vertexBuffer.put(toFixed(temp.y));//            vertexBuffer.put(toFixed(temp.z));//        }//    }}

 定义个变量来保存顶点:

public static ArrayList<GLVertex> mVertexList = new ArrayList<GLVertex>();

 好了,打工告成。

这就是实现一个地球,月亮,太阳模型的所有的东西都在这里。

总之,非常简单。后续博客将拿这8个变量来实现地球,月亮,太阳模型。

 

密码管理请下载:

http://a.app.qq.com/o/simple.jsp?pkgname=com.wa505.kf.epassword

 

原创粉丝点击