2014-09-27 2 views
0

Я рисую квад с текстурой 512 x 512, состоящей из 4 квадратов с 4 различными цветами (желтый, синий, зеленый, красный). Когда я смотрю на изображение, все это желтый, но текс Coords пространство от 0 до 1, и я совершенно уверен, что они отображаются правильно ... вот код:LWJGL Texture loading/mapping issue

private void loadTexture(String textureFile) { 
     TexHandle = glGenTextures(); 
     BufferedImage TextureBuffer = null; 
     try { 
      TextureBuffer = ImageIO.read(new File(textureFile)); 
     } catch (IOException ex) { 
      System.err.println("Error while reading the texture: " + textureFile); 
      System.exit(1); 
     } 
     Width = TextureBuffer.getWidth(); 
     Height = TextureBuffer.getHeight(); 
     AlphaChannel = TextureBuffer.getColorModel().hasAlpha(); 
     int pixel; 
     int[] pixels = TextureBuffer.getRGB(0, 0, Width, Height, null, 0, Width); 
     ByteBuffer Buffer = BufferUtils.createByteBuffer(Width * Height * 4); 
     for(int i = 0; i < Height; i++){ 
      for(int j = 0; j < Width; j++){ 
       pixel = pixels[i * Width + j]; 

       Buffer.put((byte)(pixel  & 0xff)); 
       Buffer.put((byte)((pixel >> 8) & 0xff)); 
       Buffer.put((byte)((pixel >> 16) & 0xff)); 

       if(AlphaChannel) 
        Buffer.put((byte)((pixel >> 24) & 0xff)); 
       else 
        Buffer.put((byte)0xff); 
      } 
     } 
     glBindTexture(GL_TEXTURE_2D, TexHandle); 

     Buffer.flip(); 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Width, Height, 0, GL_BGRA, GL_UNSIGNED_BYTE, Buffer); 

     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 

     glBindTexture(GL_TEXTURE_2D, 0); 
    } 

public void initOpenGL() { 
     glClearColor(0f, 0f, 0.4f, 1f); 

     glFrontFace(GL_CCW); 

     glCullFace(GL_BACK); 
     glEnable(GL_CULL_FACE); 

     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
     glEnable(GL_BLEND); 

     glDepthFunc(GL_LEQUAL); 
     glEnable(GL_DEPTH_TEST); 
     glEnable(GL_DEPTH_CLAMP); 

     glEnable(GL_TEXTURE_2D); 
    } 

главная:

while(!window.isClosing()){ 

     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     program.updateUniform("TextureIndex", 0); 
     glActiveTexture(GL_TEXTURE0 + 0); 
     glBindTexture(GL_TEXTURE_2D, TexHandle); 
     glBegin(GL_QUADS); 
     glNormal3f(0, 0, 0); 

     glTexCoord2f(0, 0); 
     glVertex3f(-.5f, -.5f, -2f); 

     glTexCoord2f(1, 0); 
     glVertex3f(.5f, -.5f, -2f); 

     glTexCoord2f(1, 1); 
     glVertex3f(.5f, .5f, -2f); 

     glTexCoord2f(0, 1); 
     glVertex3f(-.5f, .5f, -2f); 

     glEnd(); 

     window.update(); 
    } 

вершина:

layout(location = 0) in vec3 in_position; 
layout(location = 1) in vec2 in_texture_coord; 
layout(location = 2) in vec3 in_normal; 
out vec2 out_texture_coord; 

void main(){ 

    gl_Position = vec4(in_position, 1.0); 
    out_texture_coord = in_texture_coord; 

} 

фрагмент:

out vec4 out_color; 
    in vec2 in_texture_coord; // passed from the vertex shader 
    uniform sampler2D TextureIndex; 

    void main(){ 

     out_color = texture2D(TextureIndex, in_texture_coord); 

    } 
+0

Произошла одна вещь, связанная с вызовом 'glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)', чтобы очистить окно перед рисованием.Помимо этого, следующее предположение будет проблемой с вершинным шейдером. –

+0

Я добавил функцию, но я все еще получаю ошибку. Также я добавил вершинный шейдер – Mk3Y

ответ

0

Проблема была в названии переменной: в VS у меня есть «out vec3 out_tex_coord», а в FS у меня есть «in vec3 in_tex_coord» и потому, что они не соответствовали UVs текстуры, где всегда (0,0).

2

Опубликованный код смешивает устаревшую функциональность OpenGL с современной функциональностью OpenGL неподдерживаемыми способами. Код спецификации вершина использует старый фиксированная функция атрибуты стиля:

glNormal3f(0, 0, 0); 
glTexCoord2f(0, 0); 
glVertex3f(-.5f, -.5f, -2f); 

Хотя вершинный шейдер ожидает общая вершина атрибуты:

layout(location = 0) in vec3 in_position; 
layout(location = 1) in vec2 in_texture_coord; 
layout(location = 2) in vec3 in_normal; 

Там нет прямого соответствия между ними. Спецификация имеет некоторый язык, говорящий, что общий атрибут 0 сопоставляется с устаревшей вершинной позицией, но даже это не всегда надежно работает со всеми драйверами. И, конечно, недействительно предположить, что, например, значения, указанные в glTexCoord2f(), будут отображаться в атрибуте с (location = 1) в вершинном шейдере.

Есть два основных способа исправить, что:

  1. Изменить код шейдера для работы с унаследованными вызовов, используемых для определения данных вершин. Это делается путем удаления in объявления переменных в коде шейдера вершин, и используя предопределенные переменные для доступа к значениям атрибутов:

    gl_Vertex для положения вершины

    gl_MultiTexCoord0 для текстурных координат

    gl_Normal для нормального

  2. Использовать функции API для установки значений общих атрибутов вершин вместо атрибутов фиксированной функции. Для фрагмента кода выше, и соответствующие места из кода вершинного шейдера:

    glVertexAttrib3f(2, 0.0f, 0.0f, 0.0f); 
    glVertexAttrib2f(1, 0.0f, 0.0f); 
    glVertexAttrib3f(0, -0.5f, -0.5f, -2.0f); 
    

Если вы готовы перейти к современной OpenGL, вариант 2 будет лучше направление. Одним из следующих шагов этого пути будет использование объектов-вершинных буферов (VBO) для указания данных вершин вместо вызовов немедленного режима в вашем текущем коде.

+0

Спасибо за помощь, но ... Я реализовал исправление # 2, но у меня все еще есть полностью желтый прямоугольник. Я предполагаю, что моя проблема заключается в инициализации загрузчика текстур/openGL. Этот код, над которым я работаю, - это старое приложение, которое я сделал несколько лет назад, и теперь я пытаюсь его обновить и добавить некоторые функции – Mk3Y