繁体   English   中英

OpenGL OSG::Texture 乘法只显示一种颜色

[英]OpenGL OSG::Texture multiplication only shows one color

我的目标是“乘以”两个 OSG::Textures,其中一个是光分布(RGBA 图片),另一个是我自己生成的黑白过滤器图像/纹理。 现在,两个纹理具有相同的大小,即使它们可能没有,也会很好。 你可以想象,我试图从光纹理中去除过滤器纹理上的黑色区域。

目前,无论如何,我的代码都可以使整个屏幕变成一种颜色。 我认为gl_MultiTexCoord0gl_TexCoord[0]周围的东西是不正确的。 我查看了多个在线资源,但无法使用其他任何方法。

遗憾的是,我必须使用旧版本的glew (2.1.0) [-> ? 由于框架限制,OpenGL #version 120 ] 和 OSG (3.0.1)。

因为什么都不能正常工作,我现在会尝试只显示 filterTexture(因为如果我显示 lightTexture,一切都是黑色的)......在 init 和 update 我有多个“checkError”到位,看看发生了什么, 但 atm 没有错误。 这是我的着色器:

// vertex shader
const char* shader_combine_vertex = "\n\
#version 120                                    \n\
                                                \n\
void main()                                     \n\
{                                               \n\
    // homogeneous vertex position              \n\
    gl_Position = ftransform();                 \n\
    //Texture coordinate of texture unit 0 and 1\n\
    gl_TexCoord[0] = gl_MultiTexCoord0;         \n\
    gl_TexCoord[1] = gl_MultiTexCoord1;         \n\
}                                               \n";


// fragment shader
const char* shader_combine_fragment = "                                     \n\
#version 120                                                                \n\
// input                                                                    \n\
uniform sampler2D lightTexture;                                             \n\
uniform sampler2D filterTexture;                                            \n\
//varying vec2 lightTexCoord;                                               \n\
//varying vec2 filterTexCoord;                                              \n\
                                                                            \n\
void main()                                                                 \n\
{                                                                           \n\
    gl_FragColor = texture2D(filterTexture, gl_TexCoord[1].st);             \n\
                                                                            \n\
    // gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); //works and shows red       \n\
                                                                            \n\
    // gl_FragColor = texture2D(filterTexture, filterTexCoord);             \n\
                                                                            \n\
    // vec4 texel = texture2D(lightTexture, gl_TexCoord[0].st);             \n\
    // gl_FragColor = texel * texture2D(filterTexture, gl_TexCoord[1].st);  \n\
}\n";

以及具有有效 OpenGL 上下文的全局变量和 init 和 update 函数:

    /** textures for each lightSourceID **/
    std::map<int, GLuint> vp_ShaderCombine;
    std::map<int, GLuint> fp_ShaderCombine;
    /** Program linking shaders **/
    std::map<int, GLhandleARB> combineProgram;

    // TODO: maybe generate all texture IDs at once, but works for now
    std::map<int, unsigned int> g_uiSceneTex[2]; // for every sensor - 2 texture IDs (Light | Filter)

---------

bool initShaders(int id, int width, int height, char* texture)
{
    // Shaders compilation
    vp_ShaderCombine.insert(std::pair<int, GLuint>(id, glCreateShaderObjectARB(GL_VERTEX_SHADER)));
    fp_ShaderCombine.insert(std::pair<int, GLuint>(id, glCreateShaderObjectARB(GL_FRAGMENT_SHADER)));

    glShaderSource(vp_ShaderCombine.at(id), 1, &shader_combine_vertex, NULL);
    glShaderSource(fp_ShaderCombine.at(id), 1, &shader_combine_fragment, NULL);

    glCompileShader(vp_ShaderCombine.at(id));
    checkShaderCompileError(vp_ShaderCombine.at(id), "vertex");
    glCompileShader(fp_ShaderCombine.at(id));
    checkShaderCompileError(fp_ShaderCombine.at(id), "fragment");

    combineProgram[id] = glCreateProgram();
    glAttachShader(combineProgram[id], vp_ShaderCombine[id]);
    glAttachShader(combineProgram[id], fp_ShaderCombine[id]);

    glLinkProgram(combineProgram.at(id));
    glValidateProgram(combineProgram.at(id));

    // Check result and display errors if any
    ...
    return ...;
}

void update()
{
    for (... every light source id ...)
    {
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_LIGHTING);
        // ------------  NECESSARY? ----------------
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_CULL_FACE);
        glDisable(GL_BLEND);
        // ----------- LIGHT----------------
        // mainly the same as filter just on g_uiSceneTex[id][0]
        // ----------- FILTER ----------------
        glUseProgramObjectARB(combineProgram[id]); // call before each glActiveTexture (according to some SO post)
        glActiveTexture(GL_TEXTURE0 + 1);
        // TODO: maybe generate all texture IDs at once, but works for now
        glGenTextures(1, &g_uiSceneTex[id][1]); // generate texture names
        glBindTexture(GL_TEXTURE_2D, g_uiSceneTex[id][1]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, itSHM->myOsgImg->s(), itSHM->myOsgImg->t(), 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, itSHM->myOsgImg);

        GLint filterTexUnitLoc = glGetUniformLocation(combineProgram[id], "filterTexture");
        glUniform1i(filterTexUnitLoc, 0);

        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_CLAMP_TO_BORDER);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);

        // render
        // draw QUAD
        glBegin(GL_QUADS);
        glTexCoord2f(0, 0);
        glVertex3f(0, 1, -1);
        glTexCoord2f(0, ScreenHeight);
        glVertex3f(0, 0, -1);
        glTexCoord2f(ScreenWidth, ScreenHeight);
        glVertex3f(1, 0, -1);
        glTexCoord2f(ScreenWidth, 0);
        glVertex3f(1, 1, -1);
        glEnd();

        // Disable Shaders
        glUseProgramObjectARB(0);

        glDisable(GL_TEXTURE_2D);
        // NECESSARY?
        myShmImages[0].myOsgImg->dirty();
        myPhotometries[0].myOSGTexture->dirtyTextureObject();
    }
}

现在在我这边出现多个问题:

  1. 着色器有什么问题,它们只显示一种颜色? 我认为他们只评估一个像素。
  2. 使用这些 gl 函数与使用 OSG 本机函数创建着色器有什么区别? 是否有限制,或者我的设置是否可行? 它“更容易”吗? 关于该主题的任何好读物,我没有找到任何?
  3. 更新代码看起来很长而且没有必要,每次更新时我都需要生成/创建纹理,还是只能初始化一次?
  4. 目前纹理是全屏显示,但我想在 OSG 树中的 Light 位置显示它。 我有光分布的视锥体,因此我认为,我只需要使用该视图/相机/视锥体“映射”新的过滤纹理...

您根本不提供gl_Multitexcoord1

 glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(0, 1, -1); [...] glEnd();

此代码仅提供gl_MultiTexCoord0数据。 如果您确实需要为每个纹理使用不同的 texcoord,那么您需要通过glMultiTexCoord为每个顶点提供它们:

 glBegin(GL_QUADS); glMultiTexCoord2f(GL_TEXTURE0, 0, 0); glMultiTexCoord2f(GL_TEXTURE1, ..., ...); glVertex3f(0, 1, -1); [...] glEnd();

但是,如果您真的不需要不同的值(从您的问题中不清楚),您也可以为两个纹理使用一组纹理坐标。

请注意,您的代码已经过时了,并且自 2008 年以来在 GL 中已弃用。 即使你只限于GL2.x(如着色器的目标),你应该使用内置的属性,如gl_MultiTexCoord*等使用通用顶点属性,并提供您的数据作为顶点缓冲对象顶点数组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM