當前位置:
首頁 > 知識 > 自己動手實現OpenGL-OpenGL原來如此簡單(三)

自己動手實現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伺服器