2017-01-07 59 views
0

我试图在正交模式下执行2D图形。该代码加载一张猫的图片和两个简单​​的着色器,它们只是通过它们的输入,没有修改。我希望程序在屏幕中间显示猫的图片(或至少其中的一部分),而不会有任何旋转或偏斜。使用着色器生成倾斜图像的LWJGL纹理

该计划成功执行,但我不明白,为什么结果是这样的:

Screenshot

一个OpenGL大师可以快速发现问题,但我不能找到它。我感觉这个问题可能出现在“为顶点和纹理坐标创建缓冲区”部分,但一切看起来都不错。

猫图像:

cat

顶点着色器:

#version 150 core 

in vec4 in_Position; 
in vec2 in_TextureCoord; 

out vec2 pass_TextureCoord; 

void main(void) { 
    gl_Position = in_Position; 

    pass_TextureCoord = in_TextureCoord; 
} 

像素着色器:

#version 150 core 

uniform sampler2D texture_diffuse; 
in vec2 pass_TextureCoord; 
out vec4 out_Color; 

void main(void) { 
    out_Color = texture(texture_diffuse, pass_TextureCoord); 
} 

的Java(LWJGL)代码:

package lwjgl_test1; 

import java.awt.image.BufferedImage; 
import java.io.*; 
import java.nio.*; 

import javax.imageio.ImageIO; 

import org.lwjgl.*; 
import org.lwjgl.opengl.*; 

import static org.lwjgl.glfw.GLFW.*; 
import java.util.concurrent.TimeUnit; 
import static org.lwjgl.opengl.GL11.*; 


public class Main { 
    public static void main(String[] args) { 
     try { 
      if (!glfwInit()) { 
       throw(new Exception("Can't init glfw.")); 
      } 

      /* 
      * Create Window 
      */ 
      glfwWindowHint(GLFW_RESIZABLE, 0); 
      long windowGlID = glfwCreateWindow(1024, 768, "Example OpenGL App", 0, 0); 

      glfwSetWindowPos(windowGlID, 50, 50); 
      glfwMakeContextCurrent(windowGlID); 
      glfwShowWindow(windowGlID); 

      /* 
      * Initialize OpenGL 
      */ 
      GL.createCapabilities(); 

      glMatrixMode(GL_PROJECTION); 
      glLoadIdentity(); 
      glOrtho(0, 1024, 768, 0, 0, 1); 
      glMatrixMode(GL_MODELVIEW); 

      /* 
      * Load texture 
      */ 
      int cat = loadTexture("cat.png"); 

      /* 
      * Load shaders 
      */ 
      int vertexShader = loadShader("vertex_shader.txt", GL20.GL_VERTEX_SHADER); 
      int pixelShader = loadShader("pixel_shader.txt", GL20.GL_FRAGMENT_SHADER); 

      int pId = GL20.glCreateProgram(); 
      GL20.glAttachShader(pId, vertexShader); 
      GL20.glAttachShader(pId, pixelShader); 

      // Position information will be attribute 0 
      GL20.glBindAttribLocation(pId, 0, "in_Position"); 
      // Textute information will be attribute 1 
      GL20.glBindAttribLocation(pId, 1, "in_TextureCoord"); 

      GL20.glLinkProgram(pId); 
      GL20.glValidateProgram(pId); 

      exitOnGLError("Compiling shaders failed."); 

      /* 
      * Create buffer for vertex and texture coordinates 
      */ 
      float size = 120.0f; 

      FloatBuffer vertex_data = BufferUtils.createFloatBuffer(20); 
      vertex_data.put(new float[] { -size, -size, 0f, 0f, 0f }); // (Vx, Vy, Vz, Tx, Ty) 
      vertex_data.put(new float[] { size, -size, 0f, 0f, 1f }); 
      vertex_data.put(new float[] { size, size, 0f, 1f, 1f }); 
      vertex_data.put(new float[] { -size, size, 0f, 1f, 0f }); 
      vertex_data.flip(); 

      int vbo_vertex_handle = GL15.glGenBuffers(); 
      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo_vertex_handle); 
      GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertex_data, GL15.GL_STATIC_DRAW); 

      GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 2 * 4, 0); // mark vertex coordinates 
      GL20.glVertexAttribPointer(1, 2, GL11.GL_FLOAT, false, 3 * 4, 3 * 4); // mark texture coordinates 

      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); 
      GL30.glBindVertexArray(0); 

      exitOnGLError("Creating buffers failed."); 

      /* 
      * Main rendering loop 
      */ 
      while(true) { 
       /* 
       * Clear screen 
       */ 
       glClearColor(0.0f, 1.0f, 1.0f, 0.0f); 
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

       /* 
       * Apply shader program 
       */ 
       GL20.glUseProgram(pId); 

       // Bind the texture 
       GL13.glActiveTexture(GL13.GL_TEXTURE0); 
       GL11.glBindTexture(GL11.GL_TEXTURE_2D, cat); 

       /* 
       * Draw (use buffers) 
       */ 
       GL20.glEnableVertexAttribArray(0); 
       GL20.glEnableVertexAttribArray(1); 

       GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo_vertex_handle); 
       GL11.glDrawArrays(GL11.GL_QUADS, 0, 4); // Draw an entity with 4 vertices 
       GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); 

       exitOnGLError("Draw failed."); 

       GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); 
       GL20.glUseProgram(0); // deselect 

       /* 
       * Swap buffers 
       */ 
       glfwSwapBuffers(windowGlID); 

       /* 
       * Events 
       */ 
       glfwPollEvents(); 
       if (glfwWindowShouldClose(windowGlID)) { 
        break; 
       } 

       TimeUnit.MILLISECONDS.sleep(10); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    private static int loadTexture(String path) throws Exception { 
     int[] pixels = null; 
     BufferedImage image = null; 

     image = ImageIO.read(new FileInputStream(path)); 
     int width = image.getWidth(); 
     int height = image.getHeight(); 
     pixels = new int[width * height]; 
     image.getRGB(0, 0, width, height, pixels, 0, width); 

     int[] data = new int[width * height]; 
     for (int i = 0; i < width * height; i++) { 
      int a = (pixels[i] & 0xff000000) >> 24; 
      int r = (pixels[i] & 0xff0000) >> 16; 
      int g = (pixels[i] & 0xff00) >> 8; 
      int b = (pixels[i] & 0xff); 

      data[i] = a << 24 | b << 16 | g << 8 | r; 
     } 

     IntBuffer intBuffer1 = ByteBuffer.allocateDirect(data.length << 2).order(ByteOrder.nativeOrder()).asIntBuffer(); 
     intBuffer1.put(data).flip(); 

     int result = glGenTextures(); 
     glBindTexture(GL_TEXTURE_2D, result); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, intBuffer1); 
     glBindTexture(GL_TEXTURE_2D, 0); 

     exitOnGLError("Loading texture '"+ path +"' failed."); 

     return result; 
    } 

    private static int loadShader(String filename, int type) { 
     StringBuilder shaderSource = new StringBuilder(); 
     int shaderID = 0; 

     try { 
      BufferedReader reader = new BufferedReader(new FileReader(filename)); 
      String line; 
      while ((line = reader.readLine()) != null) { 
       shaderSource.append(line).append("\n"); 
      } 
      reader.close(); 
     } catch (IOException e) { 
      System.err.println("Could not read file."); 
      e.printStackTrace(); 
      System.exit(-1); 
     } 

     shaderID = GL20.glCreateShader(type); 
     GL20.glShaderSource(shaderID, shaderSource); 
     GL20.glCompileShader(shaderID); 

     if (GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) { 
      System.err.println("Could not compile shader."); 
      System.exit(-1); 
     } 

     return shaderID; 
    } 

    private static void exitOnGLError(String errorMessage) throws Exception { 
     int errorValue = GL11.glGetError(); 

     if (errorValue != GL11.GL_NO_ERROR) { 
      throw new Exception(errorMessage); 
     } 
    } 
} 

回答

1

的问题在于在此行的步幅参数:

GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 2 * 4, 0); 
GL20.glVertexAttribPointer(1, 2, GL11.GL_FLOAT, false, 3 * 4, 3 * 4); 

步幅告诉OpenGL如何开多少字节彼此开始连续两个条目是。既然你每个顶点使用5个浮点数,这两条线都必须是5 * 4

GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 5 * 4, 0); 
GL20.glVertexAttribPointer(1, 2, GL11.GL_FLOAT, false, 5 * 4, 3 * 4); 
+0

啊谢谢!现在我不得不减小四边形的尺寸,但猫至少没有减半。我想还有其他问题,但我会找到那些。 –