Проблема загрузки нескольких текстур с использованием нескольких шейдеров с GLSL - PullRequest
1 голос
/ 14 апреля 2010

Я пытаюсь использовать несколько текстур в одной сцене, но независимо от того, что я пытаюсь, одна и та же текстура загружается для каждого объекта. Вот что я сейчас делаю, я инициализирую каждый шейдер:

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 :: UseShader (char textureName []) {

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

}

И, наконец, методы загрузки текстуры:

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;

}

Какой шейдер когда-либо инициализируется последним, это текстура, которая используется для обоих объектов. Спасибо за ваше время, и я ценю любые комментарии.

Ответы [ 2 ]

3 голосов
/ 14 апреля 2010

Как вы должны вызывать glUseProgram (программу) перед использованием шейдера для рендеринга, вы также должны привязать правильную текстуру непосредственно перед рендерингом.

Код должен выглядеть так:

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

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

Кроме того, Uniforms также должны быть установлены непосредственно перед рендерингом, а не при инициализации шейдера.

Так что в вашем случае часть

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

принадлежит не функции SendShaders, а функции UseShader!

1 голос
/ 14 апреля 2010

Я собираюсь указать на очевидное, просто чтобы убедиться, что вы можете исключить это.

Действительно ли ваши данные изображения текстуры отличаются? Вы проверили свой код загрузки текстуры, чтобы убедиться, что вы получаете разные файлы для текстуры?

...