簡體   English   中英

GLSL紋理函數僅向天空框返回黑色

[英]GLSL Texture Function Returning Only Black For Sky Box

我正在嘗試通過使用GLSL為四邊形紋理來為OpenGL場景生成一個天空盒。 但是,當我嘗試使用紋理生成天空盒顏色時,天空盒只是變成黑色。 當我手動設置顏色時,天空盒可以工作,因此我基本上將問題縮小到我設置紋理的方式有問題。 我還弄亂了紋理函數的一堆不同的eyeDirection矢量值,但仍然只得到一個黑色正方形。

這是我的片段着色器:

#version 450 compatibility

layout(binding=0) uniform samplerCube currTexture;

smooth in vec3 eyeDirection;

out vec4 fragmentColor;

void main() {
    fragmentColor = texture(currTexture, eyeDirection);
    //fragmentColor = vec4(eyeDirection, 1.0);
}

這是我的頂點着色器:

#version 450

uniform mat4 projection;
uniform mat4 modelView;

in vec4 aPosition;

smooth out vec3 eyeDirection;

void main() {
    mat3 inverseModelView = inverse(mat3(modelView));
    vec3 unprojected = (inverse(projection) * aPosition).xyz;
    eyeDirection = inverseModelView * unprojected;
    // eyeDirection = aPosition.xyz;

    //gl_Position = aPosition.xyww;
    gl_Position = new vec4(aPosition.x, aPosition.y, 1.0, aPosition.w );
} 

這是我初始化紋理的地方:

// initializes all the necessary texture values
void TrainView::initTextures() {
    // loading in texture maps
    SDL_Surface* xPos = IMG_Load("SkyBoxXpos.png");
    SDL_Surface* xNeg = IMG_Load("SkyBoxXneg.png");
    SDL_Surface* yPos = IMG_Load("SkyBoxYpos.png");
    SDL_Surface* yNeg = IMG_Load("SkyBoxYneg.png");
    SDL_Surface* zPos = IMG_Load("SkyBoxZpos.png");
    SDL_Surface* zNeg = IMG_Load("SkyBoxZneg.png");

    if (!xPos) 
        printf("IMG_Load: %s\n", IMG_GetError());
    if (!xNeg) 
        printf("IMG_Load: %s\n", IMG_GetError());
    if (!yPos) 
        printf("IMG_Load: %s\n", IMG_GetError());
    if (!yNeg) 
        printf("IMG_Load: %s\n", IMG_GetError());
    if (!zPos) 
        printf("IMG_Load: %s\n", IMG_GetError());
    if (!zNeg) 
        printf("IMG_Load: %s\n", IMG_GetError());
        // handle error

    glGenTextures(1, &skyBoxTexture);
    glActiveTexture(GL_TEXTURE0);
    glEnable(GL_TEXTURE_CUBE_MAP);
    glBindTexture(GL_TEXTURE_CUBE_MAP, skyBoxTexture);

    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_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);

    // files are 24-bit bmp files
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, xPos->w, xPos->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, xPos->pixels);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, xNeg->w, xNeg->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, xNeg->pixels);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, yPos->w, yPos->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, yPos->pixels);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, yNeg->w, yNeg->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, yNeg->pixels);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, zPos->w, zPos->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, zPos->pixels);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, zNeg->w, zNeg->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, zNeg->pixels);

    glBindTexture(GL_TEXTURE_CUBE_MAP, NULL);

}

這是我嘗試繪制/渲染天空盒的地方:

// handles everything for drawing the sky box
void TrainView::drawSkyBox(){

    glUseProgram(skyBoxShader);
    glActiveTexture(GL_TEXTURE0);

    glBindTexture(GL_TEXTURE_CUBE_MAP, skyBoxTexture);

    int loc = glGetUniformLocation(skyBoxShader, "modelView");

    GLfloat mvFl[16], projFl[16];

    glGetFloatv(GL_MODELVIEW_MATRIX, mvFl);

    glUniformMatrix4fv(loc, 1, GL_FALSE, mvFl);

    loc = glGetUniformLocation(skyBoxShader, "projection");

    glGetFloatv(GL_PROJECTION_MATRIX, projFl);
    glUniformMatrix4fv(loc, 1, GL_FALSE, projFl);

    loc = glGetUniformLocation(skyBoxTexture, "currTexture");
    glUniform1i(loc, 0);

    // not sure if this is necessary or done as intended by opengl
    GLuint sampler;
    glGenSamplers(1, &sampler);
    glBindSampler(0, sampler);

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);

    glBegin(GL_QUADS);
        glVertex3f(-1.0, -1.0, 0.0);
        glVertex3f(1.0, -1.0, 0.0);
        glVertex3f(1.0, 1.0, 0.0);
        glVertex3f(-1.0, 1.0, 0.0);
    glEnd();

    glUseProgram(NULL);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
}

您將在此處為多維數據集紋理啟用mipmapped采樣:

glTexParameteri(GL_TEXTURE_CUBE_MAP,
                GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

但是,您沒有為紋理創建mipmap。 在規范語言中,這意味着您的紋理不是“ mipmap完整的”,從而使它不是“紋理完整的”。 采樣不完整紋理的結果為BLACK

創建glGenerateMipmap()的最簡單方法是在指定紋理數據后,即在所有glTexImage2D()調用6面之后 ,調用glGenerateMipmap()

glGenerateMipmap(GL_TEXTURE_CUBE_MAP);

如果不需要mipmap,則只需將filter參數的值設置為不使用mipmap:

glTexParameteri(GL_TEXTURE_CUBE_MAP,
                GL_TEXTURE_MIN_FILTER, GL_LINEAR);

您嘗試創建采樣器對象所做的事情在這里無濟於事。 如果要使用多個不同的采樣屬性采樣 相同的紋理 ,則采樣器對象很有用。 假設您要在同一着色器中使用GL_LINEARGL_NEAREST對相同的紋理進行采樣,則可以通過為此紋理創建兩個采樣器對象來實現。 我認為這不是一個非常普遍的用例,但是在某些情況下它派上用場,並且在引入采樣器對象之前是不可能做到的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM