2014-05-10 3 views
0

간단한 CG 작업을하고 싶습니다. 6면에 텍스처가있는 skymap 큐브를 그립니다. 이미 튜토리얼을 많이 읽었지 만 텍스처에는 약간의 문제가 있습니다. 큐브의 6면은 모두 검은 색입니다 (그러나 조각 쉐이더에서 질감 (..)을 간단한 vec4 (1.0f, ...)로 바꾸면 벽이 색칠되어 무언가가 있어야합니다. 텍스처). 잘 작동OpenGL GL_TEXTURE_CUBE_MAP 질감 없음/검정

VertexBufferObjectAttribs* SkyCube::generateSkyCubeVBO(const vec3 &mi, const vec3 &ma) { 
    vector<vec3> vertices; 
    vector<vec3> normals; 
    vector<vec2> textureUV; 
    // tofo liste mit texture koords 
    // 00 01 
    // 10 11 
    // 2d vec 

    vertices.push_back(vec3(mi.x, ma.y, mi.z)); 
    vertices.push_back(vec3(mi.x, ma.y, ma.z)); 
    vertices.push_back(vec3(ma.x, ma.y, ma.z)); 
    vertices.push_back(vec3(ma.x, ma.y, mi.z)); 

    normals.push_back(vec3(0.0f, 1.0f, 0.0f)); 
    normals.push_back(vec3(0.0f, 1.0f, 0.0f)); 
    normals.push_back(vec3(0.0f, 1.0f, 0.0f)); 
    normals.push_back(vec3(0.0f, 1.0f, 0.0f)); 

    textureUV.push_back(vec2(0.0f, 0.0f)); 
    textureUV.push_back(vec2(0.0f, 1.0f)); 
    textureUV.push_back(vec2(1.0f, 0.0f)); 
    textureUV.push_back(vec2(1.0f, 1.0f)); 


    vertices.push_back(vec3(mi.x, mi.y, mi.z)); 
    vertices.push_back(vec3(ma.x, mi.y, mi.z)); 
    vertices.push_back(vec3(ma.x, mi.y, ma.z)); 
    vertices.push_back(vec3(mi.x, mi.y, ma.z)); 

    normals.push_back(vec3(0.0f, -1.0f, 0.0f)); 
    normals.push_back(vec3(0.0f, -1.0f, 0.0f)); 
    normals.push_back(vec3(0.0f, -1.0f, 0.0f)); 
    normals.push_back(vec3(0.0f, -1.0f, 0.0f)); 

    textureUV.push_back(vec2(0.0f, 0.0f)); 
    textureUV.push_back(vec2(0.0f, 1.0f)); 
    textureUV.push_back(vec2(1.0f, 0.0f)); 
    textureUV.push_back(vec2(1.0f, 1.0f)); 


    vertices.push_back(vec3(mi.x, mi.y, mi.z)); 
    vertices.push_back(vec3(mi.x, ma.y, mi.z)); 
    vertices.push_back(vec3(ma.x, ma.y, mi.z)); 
    vertices.push_back(vec3(ma.x, mi.y, mi.z)); 

    normals.push_back(vec3(0.0f, 0.0f, -1.0f)); 
    normals.push_back(vec3(0.0f, 0.0f, -1.0f)); 
    normals.push_back(vec3(0.0f, 0.0f, -1.0f)); 
    normals.push_back(vec3(0.0f, 0.0f, -1.0f)); 

    textureUV.push_back(vec2(0.0f, 0.0f)); 
    textureUV.push_back(vec2(0.0f, 1.0f)); 
    textureUV.push_back(vec2(1.0f, 0.0f)); 
    textureUV.push_back(vec2(1.0f, 1.0f)); 


    vertices.push_back(vec3(mi.x, mi.y, ma.z)); 
    vertices.push_back(vec3(ma.x, mi.y, ma.z)); 
    vertices.push_back(vec3(ma.x, ma.y, ma.z)); 
    vertices.push_back(vec3(mi.x, ma.y, ma.z)); 

    normals.push_back(vec3(0.0f, 0.0f, 1.0f)); 
    normals.push_back(vec3(0.0f, 0.0f, 1.0f)); 
    normals.push_back(vec3(0.0f, 0.0f, 1.0f)); 
    normals.push_back(vec3(0.0f, 0.0f, 1.0f)); 

    textureUV.push_back(vec2(0.0f, 0.0f)); 
    textureUV.push_back(vec2(0.0f, 1.0f)); 
    textureUV.push_back(vec2(1.0f, 0.0f)); 
    textureUV.push_back(vec2(1.0f, 1.0f)); 


    vertices.push_back(vec3(mi.x, mi.y, mi.z)); 
    vertices.push_back(vec3(mi.x, mi.y, ma.z)); 
    vertices.push_back(vec3(mi.x, ma.y, ma.z)); 
    vertices.push_back(vec3(mi.x, ma.y, mi.z)); 

    normals.push_back(vec3(-1.0f, 0.0f, 0.0f)); 
    normals.push_back(vec3(-1.0f, 0.0f, 0.0f)); 
    normals.push_back(vec3(-1.0f, 0.0f, 0.0f)); 
    normals.push_back(vec3(-1.0f, 0.0f, 0.0f)); 

    textureUV.push_back(vec2(0.0f, 0.0f)); 
    textureUV.push_back(vec2(0.0f, 1.0f)); 
    textureUV.push_back(vec2(1.0f, 0.0f)); 
    textureUV.push_back(vec2(1.0f, 1.0f)); 


    vertices.push_back(vec3(ma.x, mi.y, mi.z)); 
    vertices.push_back(vec3(ma.x, ma.y, mi.z)); 
    vertices.push_back(vec3(ma.x, ma.y, ma.z)); 
    vertices.push_back(vec3(ma.x, mi.y, ma.z)); 

    normals.push_back(vec3(1.0f, 0.0f, 0.0f)); 
    normals.push_back(vec3(1.0f, 0.0f, 0.0f)); 
    normals.push_back(vec3(1.0f, 0.0f, 0.0f)); 
    normals.push_back(vec3(1.0f, 0.0f, 0.0f)); 

    textureUV.push_back(vec2(0.0f, 0.0f)); 
    textureUV.push_back(vec2(0.0f, 1.0f)); 
    textureUV.push_back(vec2(1.0f, 0.0f)); 
    textureUV.push_back(vec2(1.0f, 1.0f)); 


    GLuint nrVertices = vertices.size(); 
    VertexBufferObjectAttribs::DATA *attrData = new VertexBufferObjectAttribs::DATA[nrVertices]; 

    for (GLuint i = 0; i < nrVertices; ++i) { 
     vec3 v = vertices[i]; 
     vec3 n = normals[i]; 
     vec2 t = textureUV[i]; 

     attrData[i].vx = v.x; 
     attrData[i].vy = v.y; 
     attrData[i].vz = v.z; 
     attrData[i].vw = 1.0f; 

     attrData[i].nx = n.x; 
     attrData[i].ny = n.y; 
     attrData[i].nz = n.z; 
     attrData[i].nw = 0.0f; 

     attrData[i].tx = t.x; 
     attrData[i].ty = t.y; 
     attrData[i].tz = 0.0f; 
     attrData[i].tw = 0.0f; 
    } 

    VertexBufferObjectAttribs *vbo = new VertexBufferObjectAttribs(); 
    vbo->setData(attrData, GL_STATIC_DRAW, nrVertices, GL_QUADS); 

    vbo->addAttrib(VERTEX_POSITION); 
    vbo->addAttrib(VERTEX_NORMAL); 
    vbo->addAttrib(VERTEX_COLOR); 
    vbo->addAttrib(VERTEX_TEXTURE); 
    vbo->bindAttribs(); 

    delete[] attrData; 

    return vbo; 
} 

는, 모든 텍스처는 다음과 같습니다

가 generateSkyCubeVBO 방법은 기본적으로 모든 정점과 질감 정규화 된 좌표를 생성
void SkyCube::init() { 
    mShader = new Shader("./Shader/skybox.vs", "./Shader/skybox.fs"); 

    // from: https://www.opengl.org/wiki/Common_Mistakes#Creating_a_Cubemap_Texture 

    glEnable(GL_TEXTURE_CUBE_MAP); 
    glGenTextures(1, &mTextureId); 
    glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureId); 
    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); 
    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_BASE_LEVEL, 0); 
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0); 

    // now load the textures from TGA files and make them available to OpenGL 
    TgaLoader * tgaLoader = new TgaLoader(); 
    string texturefilenames[] = {"back", "front", "bottom", "top", "left", "right"}; 
    int texturedefs[] = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 
     GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 
     GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z}; 
    for (int i = 0; i < 6; i++) { 
     tgaLoader->loadTga(mTextures[i], "data/skycube/" + texturefilenames[i] + ".tga"); 
     glTexImage2D(texturedefs[i], 0, GL_RGB, mTextures[i].width, mTextures[i].height, 
       0, GL_BGR, GL_UNSIGNED_BYTE, mTextures[i].imageData); 
    } 
    delete tgaLoader; 

    mVboSkyCube = this->generateSkyCubeVBO(vec3(-1.0f, -1.0f, -1.0f), vec3(1.0f, 1.0f, 1.0f)); 

    glDisable(GL_TEXTURE_CUBE_MAP); 
} 

:

그래서, 여기에 내가 뭘하는지의 발췌 성공적으로로드되었습니다. 정점 셰이더 :

프래그먼트 쉐이더
// OpenGL 3.3 
#version 130 

// following is probably not really needed 
#define VERT_POSITION 0 
#define VERT_NORMAL  1 
#define VERT_COLOR 2 
#define VERT_TEXTURE 3 

uniform mat4x4 matModel; 
uniform mat4x4 matView; 
uniform mat4x4 matProjection; 

attribute vec4 Position; 
attribute vec4 Normal; 
attribute vec4 Color; 
attribute vec4 Texture; 

out vec4 VertPosition; 
out vec4 VertNormal; 
out vec4 VertColor; 
out vec4 VertTexture; 

void main() 
{  
    VertPosition = Position; 
    VertNormal = Normal; 
    VertColor = Color; 
    VertTexture = Texture; 

    gl_Position = matProjection * matView * matModel * vec4(Position.xyz, 1); 
} 

:

// OpenGL 3.3 
#version 130 

in vec4 VertPosition; 
in vec4 VertNormal; 
in vec4 VertColor; 
in vec4 VertTexture; // Interpolated values from the vertex shaders, similar to the tutorial :-) 

uniform vec3 lightPos; 
uniform sampler2D skyBoxTextureSampler; // to know which texture to access, from the tutorial :-) 

void main() 
{ 
    vec4 color = VertColor; 
    gl_FragColor = texture(skyBoxTextureSampler, VertTexture.xy); //vec4(1.0f, 1.0f, 0.9f, 1.0f); // 
} 

있어서 렌더링 :

void VertexBufferObjectAttribs::render() { 
    GLint size = m_attribLocations.size(); 
    glBindBuffer(GL_ARRAY_BUFFER, m_bufferId); 
    for (GLint i = 0; i < size; ++i) { 
     GLint attribLoc = m_attribLocations[i]; 
     glVertexAttribPointer(attribLoc, 4, GL_FLOAT, GL_FALSE, sizeof (DATA), ((GLchar*) NULL + 4 * sizeof (GLfloat) * i)); 
    } 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    for (GLint i = 0; i < size; ++i) 
     glEnableVertexAttribArray(m_attribLocations[i]); 


    if (m_useIndexBuffer) { 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBufferId); 

     if (m_dynamicRendering) { 
      glDrawElements(m_primitiveMode, m_nrDynamicIndices, GL_UNSIGNED_INT, 0); 
     } else { 
      glDrawElements(m_primitiveMode, m_nrIndices, GL_UNSIGNED_INT, 0); 
     } 
    } else { 
     if (m_dynamicRendering) { 
      glDrawArrays(m_primitiveMode, 0, m_nrDynamicVertices); 
     } else { 
      glDrawArrays(m_primitiveMode, 0, m_nrVertices); 
     } 
    } 


    for (GLint i = 0; i < size; ++i) 
     glDisableVertexAttribArray(m_attribLocations[i]); 

} 
:

void SkyCube::render(const Transform& trans) { 
    mat4 projection = trans.projection; 
    mat4 view = trans.view; 
    mat4 model = mat4::identitiy(); 

    glPushAttrib(GL_ALL_ATTRIB_BITS); 
    glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); 
    glEnable(GL_TEXTURE_CUBE_MAP); 
    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureId); 

    mShader->bind(); 

    mShader->setMatrix("matProjection", projection, GL_TRUE); 
    mShader->setMatrix("matView", view, GL_TRUE); 
    // mShader->setMatrix("Texture") 

    model = mat4::scale(20.0f, 20.0f, 20.0f); 
    mShader->setMatrix("matModel", model, GL_TRUE); 

    // set the texture 
    mShader->seti("skyBoxTextureSampler", 0); 


    mVboSkyCube->render(); 

    mShader->release(); 

    glPopClientAttrib(); 
    glPopAttrib(); 
} 

다음은 VBO 객체의 메소드를 렌더링은 다음과 같다

이 코드를 자습서의 단계와 비교하면 누락되었거나 잘못된 순서로 표시되지 않습니다.

현재 Linux 버전이 1.3 만 지원하므로 최신 GLSL 버전을 사용할 수 없습니다.

+0

'sampler2D'를 사용하여 큐브 맵을 샘플링하지 않고'samplerCube'와 검색 할 방향을 나타내는 3D 텍스처 좌표를 사용합니다. 현재 2D 좌표로 무엇을하려고하는지 잘 모르겠습니다. –

+0

오! 고마워요! 프래그먼트 쉐이더를 변경했는데 이제는 효과가 있습니다. (텍스처는 여전히 왜곡되어 있지만, 직접 풀어 볼 것입니다.) – pedjjj

+0

여기서 작동하는 프래그먼트 셰이더는 다음과 같습니다. '#version 130 in vec4 VertPosition; vec4 VertNormal의 ; vec4 VertColor의 ; vec4 VertTexture의 ; // 튜토리얼과 유사한 버텍스 쉐이더의 보간 된 값 :-) uniform vec3 lightPos; uniform samplerCube skyBoxTextureSampler; // 튜토리얼에서 접근 할 텍스처를 알기 위해 :-) void main() { vec4 color = VertColor; gl_FragColor = 텍스처 (skyBoxTextureSampler, VertTexture.xyz); // 텍스처 vec2 (0.8f, 0.2f)가 생성되기 때문에 텍스처 자체가로드되지 않은 것처럼 보임 // \t // vec4 (1.0f, 1.0f, 0.9f, 1.0f); // }' – pedjjj

답변

0

좋습니다. 위의 주석에 이미 설명되어 있듯이 문제는 셰이더에 sampler2D가 포함되어있는 반면 문제는 samplerCube를 사용해야한다는 것입니다. 왜냐하면 C++ 코드에서는 큐브 함수도 상응하여 사용했기 때문입니다.