Отображение неправильных форм или других многоугольников (мультфильмы, спрайты) в треугольники в OpenGL ES - PullRequest
4 голосов
/ 16 мая 2010

Я не понимаю концепции показа спрайтов, сопоставленных с треугольниками OpenGL.

Если OpenGL ES рисует только треугольники и точки, как отображать / отображать нетреугольные фигуры?

Почему форма, сопоставленная с треугольником, не будет искажена?

Объяснить:

По-моему, отображение, скажем, спрайта Марио на треугольник привело бы к искаженному или обрезанному Марио. В таком случае голова будет раздавлена ​​или невидима.

Ответы [ 5 ]

6 голосов
/ 28 мая 2010

Если я правильно понял проблему: вы просто делите квадрат на два треугольника и используете координаты текстуры, чтобы соответственно разделить текстуру. Если вы все сделаете правильно, вы получите текстуру, нарисованную на экране 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 сопоставлены надлежащим образом), вы получите только вырезанную часть спрайта.

(Тем не менее, вы можете назначить одну и ту же текстовую строку двум точкам, или сделать текстуру пересекающей себя, и таким образом ошибиться - все еще есть много возможностей для создания беспорядка, не волнуйтесь. )

Это объясняется в руководстве по программированию OpenGL, хотя прошло много лет с тех пор, как я изучил этот материал, поэтому я не уверен, насколько он будет полезен, если у вас возникнут трудности: http://glprogramming.com/red/chapter09.html

4 голосов
/ 03 июня 2010

Проще говоря, текстура не будет искажена, потому что вы будете выбирать только три координаты текстуры - по одной на вершину. Вам нужно будет использовать два треугольника, как описано выше, и «обрезать» различные части текстуры.

Прошу прощения за мое ужасное использование искусства ASCII здесь и в остальной части этого поста:

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

Вы бы сделали два треугольника - ADB и ACD. Точка A отображается в верхнем левом углу текстуры, B - в нижнем левом, C - в верхнем правом и D - в нижнем правом. Если вы отображаете только один треугольник или другой, вы получаете только половину спрайта (или текстуры, для более сложной формы). То же самое относится к большим или более сложным полигонам. Текстура может быть единым фрагментом, но координаты текстуры каждой вершины должны разрезать ее так же, как и сама геометрия.

Более сложный пример, шестиугольник:

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

Если вы добавите среднюю точку «G» и нарежете ее на шесть треугольников (ABG, BCG, CDG и т. Д.), Вам нужно будет убедиться, что любая используемая вами текстура разрезана по координатам матч. Это не имеет значения, если вы просто используете GL_TRIANGLES, так как проще всего оставить текстуру в ее шестиугольной форме, но как только вы начнете рисовать полосы или вееры, вы можете переворачивать, наклонять или дублировать, если вы не сохраните из-за порядка прорисовки закрыть трек того, какая вершина отображается в какой части текстуры.

В качестве отступления, если вы просто заинтересованы в двухмерных квадратах с выравниванием по экрану, для чего обычно нужны спрайты, используйте расширение OES_Draw_Texture , доступное на iPhone, и избавьте себя от душевной боли, пока набирает значительный прирост скорости.

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.

Боже, даже здесь я чувствую "д-р". Я прошу прощения за это.

3 голосов
/ 28 мая 2010

Причина в том, что конвейер рендеринга находится на самом низком уровне, это все треугольники. Более сложные формы, такие как многоугольники и тому подобное, превращаются в набор треугольников с помощью процесса, называемого тесселяцией.

Так что, если вы хотите смоделировать своего сложного персонажа Марио, на самом деле хитрость состоит в том, чтобы превратить его в набор треугольников, а не в один.

Я вижу в другом ответе вы упомянули прозрачные пиксели. Я не использовал новейшие версии openGL, но традиционное определение столкновения основано на пересечении поверхности, и текстура, даже прозрачная, не была принята во внимание.

EDIT:

Быстрый Google нашел решение, используя GL_TRIANGLE_STRIP с iDevGames.com. URL-адрес 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];
}
0 голосов
/ 17 мая 2010

openGL может рисовать полигоны, но обычно безопаснее их не использовать, особенно в сложных формах. Полигоны могут «крутиться» на себе и создавать неправильную форму, которая не может быть правильно отображена. С треугольниками такого никогда не бывает. Вот почему люди обычно разбивают сложные фигуры на треугольники.

См. http://www.glprogramming.com/red/chapter02.html#name2 для лучшего, более полного объяснения.

0 голосов
/ 16 мая 2010

Вы можете использовать прозрачные пиксели.

Как загрузить текстуру с прозрачными пикселями в OpenGL ES?

...