Opengl black/blank 立方体贴图纹理

Opengl black/blank cubemap texture

我正在尝试为天空盒和反射使用单个立方体贴图纹理,但我最终只为两者使用了黑色纹理。我正在为立方体贴图使用一个临时像素数组,以确保图像不是问题所在。所以忽略这个函数中的 SDL 内容;我评论了一些。纹理函数和着色器也用于 2d 和立方体贴图纹理,所以我也将其注释掉了。

纹理加载zTexture* 变量是 class 变量

bool loadCubeMap(std::vector<const char*> path)
{
    //Texture loading success
    bool textureLoaded = false;

    glEnable(GL_TEXTURE_CUBE_MAP); //probably not needed

    for(int j=0; j<path.size(); j++)
    {
        //SDL_Surface* cubFacSurf = IMG_Load(path[j]);  
        if(cubFacSurf != NULL)
        {
            //SDL_LockSurface(cubFacSurf);              
            zTextureW = cubFacSurf->w;
            zTextureH = cubFacSurf->h;
            textureLoaded = loadFromPixels((GLuint*)cubFacSurf->pixels, zTextureW, zTextureH, GL_TEXTURE_CUBE_MAP, GL_RGB, GL_TEXTURE_CUBE_MAP_POSITIVE_X+j);
            //SDL_UnlockSurface(cubFacSurf);
            //SDL_FreeSurface(cubFacSurf);
        }
        if(textureLoaded == false)
        {
            SDL_Log("Unable to load %s\n", path[j]);
        }
    }
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    return textureLoaded;
}

主要像素加载器

bool loadFromPixels(void* pixels, GLuint width, GLuint height, const GLenum tType = GL_TEXTURE_2D, const GLenum glPix = GL_RGB, const GLenum tFace = GL_TEXTURE_2D)
{
    glGenTextures(1, &zTextureID);
    glBindTexture(tType, zTextureID);

    GLfloat checkerboard[] = {1.f,1.f,1.f,  0.f,0.f,0.f,    0.f,0.f,0.f,    1.f,0.f,1.f};
    if(tType == GL_TEXTURE_CUBE_MAP)
        glTexImage2D(tFace, 0, glPix, 2, 2, 0, glPix, GL_FLOAT, &checkerboard);
    //else
    //glTexImage2D(tFace, 0, glPix, width, height, 0, glPix, GL_UNSIGNED_BYTE, pixels);

    //Check for error
    GLenum error = glGetError();
    if( error != GL_NO_ERROR )
    {
        SDL_Log( "Error loading texture from %p pixels! %d\n", pixels, error);
        return false;
    }
    return true;
}

纹理绑定:

void apply(const GLenum typ = GL_TEXTURE_2D)
{
    glEnable(typ); //Probably not necessary doesnt change anything if left out
    if(typ == GL_TEXTURE_2D)
    {
        glDisable(GL_TEXTURE_CUBE_MAP); //same here
        glUniform1i(mainTxtrID, 0); //mainTxtrID = Textr in frag
        glActiveTexture(GL_TEXTURE0);
    }
    else
    {
        glDisable(GL_TEXTURE_2D); //and here
        glUniform1i(cubeID, 1); //cubeID = TextCub in frag
        glActiveTexture(GL_TEXTURE1);
    }
    glBindTexture(typ, zTextureID);
}

"Uber" 着色器:
顶点:

#version 100  
precision mediump float;  

uniform mat4 ModelMat;  
uniform mat4 ViewMat;  
uniform mat4 ProjMat;  
uniform mat4 OrthMat;

uniform bool world;  
attribute vec4 vPosition;  
attribute vec2 UVCoordAt;  
attribute vec3 nPosition;  
varying vec2 UVCoord;  
varying vec3 vPos;  
varying vec3 vNor;  
varying vec3 vRefl;  

void main()  
{  
    UVCoord = UVCoordAt;  
    vPos = vec3(vPosition);  //skybox coords
    vNor = normalize(vec3(ModelMat * vec4(nPosition,0.0)));  
    vRefl = reflect(normalize(vPos - vec3(ViewMat[3][0], ViewMat[3][1], ViewMat[3][2])), vNor); //reflection direction vector 
    if(world)
            gl_Position = ProjMat * ViewMat * ModelMat * vPosition;
    else    gl_Position = OrthMat * ModelMat * vPosition;
}

片段:

#version 100  
precision mediump float;  

uniform samplerCube TextCub;  
uniform sampler2D Textr;  
uniform vec3 LiPos;  
uniform vec4 fragCol;  

uniform bool lighting;  
uniform bool dimen;  
uniform bool isRefl;  
varying vec2 UVCoord;  
varying vec3 vPos;  
varying vec3 vNor;  
varying vec3 vRefl;

void main()  
{  
    vec4 textVect = texture2D(Textr, UVCoord);  //default texturing
    if(dimen){    textVect = textureCube(TextCub, vPos);    }  //skybox
    else if(isRefl){    textVect = mix(textVect, textureCube(TextCub, vRefl), 0.7);    }  //reflections mixed with default textr
    if(lighting){ 
        float diffuse = clamp(dot(vNor, LiPos), 0.0, 1.0);
        gl_FragColor = clamp(diffuse*2.0, 0.6, 1.1) * fragCol * textVect;  
    }  
    else{   gl_FragColor =  fragCol * textVect; }
}

我正在使用 GL_DEPTH_TEST,我怀疑这会影响什么。我猜问题出在 apply() 函数或其他我遗漏的地方。有立方体贴图的扩展,但我假设默认的 opengles 2 立方体贴图在没有它们的情况下也能工作。

您正在为每个立方体贴图面创建一个新纹理。在 loadFromPixels() 函数中,您为每张脸调用该函数:

glGenTextures(1, &zTextureID);
glBindTexture(tType, zTextureID);
...
glTexImage2D(...);

这意味着您最终将得到 6 个纹理,每个纹理都只有指定一个面的数据,这使得它们不完整。

您需要创建一个立方体贴图纹理,然后为该立方体贴图的所有 6 个面指定数据。