В шейдерах OpenGL не получается использовать texture2D и textureCube вместе

Рейтинг: -1Ответов: 1Опубликовано: 03.08.2023

Мне надо использовать обычную 2d текстуру и текстуру куба через один шейдер, но если я использую их через if то всё ломается, нет ничего, чёрное окно. Если использовать что-то одно, то всё нормально, например если я использую только textureCube, то куб будет с текстурой, остальное нет. Погуглил, нашёл такой же открытый вопрос на английском, там был ответ (он не был помечен как правильный), но я его не понял.

//fragment shader
#version 120

uniform sampler2D GL_TEXTURE_2D; 
uniform samplerCube GL_TEXTURE_CUBE_MAP;    

varying vec4 color;
uniform int setTexture;

uniform int isCube;

varying vec4 TexCoord;

void isCubes()
{
    gl_FragColor = textureCube(GL_TEXTURE_CUBE_MAP, TexCoord.rgb);
}

void notCube()
{
    gl_FragColor = texture2D(GL_TEXTURE_2D, TexCoord.rg);
}

void main()
{    
    if(setTexture != 0)
    {
        if(isCube != 0)
            isCubes();
        else
            notCube();
    }
    else
    {
        gl_FragColor = color;
    }
    if(gl_FragCoord.x > ((1920.0/2.0)-1.0) && gl_FragCoord.x < ((1920.0/2.0)+1.0) && gl_FragCoord.y > ((1080.0/2.0)-1.0)&& gl_FragCoord.y < ((1080.0/2.0)+1.0))
    gl_FragColor.rgb = vec3(1)-gl_FragColor.rgb;
}
//vertex shader
#version 120

varying vec4 color;
varying vec4 TexCoord;

void main()
{
  
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    
    color = gl_Color;
    
    TexCoord = gl_MultiTexCoord0;
}

Ответы

▲ 2Принят

Решение было найдено, проблема была из-за того, что я текстуры разного типа загружал в 1 текстурный блок. glActiveTexture меняет текстурные блоки. Например, для загрузки 2D текстур можно использовать glActiveTexture(GL_TEXTURE0); а для загрузки кубических glActiveTexture(GL_TEXTURE1);, можно выбрать любой текстурный блок от 0 до 31.
Так же в шейдеры надо передать значение текстурного блока через glUniform1i Например, если программа шейдера называется prog, в шейдерах uniform sampler2D называется texture_2D; и она используется для функции texture2D(в новых версиях GL texture) то передача значения текстурного блока будет выглядеть так glUniform1i(glGetUniformLocation(prog,"texture_2D"),0); а для кубической текстуры будет так glUniform1i(glGetUniformLocation(prog,"cubeTexture"),1); (uniform samplerCube должен быть cubeTexture; но может быть любым другим)
Для удобной загрузки текстур в блоки я использую свою функцию

void BindTexture(int type, int id)
{

    glUniform1i(SHDsetTexture,id);
    if(type == GL_TEXTURE_CUBE_MAP) 
    {
        glActiveTexture(GL_TEXTURE0);//0 потому что у меня не работает 1, можно изменить на 1
        glBindTexture(type,id); 
        glUniform1i(glGetUniformLocation(prog,"cubeTexture"),0); //тут должно быть число текстурного блока, если текстурный блок GL_TEXTURE0 то и тут должно быть 0, GL_TEXTURE1 то 1 и т.п.
    }
    else 
    {
        glActiveTexture(GL_TEXTURE1);//тут тоже самое что и выше, но блоки не должны совпадать
        glBindTexture(type,id); 
        glUniform1i(glGetUniformLocation(prog,"texture_2D"),1);
    }
    
}

P.S. Прежде чем ставить -1 рейтинг, пожалуйста, обоснуйте его в коментариях, я обьясню если чего то не понятно.