Как реализовать повторное наложение текстур по координатам по миру в OpenGL? - PullRequest
1 голос
/ 26 августа 2011

Когда вы создаете кисть в редакторе трехмерных карт, таком как Valve's Hammer Editor, текстуры объекта по умолчанию повторяются и выравниваются по мировым координатам.

Как реализовать эту функцию, используяOpenGL?

Можно ли использовать glTexGen для достижения этой цели?

Или я должен как-то использовать матрицу текстур?

Если я создаю блок 3х3, то это легко: установить для GL_TEXTURE_WRAP_T значение GL_REPEAT Установить для текстурных координат 3,3 по краям.

Но если объект не выровнен по оси, выпуклая оболочка получает немногосложный.

В основном я хочу создать функциональность листа редактирования лица из Valve Hammer:

Valve Hammer Face Edit tool

1 Ответ

2 голосов
/ 26 августа 2011

Технически для этого вы можете использовать генерацию координат текстуры. Но я рекомендую использовать вершинный шейдер, который генерирует координаты текстуры из преобразованных координат вершин. Будь более конкретным (я не очень хорошо знаю Хаммера).


После просмотра видео я понимаю ваше замешательство. Я думаю, вы должны знать, что Hammer / Source, вероятно, не имеют API рисования, генерирующего текстурные координаты, но производят их внутри.

Итак, вы можете видеть, что есть текстуры, которые проецируются на плоскость X, Y или Z, в зависимости от того, в каком основном направлении указывает грань. Затем он использует локальные координаты вершины в качестве координат текстуры.

Это можно реализовать в коде, загружающем модель в объект буфера вершин (более эффективный, так как вычисления выполняются только один раз), или в вершинном шейдере GLSL. Я дам вам псевдокод:

cross(v1, v2):
    return { x = v1.y * v2.z - v1.z * v2.y,
             y = v2.x * v1.z - v2.z * v1.x, // <- "swapped" order!
             z = v1.x * v2.y - v1.y * v2.x }

normal(face): 
    return cross(face.position[1] - face.position[0], face.position[2] - face.position[0])

foreach face in geometry:
    n = normal(face) // you'd normally precompute the normals and store them
    if abs(n.x) > max(abs(n.y), abs(n.z)): // X major axis, project to YZ plane
        foreach (i, pos) in enumerate(face.position):
             face.texcoord[i] = { s = pos.y, t = pos.z }

    if abs(n.y) > max(abs(n.x), abs(n.z)): // Y major axis, project to XZ plane
        foreach (i, pos) in enumerate(face.position):
             face.texcoord[i] = { s = pos.x, t = pos.z }

    if abs(n.z) > max(abs(n.y), abs(n.x)): // Z major axis, project to XY plane
        foreach (i, pos) in enumerate(face.position):
             face.texcoord[i] = { s = pos.x, t = pos.y }

Чтобы это работало с генерацией координат текстуры glTexGen, вам нужно разделить ваши модели на части каждой большой оси. Что делает glTexGen - это просто шаг отображения face.texcoord[i] = { s = pos.<>, t = pos.<> }. В вершинном шейдере вы можете делать ветвление напрямую.

...