自己動手實現OpenGL-OpenGL原來如此簡單(三)
上一篇自己動手寫opengl 由於時間原因停止了更新,現在繼續。
1. 首先我們定義以下變數
public static class DisplayInfo{
Canvas canvas;
int height;
int width;
}
private static DisplayInfo mInfo;
public static void initDrawEnvirement(DisplayInfo info){
mInfo = info;
}
public enum MatrixMode{
MODE_MODEL_VIEW,
MODE_PROJECTION
}
//for testing
public static M4 mCurrentSurfaceViewProjectionMatrix = null;
public static M4 mCurrentSurfaceViewModelViewMatrix = null;
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 MatrixMode mMatrixMode = MatrixMode.MODE_MODEL_VIEW;
public static float mViewPortZNear = 0.0f;
public static float mViewPortZFar = 1.0f;
public static GLColor mVertexColor = new GLColor(0, 0, 0);
public static ArrayList<GLVertex> mVertexList = new ArrayList<GLVertex>;
從上面可以看到我們的變數基本上有以下幾個
1. ModelView matrix
2.Project matrix
3.Viewport matrix
這幾個矩陣就構成了把一個3D空間的(x,y,z)轉換為2D空間的所有的東西。下面看看他們如何實現他們,與矩陣相關的幾個函數如下:
矩陣模式 public static void glMatrixMode(MatrixMode mode){
mMatrixMode = mode;
}
矩陣指定
glLoadIdentity
public static void glLoadIdentity{
if(mMatrixMode == MatrixMode.MODE_MODEL_VIEW){
mCurrentModelViewMatrix.setIdentity;
}else{
mCurrentProjectionMatrix.setIdentity;
}
}
矩陣保存
glPushMatrix
public static void glPushMatrix{
if(mMatrixMode == MatrixMode.MODE_MODEL_VIEW){
mModelViewMatrixStack.push(new M4(mCurrentModelViewMatrix));
}else{
mProjectionMatrixStack.push(new M4(mCurrentProjectionMatrix));
}
}
矩陣恢復
glPopMatrix
public static void glPopMatrix{
if(mMatrixMode == MatrixMode.MODE_MODEL_VIEW){
mCurrentModelViewMatrix = mModelViewMatrixStack.pop;
}else{
mCurrentProjectionMatrix = mProjectionMatrixStack.pop;
}
}
矩陣修改
glMultMatrix
public static void glMultMatrix(M4 m){
if(mMatrixMode == MatrixMode.MODE_MODEL_VIEW){
mCurrentModelViewMatrix.multiply(m);
}else{
mCurrentProjectionMatrix.multiply(m);
}
}
ViewPort矩陣指定
public static void glDepthRangef(
float zNear,
float zFar
){
mViewPortZNear = zNear;
mViewPortZFar = zFar;
}
public static void glViewport(
int x,
int y,
int width,
int height
)
{
int surfaceHeight = mInfo.height;
float far = mViewPortZFar;
float near = mViewPortZNear;
float sx = width/2.0f;
float ox = sx + x;
float sy = height/2.0f;
float oy = sy + surfaceHeight - height - y;
float A = (far - near)/2.0f;
float B = (far + near)/2.0f;
// compute viewport matrix
float f = new float[4][4];
f[0][0] = sx; f[0][1] = 0; f[0][2] = 0; f[0][3] = ox;
f[1][0] = 0; f[1][1] =-sy; f[1][2] = 0; f[1][3] = oy;
f[2][0] = 0; f[2][1] = 0; f[2][2] = A; f[2][3] = B;
f[3][0] = 0; f[3][1] = 0; f[3][2] = 0; f[3][3] = 1;
mCurrentViewPortMatrix = new M4;
mCurrentViewPortMatrix.m = f;
}
這下好了所有矩陣都有了,唯一的事情就是指定頂點和繪製方式了
2. 然後我們指定頂點
public static void glVertexPointer(
int size,
int type,
int stride,
java.nio.Buffer pointer)
{
if((type!= GL10.GL_FLOAT && type!= GL10.GL_FIXED) ||size != 3){
throw new RuntimeException("this lib only support GL_FLOAT GL_FIXED type and size must equals 3, stride must equals 0!");
}
mVertexList.clear;
int capacity = pointer.capacity;
pointer.position(0);
while(true){
if(capacity >= size){
capacity-=size;
GLVertex verTex = new GLVertex;
if(type == GL10.GL_FLOAT){
verTex.x= ((FloatBuffer)pointer).get;
verTex.y= ((FloatBuffer)pointer).get;
verTex.z= ((FloatBuffer)pointer).get;
}else if(type == GL10.GL_FIXED){
verTex.x= ((IntBuffer)pointer).get>>16;
verTex.y= ((IntBuffer)pointer).get>>16;
verTex.z= ((IntBuffer)pointer).get>>16;
}
mVertexList.add(verTex);
if(capacity >= stride){
capacity -= stride;
for(int i = 0; i < stride; ++i){
if(type == GL10.GL_FLOAT){
((FloatBuffer)pointer).get;
}else if(type == GL10.GL_FIXED){
((IntBuffer)pointer).get;
}
}
}else{
break;
}
}else{
break;
}
}
}
看上去是不是很簡單呢,接下就是繪製了
3. 最後我們繪製圖像
public static void glDrawElements(int mode, int mIndexCount,
int type, Buffer mIndexBuffer) {
if(mode!= GL10.GL_TRIANGLES){
throw new RuntimeException;
}
if((type!= GL10.GL_UNSIGNED_SHORT&&type!=GL10.GL_UNSIGNED_BYTE) || mode != GL10.GL_TRIANGLES){
throw new RuntimeException("this lib glDrawElements only support GL_TRIANGLES and GL_UNSIGNED_SHORT !");
}
mIndexBuffer.position(0);
ArrayList<GLVertex> drawingList = preDealVertex;
//clearColor;
int capacity = mIndexCount;
while(true){
if(capacity >= 3){
if(type == GL10.GL_UNSIGNED_SHORT){
capacity-=3;
ShortBuffer buffer = ((ShortBuffer)mIndexBuffer);
GLVertex v1 = drawingList.get(buffer.get);
GLVertex v2 = drawingList.get(buffer.get);
GLVertex v3 = drawingList.get(buffer.get);
drawTriangles(v1,v2,v3);
}else if(type == GL10.GL_UNSIGNED_BYTE){
capacity-=3;
ByteBuffer buffer = ((ByteBuffer)mIndexBuffer);
GLVertex v1 = drawingList.get(buffer.get);
GLVertex v2 = drawingList.get(buffer.get);
GLVertex v3 = drawingList.get(buffer.get);
drawTriangles(v1,v2,v3);
}
}else{
break;
}
}
}
如果需要源代碼,請下載此軟體到手機上。
※thinkphp實現無限級分類
※Security5:授予許可權
※spring boot 項目筆記2一自定義配置文件的讀取
※Linux常用命令——顯示文件列表
TAG:達人科技 |
※CentOS+OpenVZ+Vtonf實現Linux虛擬化
※Github 項目推薦 用PyTorch 實現 OpenNMT
※用Numpy 實現簡單的 GAN
※AspectJ 框架 spring 實現 AOP?
※TU Ilmenau提出新型Complex-YOLO,實現點雲上實時3D目標檢測
※「CVPR Oral」TensorFlow實現StarGAN代碼全部開源,1天訓練完
※LVS/DR+keepalived負載均衡實現
※GAN的Keras 實現案例集合——Keras-GAN
※與AMD合作,Premiere原生支持Radeon Pro SSG,實現更高效視頻製作
※ArrayList,LinkedList,Vector基本原理與實現
※YOLOv3 的最小化 PyTorch 實現
※CentOS下實現iptables持久化
※SpaceTime Enterprises 用VR實現你的太空夢
※用PaddlePaddle和Tensorflow實現GoogLeNet InceptionV2/V3/V4
※語義分割網路DeepLab-v3的架構設計思想和TensorFlow實現
※淺入淺出TensorFlow 6—實現AlexNet和VGG等經典網路
※Apple 蘋果 iPhone X 真正實現雙卡雙待的神器—IKOS 三代蘋果皮
※利用谷歌object detection API實現Oxford-IIIT Pets Dataset 目標檢測趟坑記錄
※使用Tensorflow Object Detection API實現對象檢測
※使用Python實現一個簡易Http伺服器