Каковы возможные причины, по которым текстуры не отображаются в GLSL? - PullRequest
0 голосов
/ 25 июня 2010

Я узнал о том, как использовать текстуры с 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();

Ответы [ 3 ]

1 голос
/ 08 февраля 2011

Вы предоставляете координаты текстуры, но не используете их в шейдере.Вместо этого вы используете gl_FragCoord, который дает координаты окна:

texture2D(rectTexture, gl_FragCoord.st)

Вы должны использовать gl_MultiTexCoord0.xy .

1 голос
/ 03 июля 2013

Поскольку вы используете GL_TEXTURE_2D для хранения rectTexture, сэмплер будет ожидать нормализованных координат текстуры (т. Е. [0.0, 1.0]).

Поэтому ваш шейдер должен быть изменен на:

uniform vec2 invTextureSize; // contains [1.0 / w, 1.0 / h];
uniform sampler2D rectTexture;

void main() {
  vec4 color = texture2D( rectTexture, gl_FragCoord.st * invTextureSize.xy );
  gl_FragColor = color;
}

Кроме того, вам необходимо правильно настроить GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER, GL_TEXTURE_WRAP_S и GL_TEXTURE_WRAP_T для этого объекта текстуры.

Если нет, большинство драйверов opengl предоставят rgba = [0], 0, 0, 0цвет шейдера.

См. ссылку glTexParameter

Следующая конфигурация работает для большинства объектов GL_TEXTURE_2D

glTexParameter( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameter( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameter( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameter( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

Надеюсь, это поможет.

0 голосов
/ 25 июня 2010

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

...