# 自己动手实现OpenGL-OpenGL原来如此简单（二）

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

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

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

1. 矩阵管理

2. 颜色管理

3. 绘制线框

1.矩阵管理

矩阵管理，那么就必须有矩阵，那么我的矩阵是这样的：

/*
* Copyright (C) 2008 The Android Open Source Project
*
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
*/

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();
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
M4 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;
}
}

static Float minusExpf(Float v, int e) {
int i = toFixed(v);
if (i<<1 != 0) {
i -= (e)<<23;
}
}

static float mul2f(float v) {
}

static float mul2fn(float v, int 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);
}

@Override
public 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();
}
@Override
public 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
*
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
*/

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
*
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
*/

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) {
//        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>();


好了，打工告成。