C++ 使用GLSL的多个着色器加载多个纹理时出现问题

C++ 使用GLSL的多个着色器加载多个纹理时出现问题,c++,opengl,glsl,C++,Opengl,Glsl,我尝试在同一场景中使用多个纹理,但无论我尝试什么,都会为每个对象加载相同的纹理。这就是我目前正在做的,我初始化每个着色器: rightWall.SendShaders("wall.vert","wall.frag","brick3.bmp", "wallTex", 0); demoFloor.SendShaders("floor.vert","floor.frag","dirt1.bmp", "floorTex", 1); SendShaders中的代码是:

我尝试在同一场景中使用多个纹理,但无论我尝试什么,都会为每个对象加载相同的纹理。这就是我目前正在做的,我初始化每个着色器:

rightWall.SendShaders("wall.vert","wall.frag","brick3.bmp", "wallTex", 0);      
demoFloor.SendShaders("floor.vert","floor.frag","dirt1.bmp", "floorTex", 1);
SendShaders中的代码是:

            GLuint vert,frag;
            glEnable(GL_DEPTH_TEST);
            glEnable(GL_TEXTURE_2D);

            char *vs = NULL,*fs = NULL;

            vert = glCreateShader(GL_VERTEX_SHADER);
            frag = glCreateShader(GL_FRAGMENT_SHADER);

            vs = textFileRead(vertFile);
            fs = textFileRead(fragFile);
            const char * ff = fs;
            const char * vv = vs;

            glShaderSource(vert, 1, &vv, NULL);
            glShaderSource(frag, 1, &ff, NULL);

            free(vs); free(fs);

            glCompileShader(vert);
            glCompileShader(frag);

            program = glCreateProgram();
            glAttachShader(program, frag);
            glAttachShader(program, vert);

            glLinkProgram(program);
            glUseProgram(program);

        LoadGLTexture(textureImage, texture);
然后在主循环中:

rightWall.UseShader("wallTex");
rightWall.Draw();   

demoFloor.UseShader("floorTex");
demoFloor.Draw();
UseShader中的代码:

void GraphicsObject::UseShaderchar textureName[]{

glUseProgram(program);  
GLint location = glGetUniformLocation(program, textureName);
glUniform1i(location, 0); 
glActiveTexture(GL_TEXTURE0);           
glBindTexture(GL_TEXTURE_2D, texture);
}

最后,纹理加载方法:

int GraphicsObject::LoadGLTextureconst字符文件名[]{

AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture
memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL
int arraySize = strlen(fileName); 
arraySize += 1;
 if (TextureImage[0]=LoadBMP(fileName, arraySize))
{
              glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TextureImage[0]->sizeX, 
    TextureImage[0]->sizeY, 0, GL_RGB,         
     GL_UNSIGNED_BYTE, TextureImage[0]->data);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);       
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);       
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);        
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);        
 }
if (TextureImage[0])
{
        if (TextureImage[0]->data)
    {
            free(TextureImage[0]->data);    
                }
    free(TextureImage[0]);              
}   

return 1;
}

AUX_RGBImageRec*GraphicsObject::LoadBMPconst char fileName[],int arraySize{

FILE *File=NULL; 
LPWSTR pwszFileName;
int lenW;
BSTR unicodestr;

lenW = MultiByteToWideChar(CP_ACP, 0, fileName, arraySize, 0,0);

DWORD bottom = GetLastError();
unicodestr = SysAllocStringLen(0, lenW);

MultiByteToWideChar(CP_ACP,0, fileName, arraySize,
    unicodestr,lenW);
SysFreeString(unicodestr);
DWORD tit = GetLastError();

if (!fileName) 
{
    return NULL; 
}

File=fopen(fileName,"r"); 

if (File) 
{
    fclose(File);
    return auxDIBImageLoad((LPCWSTR)unicodestr);
}
return NULL;
}


最后初始化哪个着色器是用于两个对象的纹理。感谢您的时间,我非常感谢您的评论。

就像您必须在使用着色器进行渲染之前调用glUseProgramprogram一样,您也必须在渲染之前直接绑定正确的纹理

代码应该如下所示:

glUseProgram(program1);
glBindTexture(GL_TEXTURE_2D, texture1);
// render calls for object 1

glUseProgram(program2);
glBindTexture(GL_TEXTURE_2D, texture2);
// render calls for object 2
此外,制服也必须在渲染之前直接设置,而不是在着色器初始化时设置

那么在你的情况下

GLint location = glGetUniformLocation(program, textureName);
glUniform1i(location, 0);
glActiveTexture(GL_TEXTURE0);           
glBindTexture(GL_TEXTURE_2D, texture);

不属于函数SendShaders,但属于UseShader

就像在使用着色器进行渲染之前必须调用GluseProgramRampRogram一样,也必须在渲染之前直接绑定正确的纹理

代码应该如下所示:

glUseProgram(program1);
glBindTexture(GL_TEXTURE_2D, texture1);
// render calls for object 1

glUseProgram(program2);
glBindTexture(GL_TEXTURE_2D, texture2);
// render calls for object 2
此外,制服也必须在渲染之前直接设置,而不是在着色器初始化时设置

那么在你的情况下

GLint location = glGetUniformLocation(program, textureName);
glUniform1i(location, 0);
glActiveTexture(GL_TEXTURE0);           
glBindTexture(GL_TEXTURE_2D, texture);

不属于函数SendShaders,但属于UseShader

我要指出显而易见的事情,以确保你能排除它


您的纹理图像数据实际上不同吗?你有没有检查过你的纹理加载代码,以确保你得到了不同的纹理文件?

我要指出明显的问题,以确保你能排除它


您的纹理图像数据实际上不同吗?您是否检查了纹理加载代码以确保为纹理获取不同的文件?

谢谢您的输入,但是,在进行这些更改后,结果仍然是一样的。我更新了我的答案,制服也必须以不同的方式处理。你能看看这个吗?好的,现在我的UseShader看起来像:GluseProgramRamprogram;闪烁位置=glGetUniformLocationprogram,textureName;葡糖基化,0;GlactiveTextureRegl_TEXTURE0;GLBindTextureGLU纹理2D,纹理;但是结果仍然和以前完全一样。请更新上面的源代码,说明SendShader和useshader的全部功能LoadGLTexturetextureImage,texture;会有帮助的。“纹理”在哪里定义?SendShader中最后一个参数的目的是什么?请再加上这个。还有一个问题:墙和地板着色器是否相同?如果不是,着色器是否正确?感谢您的输入,但是,在进行这些更改后,结果仍然是一样的。我更新了我的答案,制服也必须以不同的方式处理。你能看看这个吗?好的,现在我的UseShader看起来像:GluseProgramRamprogram;闪烁位置=glGetUniformLocationprogram,textureName;葡糖基化,0;GlactiveTextureRegl_TEXTURE0;GLBindTextureGLU纹理2D,纹理;但是结果仍然和以前完全一样。请更新上面的源代码,说明SendShader和useshader的全部功能LoadGLTexturetextureImage,texture;会有帮助的。“纹理”在哪里定义?SendShader中最后一个参数的目的是什么?请再加上这个。还有一个问题:墙和地板着色器是否相同?如果着色器不正确?纹理图像数据不同,这取决于在两个对象上绘制哪个纹理时最后声明哪个SendShader。纹理图像数据不同,这取决于在两个对象上绘制哪个纹理时最后声明哪个SendShader。