簡體   English   中英

在OpenGL ES中將不規則形狀或其他多邊形(漫畫,精靈)映射到三角形

[英]Mapping irregular shapes or other polygons (cartoons, sprites) to triangles in OpenGL ES

我不明白顯示精靈映射到OpenGL三角形的概念。

如果OpenGL ES只繪制三角形和點,那么如何顯示/繪制非三角形?

為什么映射到三角形的形狀不會失真?

解釋:

在我看來,將一個馬里奧的精靈映射到一個三角形會產生一個扭曲或裁剪的馬里奧。 在這種情況下,頭部會被擠壓或看不見。

如果我正確理解了這個問題:你只需將方塊分成兩個三角形,然后使用紋理坐標相應地划分紋理。 如果你做得對,你就會在屏幕上畫出1:1的紋理,好像它是一個精靈。 (當然你也可以選擇旋轉和伸展等等。)

0     1  <-- If your square is divided up like this, say, set texcoord
+-----+      for point 0 to be the top left of the sprite; for point 3, the
|\    |      bottom right of the sprite; and correspondingly, for points
| \   |      1 and 2.
|  \  |
|   \ |
|    \|
+-----+
2     3

事實證明,你不會像你期望的那樣得到一個壓扁的精靈。 我想你正在想象從我上面的圖片中繪制三角形0-3-2,比如說,以明顯的方式繪制,並將頂部掃描線無限擠壓到一個點(點0)? 但實際上這不會發生,因為點0只有一個紋理坐標,所以(如果第2和第3點被適當地映射),你將只得到精靈的截斷部分。

(也就是說,你可以將相同的texcoord分配給兩個點,或者讓紋理跨越自己,並以錯誤的方式弄錯 - 仍然有足夠的空間制造混亂,不要擔心。)

這可以在OpenGL編程指南中解釋,雖然我學習了這些東西已經多年了,所以我不確定如果你遇到困難會有多大幫助: http//glprogramming.com/red/chapter09.html

很簡單,紋理不會扭曲,因為你只需要挑選三個紋理坐標 - 每個頂點一個。 您將必須使用如上所述的兩個三角形,並“剪切”紋理的不同部分。

請原諒我在這里使用ASCII藝術,以及在這篇文章的其余部分:

  Polygon     Texture        ADB        ACD
  A-----C  |  x-----x  |  x        |  x-----x
  |\    |  |  | ___ |  |  |        |    ___ |
  | \   |  |  |<o.o>|  |  |<o      |     .o>|
  |  \  |  |  | ### |  |  | ##     |      # |
  |   \ |  |  | -|- |  |  | -|-    |        |
  |    \|  |  | / \ |  |  | / \    |        |
  B-----D  |  x-----x  |  x-----x  |        x

你會制作兩個三角形 - 亞行和ACD。 A點映射到紋理的左上角,B映射到左下角,C映射到右上角,D映射到右下角。 如果您只繪制一個三角形或另一個三角形,則只獲得精靈的一半(或紋理,對於更復雜的形狀。)同樣適用於更大或更復雜的多邊形。 紋理可以是單個統一的塊,但每個頂點的紋理坐標必須以與幾何體本身相同的方式將其切片。

更復雜的例子,一個六邊形:

   a   b
    ___
   /   \
f /  .  \ c
  \  g  /
   \___/
  e     d

如果你添加一個中間點“G”並將其切成六個三角形(ABG,BCG,CDG等),你必須確保你正在使用的任何紋理都是以坐標方式切片以匹配。 如果您只使用GL_TRIANGLES ,這GL_TRIANGLES ,因為最簡單的方法是將紋理保留為六邊形,但是一旦開始繪制條帶或扇形,如果不保持近距離跟蹤,則可以翻轉,傾斜或復制由於繪制順序,什么頂點映射到紋理的哪個部分。

順便說一句 ,如果你只關心2D屏幕對齊的四邊形 - 這是精靈通常用於 - 使用iPhone上提供的OES_Draw_Texture擴展,並在獲得顯着的速度提升時節省一大堆心痛。

int rect[4] = {0, 0, 64, 64}; 
glBindTexture(GL_TEXTURE_2D, texMario); 
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, rect); 
glDrawTexiOES(playerX, playerY, spriteZ, width, height); 

rect定義了你要剪出的紋理的坐標(以像素為單位,所以這將是一個64x64精靈)然后實際調用glDrawTexiOES將其直接放到屏幕視圖中,其左下角放在playerX上playerY。

天哪,即使我在這里感受到“tl; dr”的感覺。 我為此道歉。

原因是在最低級別的渲染管道中它是所有三角形。 諸如多邊形等更復雜的形狀通過稱為曲面細分的過程被轉換成三角形的集合。

因此,如果你想對復雜的馬里奧角色進行建模,那么訣竅就是讓他成為三角形的集合,而不是一個三角形。

我在另一個答案中看到你提到透明像素。 我沒有使用最新版本的openGL,但傳統的定義是碰撞是基於表面和紋理的交叉,即使是透明的,也沒有考慮到。

編輯:

快速谷歌使用了iDevGames.com的GL_TRIANGLE_STRIP找到了解決方案。網址是http://www.idevgames.com/forum/showpost.php?p=143983&postcount=6

這是相關的繪制方法:

- (void)drawView {

    // Replace the implementation of this method to do your own custom drawing

    const GLfloat squareVertices[] = {
        -0.5f, -0.5f,
        0.5f,  -0.5f,
        -0.5f,  0.5f,
        0.5f,   0.5f,
    };

    GLshort genericTexCoords[] = { 0, 1, 1, 1, 0, 0, 1, 0 };

    [EAGLContext setCurrentContext:context];

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glViewport(0, 0, backingWidth, backingHeight);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
    glMatrixMode(GL_MODELVIEW);
    glRotatef(3.0f, 0.0f, 0.0f, 1.0f);

    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glVertexPointer(2, GL_FLOAT, 0, squareVertices);
    glTexCoordPointer(2, GL_SHORT, 0, genericTexCoords);

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, sprite);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

openGL實際上可以繪制多邊形,但通常不使用它們更安全,特別是在復雜的形狀中。 多邊形可以“扭曲”自身並形成無法正確渲染的無效形狀。 對於三角形,這種情況從未發生 這就是人們通常將復雜形狀分解為三角形的原因。

有關更好,更完整的說明,請參見http://www.glprogramming.com/red/chapter02.html#name2

暫無
暫無

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

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