tags:

views:

411

answers:

2

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  A: 

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!

Danvil
Thank you for your input, however, after making those changes the result is still the same.
paj777
I updated my answer, that uniforms must also be treated differently. Culd you check this out?
Danvil
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.
paj777
Could you please update your source code above, stating the whole functions SendShader and UseShader
Danvil
updated as requested.
paj777
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?
Danvil
Firstly, the last parameter is now no longer used but haven't had time to take it out. Secondly, the shaders are identical and lastly, texture is defined in the private section of the header.
paj777
LoadGLTexture method added.
paj777
Did you call glGenTextures?
Danvil
I did try glGenTextures but that didn't work either.
paj777
Please add to your code where you call it. Especially where you set the "texture" variable used in the call to LoadGLTexture(textureImage, texture);Also could you try a glBindTexture(GL_TEXTURE_2D, textureID); in the beginning of the function LoadGLTexture.
Danvil
Ok, updated as requested, although like I said the result is no different.
paj777
Ok, Im officially a spanner, I wasn't binding the texture when I wanted to use it in UseShader.
paj777
+1  A: 

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?

Jose
The texture image data is different, it depends on which SendShaders is stated last as to which texture gets drawn on both objects.
paj777
nevermind I just saw the end of the last answer.
Jose