簡體   English   中英

android OpenGL ES坐標映射

[英]android OpenGL ES coordinates mapping

我進行了大量搜索,但沒有任何解決方案。 我對android和3d編程都是新手。 我正在開發一個Android項目,該項目需要使用opengl es在android設備上繪制3d對象。 對於每個像素,我的距離值介於200和9000之間,需要將其映射為Z坐標。 對象是320x240。

問題是:

  • 如何從(x,y,z)映射到OpenGL ES坐標系? 我創建了一個頂點數組,其值為{50f,50f,400f,50f,51f,290f,...}。 每個像素表示為3個浮點數(x,y,z)。
  • 如何在Android上使用opengl繪制此頂點數組?
  • 使用OpenGl ES可以繪制320 * 240像素嗎?

OpenGL不能很好地處理大量數字(就像10.0f以上的任何東西一樣,只是它的設計方式)。 最好將您的坐標轉換為-1和1(即歸一化),而不是嘗試使openGL使用50f或290f坐標。

坐標歸一化為-1和1之間的原因是因為模型坐標僅被認為是彼此相對的,並不表示它們在特定游戲/應用中的實際尺寸。 該模型可以用於具有不同坐標系的許多不同游戲/應用程序中,因此您希望所有模型坐標都采用某種標准化的標准格式,以便程序員可以按照自己的方式進行解釋。

為了規范化,您遍歷所有坐標並找到距離0最遠的值,即

float maxValueX = 0;
float maxValueY = 0;
float maxValueZ = 0;

// find the max value of x, y and z
for(int i=0;i<coordinates.length'i++){
    maxValueX = Math.max(Math.abs(coordinates[i].getX()), maxValueX);
    maxValueY = Math.max(Math.abs(coordinates[i].getY()), maxValueY);
    maxValueZ = Math.max(Math.abs(coordinates[i].getZ()), maxValueZ);
}

// convert all the coordinates to be between -1 and 1
for(int i=0;i<coordinates.length'i++){
    Vector3f coordinate = coordinates[i];
    coordinate.setX(coordinate.getX() / maxValueX);
    coordinate.setY(coordinate.getY() / maxValueY);
    coordinate.setZ(coordinate.getZ() / maxValueZ);
}    

您只需要這樣做一次。 假設您將數據存儲在文件中,則可以編寫一個小的實用程序,將上述操作存儲到文件中並保存,而不必每次將數據加載到應用程序中時都執行

除了詹姆斯提到的關於標准化為[-1,1]的內容。 一點代碼:

假設您正在使用類似於以下內容的頂點着色器,則將數據按x,y,z填充到平面數組中:

 "attribute vec3 coord3d;" +
    "uniform mat4 transform;" +
    "void main(void) {" +
    "  gl_Position = transform * vec4(coord3d.xyz, 1.0f);" + // size of 3 with a=1.0f for all points
    "  gl_PointSize = 10.0;"+
    "}"

獲取屬性:

attribute_coord3d = glGetAttribLocation(program, "coord3d");

創建VBO:

glGenBuffers(1, vbo,0);

綁定

glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);

將數據放入:

glBufferData(GL_ARRAY_BUFFER, size:SIZE_OF_ARRAY, makeFloatBuffer(FlatArray), GL_STATIC_DRAW);

其中makeFloatBuffer是創建緩沖區的函數:

  private FloatBuffer makeFloatBuffer(float[] arr) {
                ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
                bb.order(ByteOrder.nativeOrder());
                FloatBuffer fb = bb.asFloatBuffer();
                fb.put(arr);
                fb.position(0);
                return fb;
            }

綁定並指向緩沖區:

    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glEnableVertexAttribArray(attribute_coord3d);
    glVertexAttribPointer(attribute_coord3d, 
    size:3,GL_FLOAT,false,stride:vertexStride, 0);

其中vertexStride = num_components*Float.BYTES; 在我們的例子中num_components = 3 // x,y,z.

畫:

glDrawArrays(GL_POINTS, 0, NUM_OF_POINTS);

禁用VBO:

glDisableVertexAttribArray(attribute_coord2d);

在Android SDK隨附的APIDemos中檢出GLSurfaceView活動。 這將為您提供有關Android如何通過OpenGL ES處理渲染的基礎入門。 這位於android-sdk / samples / android-10 / ApiDemos中。 確保已下載給定API級別下的“ SDK樣本”。

以下還有一些資源可幫助您入門:

GLSurfaceView上的Android開發博客

OpenGLES上的說明

OpenGL上的Android開發文檔

希望能有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM