2013-07-27 3 views
6

Я пытаюсь отобразить куб с 6 растровыми изображениями, чтобы добиться эффекта skybox. Моя проблема заключается в том, что одна текстура отображается на каждую грань куба. Я проверил в gDEBugger, в памяти кубической текстуры у меня есть только одно изображение (поскольку я пытаюсь загрузить шесть изображений).Отображение куба в OpenGL

Код подготовки текстуры:

bool Texture::LoadCubicTexture(vector<string> filenameTable) 
{ 
    glGenTextures(1,&texID); 
    glBindTexture(GL_TEXTURE_CUBE_MAP,texID); 

    glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_WRAP_R,GL_CLAMP_TO_EDGE); 

    int i = 0; 
    vector<string>::iterator vsit; 

    // There is always six filenames 
    for(vsit=filenameTable.begin();vsit!=filenameTable.end();++vsit) 
    { 
    string filename = *vsit; 
    BMPData* bmpData = LoadTextureBMPData_custom(filename); 
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i,0,GL_RGB,bmpData->width,bmpData->height,0,GL_BGR,GL_UNSIGNED_BYTE,&(bmpData->data[0])); 
    i++; 
    delete daneObrazu; 
    } 
    glGenerateMipmap(GL_TEXTURE_CUBE_MAP); 

    return true; 
} 

VS:

#version 330 core 

in vec3 vVertexPos; 
in vec3 vertexUV; 

out vec3 vCoords; 
uniform mat4 MVP; 

void main() 
{ 
    vCoords = normalize(vertexUV); 
    gl_Position = MVP * vec4(vVertexPos,1.0); 
} 

FS:

#version 330 core 

in vec3 vCoords; 
uniform samplerCube cube; 

out vec4 vFragColor; 

void main() 
{ 
    vFragColor = texture(cube, vCoords); 
} 

OBJ файла:

# Blender v2.62 (sub 0) OBJ File: 'skybox.blend' 
# www.blender.org 
mtllib skybox.mtl 
o Cube 
v 10.487665 -10.487666 -10.487665 
v 10.487665 -10.487666 10.487665 
v -10.487667 -10.487666 10.487664 
v -10.487662 -10.487666 -10.487670 
v 10.487671 10.487666 -10.487660 
v 10.487659 10.487666 10.487673 
v -10.487670 10.487666 10.487662 
v -10.487665 10.487666 -10.487666 
vt 0.990480 0.014286 
vt 0.993478 0.991259 
vt 0.016505 0.994256 
vt 0.013507 0.017283 
vt 0.988479 0.008111 
vt 0.985457 0.993412 
vt 0.000157 0.990390 
vt 0.003179 0.005089 
vt 0.002693 1.001082 
vt -0.000347 0.009939 
vt 0.990796 0.006898 
vt 0.993837 0.998041 
vt 0.004581 0.999210 
vt 0.001535 0.006444 
vt 0.994302 0.003398 
vt 0.997347 0.996165 
vt 0.004172 -0.000587 
vt 0.996320 -0.003630 
vt 0.999364 0.988517 
vt 0.007216 0.991561 
vt 0.000632 0.000140 
vt 0.983846 -0.002921 
vt 0.986862 0.995017 
vt 0.003648 0.998078 
vn 0.000000 -1.000000 0.000000 
vn 0.000000 1.000000 0.000000 
vn 1.000000 0.000000 0.000000 
vn -0.000000 -0.000000 1.000000 
vn -1.000000 -0.000000 -0.000000 
vn 0.000000 0.000000 -1.000000 
usemtl Skybox 
s off 
f 1/1/1 2/2/1 3/3/1 
f 1/1/1 3/3/1 4/4/1 
f 5/5/2 8/6/2 7/7/2 
f 5/5/2 7/7/2 6/8/2 
f 1/9/3 5/10/3 6/11/3 
f 1/9/3 6/11/3 2/12/3 
f 2/13/4 6/14/4 7/15/4 
f 2/13/4 7/15/4 3/16/4 
f 3/17/5 7/18/5 8/19/5 
f 3/17/5 8/19/5 4/20/5 
f 5/21/6 1/22/6 4/23/6 
f 5/21/6 4/23/6 8/24/6 


Мои вопросы:

  • Существуют методы, которые я использую в этом коде выглядит нормально?
  • Как текстуры сопоставляются для куба (в текстуре GL_TEXTURE_CUBE_MAP), , когда есть только 2 UV? (Я имею в виду в целом.)
  • Могу ли я использовать автоматическую генерацию УФ-излучения в этой ситуации (есть ли у меня , чтобы сделать много изменений в шейдере)?
  • Может ли кто-нибудь предложить мне, где я могу найти проблему? (с некоторой вероятностью , буферы, шейдеры, сетки, только предложение)?

[Изменить]: Я пытался жёстко вершины и Увс в отдельном исходном файле и у меня есть один и тот же проблемно одну текстуру для всех граней куба. Запрограммированные данные кажется правильным:

#include "TestCube.h" 

vector<vec3> GetTestCubeVertices() 
{ 
    vector<vec3> vrtx; 

    const float xd = 1.0f; 
    const float yd = 1.0f; 
    const float zd = 1.0f; 

    const float testCubeVertices[] = 
    { 
    -xd, -yd, zd, xd, -yd, zd, -xd, yd, zd, // ABE 
    xd, -yd, zd, -xd, yd, zd, xd, yd, zd, // BEF 
    xd, -yd, zd, xd, -yd, -zd, xd, yd, zd, // BCF 
    xd, -yd, -zd, xd, yd, zd, xd, yd, -zd, // CFG 
    xd, -yd, -zd, -xd, -yd, -zd, xd, yd, -zd, // CDG 
    -xd, -yd, -zd, xd, yd, -zd, -xd, yd, -zd, // DGH 
    -xd, -yd, -zd, -xd, -yd, zd, -xd, yd, -zd, // DAH 
    -xd, -yd, zd, -xd, yd, -zd, -xd, yd, zd, // AHE 
    -xd, yd, zd, xd, yd, zd, -xd, yd, -zd, // EFH 
    xd, yd, zd, -xd, yd, -zd, xd, yd, -zd, // FHG 
    xd, -yd, zd, -xd, -yd, zd, xd, -yd, -zd, // BAC 
    -xd, -yd, zd, xd, -yd, -zd, -xd, -yd, -zd, // ACD 
    }; 

    for(int i=0;i<108;i=i+3) 
    vrtx.push_back(vec3(testCubeVertices[i],testCubeVertices[i+1],testCubeVertices[i+2])); 

    return vrtx; 
} 

vector<vec2> GetTestCubeUVs() 
{ 
    vector<vec2> uv; 

    const float testCubeUV[] = 
    { 
    0,0, 1,0, 0,1, // ABE 
    1,0, 0,1, 1,1, // BEF 
    0,0, 1,0, 0,1, // BCF 
    1,0, 0,1, 1,1, // CFG 
    0,0, 1,0, 0,1, // CDG 
    1,0, 0,1, 1,1, // DGH 
    0,0, 1,0, 0,1, // DAH 
    1,0, 0,1, 1,1, // AHE 
    0,0, 1,0, 0,1, // EFH 
    1,0, 0,1, 1,1, // FHG 
    0,0, 1,0, 0,1, // BAC 
    1,0, 0,1, 1,1, // ACD 
    }; 

    for(int i=0;i<72;i=i+2) 
    uv.push_back(vec2(testCubeUV[i],testCubeUV[i+1])); 

    return uv; 
} 

Еще два suplementary вопросов, у меня есть OpenGL вызова:

glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_WRAP_R,GL_CLAMP_TO_EDGE); 
  • Я понимаю, что OpenGL обрабатывает г координаты автоматически, поскольку имеет информацию константа GL_TEXTURE_CUBE_MAP_POSITIVE_X для glTexImage2D()?
  • Необходима ли какая-либо модификация r Координата в Vertex Shader?

Там же результат ниже экран (инвалиды письменной формы в буфер глубины и не ставил scalling, но это не моя проблема сейчас):

enter image description here

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

enter image description here

[Последнее редактирование]: Был проблема с УФ-координаты в Skybox VS (г координат имеет одно значение), Skybox VS должно быть, как показано ниже:

void main() 
{ 
    vCoords = normalize(vVertexPos); 
    gl_Position = MVP * vec4(vVertexPos,1.0); 
} 

Там в несколько проблем с технологией Skybox, но они не были темой этого потока. Решаемые.

+0

Что произойдет, если вы не используете .obj модель и вместо того, чтобы создать 6 квадрациклов в коде? –

+0

Я жестко закодированные вершины и uvs в отдельном заголовке, и есть та же проблема. – CppMonster

ответ

5

Карты куба текстуры отображаются с использованием трехмерной текстурной координаты: она используется для определения того, какой кусок лица фактически выбран, а затем получить фактическую координату текстуры 2D, используемую для доступа к текстуру лица карты куба.

Ваши координаты текстуры являются 2D (неправильно), и на самом деле вы текстурные координаты vertexUV (и, следовательно, vCoords) Z координата всегда 0, отображение не-окончательно текстуры (недостающие компоненты копируются значения атрибута по умолчанию, то есть vec4 (0,0,0,1)).

Чтобы получить нужный результат, изменить вершинный шейдер для того, чтобы использовать meaninful координат:

vCoords = normalize(vVertexPos); 
+0

Это правда, я использую UVs в начале, и я конвертирую его в UV. Хорошо, я предполагаю, что мне нужно использовать UVs от beggining. Итак, откуда я беру 3-ю координацию на УФ-таблицу? – CppMonster

+1

См. Приведенный выше код, давая одно решение: из вершинной позиции (правильно нормированная). Куб должен иметь барицентр в (0,0,0). В этом состоянии вы можете вычислить его непосредственно в вершинном шейдере. – Luca

+0

Я понимаю, что вы имеете в виду какое-то правило, которому я должен следовать (не эта строка кода). Когда я пишу эту строку в шейдер, я нарушаю связь с потоком текстурных координат (так что в основном мне не нужны VBO UVs). Я попытался изменить эту строку, в результате получается один квадрат с текстурой (я использовал барицентрированный куб с приведенными выше угловыми вершинами). – CppMonster