Opengl黑色/空白立方体贴图纹理

时间:2016-10-11 22:38:43

标签: opengl-es sdl opengl-es-2.0

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

纹理加载zTexture* vars是类变量

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);
}

“优步”着色器:
顶点:

#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立方体贴图可以在没有它们的情况下工作。

1 个答案:

答案 0 :(得分:1)

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

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

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

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