纹理显示为纯黑色,除非我将无效值传递给纹理均匀位置

usm*_*usm 1 c++ opengl glsl

到目前为止,我的计划一直运作良好,但事实证明我很幸运.我开始对着色器进行一些清理,因为它充满了实验性的东西,并且我在片段着色器的末尾有以下行:

gl_FragColor = final_color * (texture2D(tex, gl_TexCoord[0].st)*1.0 + texture2D(tex2, gl_TexCoord[0].st)*1.0);
Run Code Online (Sandbox Code Playgroud)

我试图清理它,并在顶部声明了以下内容:

uniform sampler2D tex, tex2;
Run Code Online (Sandbox Code Playgroud)

将这些行更改为:

gl_FragColor = final_color * texture2D(tex, gl_TexCoord[0].st;
Run Code Online (Sandbox Code Playgroud)

uniform sampler2D tex;
Run Code Online (Sandbox Code Playgroud)

实际上打破了程序(黑屏),即使我在做

GLuint tex_loc = glGetUniformLocation(shader_prog_id_, "tex");
glUniform1i(tex_loc, texture_id_);
Run Code Online (Sandbox Code Playgroud)

在我的主要代码中.我确定这是一个纹理问题而不是glsl编译器错误,因为我可以添加1.0到输出并最终得到我的网格的白色轮廓.

当我将着色器中的线条更改为:

gl_FragColor = final_color * texture2D(tex2, gl_TexCoord[0].st;
Run Code Online (Sandbox Code Playgroud)

uniform sampler2D tex2;
Run Code Online (Sandbox Code Playgroud)

但仍然检索位置tex.即使检查tex_loc调试器中的值指示错误,程序也会像往常一样工作.我不喜欢这样做,现在我正在尝试加载多个纹理,这将导致更大的头痛.

我正在使用交错格式的VBO来渲染几何体.我通过这种方式传递顶点位置,普通和texcoord.

"黑色纹理"问题还有其他问题,但它们使用立即模式调用并设置错误的纹理状态.我尝试在提供数组之前更改纹理单元,但没有成功.

这是与主程序尽可能相关的代码:

void MeshWidget::draw() {

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -4.0f + zoom_factor_);
    glRotatef(rotX, 1.0f, 0.0f, 0.0f);
    glRotatef(rotY, 0.0f, 1.0f, 0.0f);
    glRotatef(rotZ, 0.0f, 0.0f, 1.0f);

    // Auto centre mesh based on vertex bounds.
    glTranslatef(-x_mid_, -y_mid_, -z_mid_);

    glDrawElements(GL_TRIANGLES, mesh_.num_indices, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));   //The starting point of the IBO
}


void MeshWidget::openMesh(const string& filename) {

    if (mesh_filename_ != filename) {

        clearMeshData(mesh_);

        glDeleteBuffersARB(1, &VertexVBOID);
        glDeleteBuffersARB(1, &IndexVBOID);

        ReadMsh(mesh_, filename);

        // Create buffer objects here.
        glGenBuffersARB(1, &VertexVBOID);
        glBindBufferARB(GL_ARRAY_BUFFER, VertexVBOID);
        glBufferDataARB(GL_ARRAY_BUFFER, sizeof(VertexAttributes)*mesh_.num_vertices, &mesh_.vertices[0], GL_STATIC_DRAW);

        glGenBuffersARB(1, &IndexVBOID);
        glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
        glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint16_t)*mesh_.num_indices, &mesh_.indices[0], GL_STATIC_DRAW);

        glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(3, GL_FLOAT, sizeof(VertexAttributes), BUFFER_OFFSET(0));   //The starting point of the VBO, for the vertices
        glEnableClientState(GL_NORMAL_ARRAY);
        glNormalPointer(GL_FLOAT, sizeof(VertexAttributes), BUFFER_OFFSET(12));   //The starting point of normals, 12 bytes away
        glClientActiveTexture(GL_TEXTURE0);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glTexCoordPointer(2, GL_FLOAT, sizeof(VertexAttributes), BUFFER_OFFSET(24));   //The starting point of texcoords, 24 bytes away

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);

        if (startup_done_) updateGL();
    }
}

void MeshWidget::openTexture(const string& filename) {

    size_t dot = filename.find_last_of('.');
    string ext(filename, dot, filename.size()); // 3rd parameter should be length of new string, but is internally clipped to end.

    glActiveTexture(GL_TEXTURE0);
    glClientActiveTexture(GL_TEXTURE0);
    glDeleteTextures(1, &texture_id_);
    glGenTextures(1, &texture_id_);
    glBindTexture(GL_TEXTURE_2D, texture_id_);

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    if (ext == ".dds") {
        if (GLEE_EXT_texture_compression_s3tc) {

            texture_id_ = SOIL_load_OGL_texture(filename.c_str(), SOIL_LOAD_AUTO, texture_id_, SOIL_FLAG_DDS_LOAD_DIRECT);
            // SOIL takes care of calling glTexParams, glTexImage2D, etc.
            yflip_texture_ = true;

            } else {
                //std::cout << "S3TC not supported on this graphics hardware." << std::endl;
                // TODO: Error message in status bar?
            }

    } else {

        QImage tex(filename.c_str());
        tex = QGLWidget::convertToGLFormat(tex);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());

        yflip_texture_ = false;

    }

    updateUniforms();

    if (startup_done_) updateGL();
}

void MeshWidget::updateUniforms() {

    GLuint texture_flip_uniform = glGetUniformLocation(shader_prog_id_, "yflip");
    glUniform1f(texture_flip_uniform, float(yflip_texture_ * 1.0f));

    GLuint tex_loc = glGetUniformLocation(shader_prog_id_, "tex");
    glUniform1i(tex_loc, texture_id_);
}
Run Code Online (Sandbox Code Playgroud)

我的着色器(这里还有一些垃圾,因为我正在试验,但没有任何影响输出的东西):

varying vec3 normal, lightDir, eyeVec;
uniform float yflip;

void main()
{   
    normal = gl_NormalMatrix * gl_Normal;

    vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);

    lightDir = vec3(gl_LightSource[0].position.xyz - vVertex);
    eyeVec = -vVertex;

    gl_TexCoord[0].x = gl_MultiTexCoord0.x;
    gl_TexCoord[1].x = gl_MultiTexCoord1.x;

    if (yflip == 1.0) {
        gl_TexCoord[0].y = 1 - gl_MultiTexCoord0.y;
        gl_TexCoord[1].y = 1 - gl_MultiTexCoord1.y;
    } else {
        gl_TexCoord[0].y = gl_MultiTexCoord0.y;
        gl_TexCoord[1].y = gl_MultiTexCoord1.y;
    }

    gl_Position = ftransform();
}
Run Code Online (Sandbox Code Playgroud)

片段着色器:

varying vec3 normal, lightDir, eyeVec;
uniform sampler2D tex2;

void main (void)
{

    vec4 texel = texture2D(tex2, gl_TexCoord[0].st);

    vec4 final_color =
(gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) + 
(gl_LightSource[0].ambient * gl_FrontMaterial.ambient);

    vec3 N = normalize(normal);
    vec3 L = normalize(lightDir);

    float lambertTerm = dot(N,L);

    if(lambertTerm > 0.0)
    {
        final_color += gl_LightSource[0].diffuse * 
                   gl_FrontMaterial.diffuse * 
                   lambertTerm; 

        vec3 E = normalize(eyeVec);
        vec3 R = reflect(-L, N);
        float specular = pow( max(dot(R, E), 0.0), 
                     gl_FrontMaterial.shininess );
        final_color += gl_LightSource[0].specular * 
                   gl_FrontMaterial.specular * 
                   specular;    
    }

    gl_FragColor = final_color * texel;
}
Run Code Online (Sandbox Code Playgroud)

aru*_*rul 6

glUniform1i(tex_loc,texture_id_);

第二个参数应指定纹理单元的ID(提示:glActiveTexture设置当前活动的纹理单元),而不是特定纹理对象的ID.