1

I am trying to use multiple textures in the same scene but no matter what I try the same texture is loaded for each object. So this what I am doing at the moment, I initialise each shader:

rightWall.SendShaders("wall.vert","wall.frag","brick3.bmp", "wallTex", 0);      
demoFloor.SendShaders("floor.vert","floor.frag","dirt1.bmp", "floorTex", 1);

The code in SendShaders is:

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

And then in the main loop:

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

demoFloor.UseShader("floorTex");
demoFloor.Draw();

The code in UseShader:

void GraphicsObject::UseShader(char textureName []){

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

}

And finally, the texture load methods:

int GraphicsObject::LoadGLTexture(const char fileName []){

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::LoadBMP(const 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;

}

Which ever shader is initialised last is the texture which is used for both objects. Thank you for your time and I appreciate any comments.

2 Answers 2

3

Like you have to call glUseProgram(program) before using the shader for rendering, you also have to bind the right texture directly before rendering.

The code should look like this:

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

glUseProgram(program2);
glBindTexture(GL_TEXTURE_2D, texture2);
// render calls for object 2

Moreover also Uniforms must be set directly before rendering, and not at shader intialization.

So in your case the part

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

does not belong in the function SendShaders, but in UseShader!

Sign up to request clarification or add additional context in comments.

9 Comments

Thank you for your input, however, after making those changes the result is still the same.
I updated my answer, that uniforms must also be treated differently. Culd you check this out?
Ok, so now my UseShader looks like: glUseProgram(program); GLint location = glGetUniformLocation(program, textureName); glUniform1i(location, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); But the result is still exactly the same as before.
Could you please update your source code above, stating the whole functions SendShader and UseShader
The code of LoadGLTexture(textureImage, texture); would be helpful. Where is 'texture' defined? What is the purpos of the last parameter in SendShader? Please add this too. And another question: are the wall and the floor shader identically? If not is the shader correct?
|
1

I'm going to point out the obvious just to make sure you can rule it out.

Is your texture image data actually different? Have you checked your texture loading code to make sure you are getting different files for the texture?

1 Comment

The texture image data is different, it depends on which SendShaders is stated last as to which texture gets drawn on both objects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.