Я узнал о том, как использовать текстуры с GLSL (в LWJGL) для создания простого фрагментного шейдера, который размывает текстуру. Первая попытка (для тестирования) была очень простым шейдером, который просто принимает исходные значения цвета:
uniform sampler2D rectTexture;
void main(){
vec4 color = texture2D(rectTexture, gl_FragCoord.st);
gl_FragColor = color;
}
Шейдер компилируется нормально. После компиляции я делаю ссылку и начинаю ее использовать, до этого все работало и об ошибках не сообщалось. Затем я пытаюсь установить единую переменную для текстуры:
uniformTextureAddr = ARBShaderObjects.glGetUniformLocationARB(programObject, "rectTexture");
ARBMultitexture.glActiveTextureARB(ARBMultitexture.GL_TEXTURE0_ARB);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
ARBShaderObjects.glUniform1iARB(uniformTextureAddr, 0);
Затем я просто рисую квад с обычными текстовыми координатами (0.0f-1.0f в обоих измерениях), но текстура не отображается. Сама текстура не проблема; Я рисую второй четырехугольник рядом с первым без моего фрагментного шейдера, и он появляется так, как вы ожидаете. Базовый подход взят из NeHe: GLSL - Введение . uniformTextureAddr
не равно -1, и если я использую еще более простой шейдер, который просто превращает каждый пиксель в красный, я получаю красный квад. Как и ожидалось. Так что ошибка должна быть во всем деле sampler2D. Тривиальные ошибки, такие как четырехугольник, просто находящийся вне кадра, также исключаются этим.
И да, после рисования без шейдера я снова вызываю glUseProgramObject (programObj) с моим шейдером.
Кстати, это работает на Windows XP SP3 с драйвером ATI Radeon Catalyst 10.6 и LWJGL версии 2.4.2.
ОБНОВЛЕНИЕ: Я думаю, что-то может быть не так с самой программой. Когда я добавляю еще одну переменную в шейдер:
uniform sampler2D secondTexture;
uniform sampler2D rectTexture;
void main(){
vec4 color = texture2D(rectTexture, gl_FragCoord.st);
gl_FragColor = color;
}
и вызовите glGetUniformLocationARB(programObject, "secondTexture");
, он просто возвращает -1, хотя он должен быть там. Информация журнала еще только говорит:
Информационный журнал:
Фрагмент шейдера был успешно скомпилирован для работы на оборудовании.
ОБНОВЛЕНИЕ 2:
Фактическая текстура копируется из буфера. Простая белая линия рисуется в меньшем окне просмотра и затем копируется в текстуру:
GL11.glViewport(0, 0, 256, 256);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glColor3f(1.0f, 1.0f, 1.0f);
GL11.glBegin(GL11.GL_LINES);
GL11.glVertex3f(0.0f, 0.0f, 0.0f);
GL11.glVertex3f(256.0f, 256.0f, 0.0f);
GL11.glEnd();
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_LUMINANCE, 0, 0, 256, 256, 0);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
Но, как я уже сказал, я не думаю, что текстура - это настоящая проблема, так как она хорошо отображается во втором квадре без моего собственного шейдера. Кроме того, не беспокойтесь о связывании; это единственная текстура в программе, которая привязывается только один раз в самом начале.
Вот мой код для рисования:
ARBShaderObjects.glUseProgramObjectARB(programObject);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0.0f, 1.0f);
GL11.glVertex3f(0.0f, 0.0f, 0.0f);
GL11.glTexCoord2f(1.0f, 1.0f);
GL11.glVertex3f(256.0f, 0.0f, 0.0f);
GL11.glTexCoord2f(1.0f, 0.0f);
GL11.glVertex3f(256.0f, 256.0f, 0.0f);
GL11.glTexCoord2f(0.0f, 0.0f);
GL11.glVertex3f(0.0f, 256.0f, 0.0f);
GL11.glEnd();
ARBShaderObjects.glUseProgramObjectARB(0);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0.0f, 1.0f);
GL11.glVertex3f(256.0f, 0.0f, 0.0f);
GL11.glTexCoord2f(1.0f, 1.0f);
GL11.glVertex3f(512.0f, 0.0f, 0.0f);
GL11.glTexCoord2f(1.0f, 0.0f);
GL11.glVertex3f(512.0f, 256.0f, 0.0f);
GL11.glTexCoord2f(0.0f, 0.0f);
GL11.glVertex3f(256.0f, 256.0f, 0.0f);
GL11.glEnd();