У меня есть эта программа для простого тестирования.Программа создает две 1-D текстуры и передает их шейдерам.Фрагмент шейдера очень прост.Он просто вытаскивает тексель с индексом 4 первой текстуры и делает этот тексель цветным фрагментом:
#extension GL_EXT_gpu_shader4 : enable
uniform sampler1D firstTexture;
uniform sampler1D secondTexture;
uniform int max_index;
void main()
{
vec4 texel = texture1D( firstTexture, float(4.0) / float(max_index));
gl_FragColor = texel;
}
Я рисую квадрат, а индекс с текселем 4 в первой текстуре содержит <1.0, 0.0, 0.0, 1.0>, который имеет красный цвет.Поэтому результаты шейдера выше - это красный квадрат.Проблема возникает, когда я создаю вторую 1-D текстуру и передаю ее шейдеру.По какой-то неизвестной причине шейдеру это не нравится, и он больше не работает, и вместо красного рисуется черный квадрат.Вот код C ++: (код внутри функции "makeGLTexture" находится ниже).
// =========================================
// Set up the first 1-D texture.
// =========================================
firstTexture.allocateTexels(10);
firstTexture.fullyPopulateTexture();
glActiveTexture(GL_TEXTURE0);
firstTextureID = firstTexture.makeGLTexture();
// =========================================
// Set up the second 1-D texture.
// =========================================
secondTexture.allocateTexels(10);
secondTexture.fullyPopulateTexture();
glActiveTexture(GL_TEXTURE1);
secondTextureID = secondTexture.makeGLTexture();
// Set up some parameters.
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// ========================================
// Create the Shaders and Get Them Running.
// ========================================
#if defined (_WIN32)
const char* vertexShaderSource = textFileRead("Vertex.vs");
const char* fragmentShaderSource = textFileRead("Fragment.fs");
#else
const char* vertexShaderSource = textFileRead("../../Vertex.vs");
const char* fragmentShaderSource = textFileRead("../../Fragment.fs");
#endif
GLuint vertexShader = createShader(vertexShaderSource, GL_VERTEX_SHADER);
GLuint fragmentShader = createShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
GLuint shaderProgram = createProgram(vertexShader, fragmentShader);
if (shaderProgram != 0) glUseProgram(shaderProgram);
delete vertexShaderSource;
delete fragmentShaderSource;
// ===================================================
// Pass the information of the textures to the shader.
// ===================================================
// Pass the texture unit of the first texture to the shaders.
GLuint location = glGetUniformLocation(shaderProgram,"firstTexture");
glUniform1i ( location, 0 );
// Pass the texture unit of the second texture to the shaders.
location = glGetUniformLocation(shaderProgram,"secondTexture");
glUniform1i ( location, 1 );
// Pass the maximum number of texels in the 1D texture.
location = glGetUniformLocation(shaderProgram,"max_index");
glUniform1i ( location, 9 );
Привязка текстур выполняется функцией "makeGLTexture".Вот код внутри него.
// Define an array that stores the texture's information.
Texel* const texelArray = new Texel[texels.size()];
// Copy information from the vector of texels into the array of texels.
for (unsigned int index = 0; index < texels.size(); index++)
texelArray[index] = texels[index];
/* ====================
* Generate the texture.
* ====================*/
// ID of the texture.
GLuint textureID;
// Generate a texture object ID for this texture.
glGenTextures( 1, &textureID );
// Bind the texture object to the texture identifier.
glBindTexture( GL_TEXTURE_1D, textureID );
// Define the texture image.
glTexImage1D( GL_TEXTURE_1D, 0, GL_RGBA, texels.size(), 0, GL_RGBA, GL_FLOAT, texelArray );
// ===================== //
// Free the memory allocated for the texture array (array of texels).
delete[] texelArray;
// Return the texture ID.
return textureID;
Особенность в том, что если я переключаю активный текстурный блок сразу после того, как я создал вторую текстуру на текстурный блок первой текстуры, то программа снова работает,и рисуется красный квадрат.
/* =========================================
* Set up the second one-dimensional texture.
* =========================================*/
...
**glActiveTexture(GL_TEXTURE0);**
Затем программа снова будет работать.
Мой вопрос: почему это происходит?Разве шейдер не зависит от текстурного блока?Разве нам не нужно только передавать текстурный блок в переменную-сэмплер, и все?В этом случае, почему я должен изменить текстурный блок обратно на нулевой блок текстуры, чтобы шейдер снова запустился?Что происходит?