使用lwjgl3时的纹理间隙问题

o3imoua4  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(318)


我有一个问题,差距出现在纹理。一切都是好的图像,我已经用其他图像来测试,即使这样这些差距出现。我正在使用lwjgl 3,我正在用java编写:
应用程序.java

import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

import org.lwjgl.BufferUtils;

public class App {
    private int width = 800;
    private int height = 600;
    private long window;

    private List<Integer> vbos = new ArrayList<Integer>();
    private List<Integer> attributes = new ArrayList<Integer>();

    private float fov = 45;
    private float aspect = (float) width / (float) height;
    private float near = 0.1f;
    private float far = 1000.0f;

    private float deltaTime = 0;
    private float lastTime = 0;

    public App() {
        glfwInit();
        glfwWindowHint(GLFW_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
        glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);

        window = glfwCreateWindow(width, height, "OpenGL", 0, 0);

        if(window == 0) {
            glfwTerminate();
            System.err.println("Couldn't create GLFW window");
            System.exit(-1);
        }

        glfwMakeContextCurrent(window);
        createCapabilities();
        glfwShowWindow(window);

        float[] vertices = {
             50f, 0.0f,  50f,
             50f, 0.0f, -50f,
            -50f, 0.0f, -50f,
            -50f, 0.0f,  50f
        };

        float[] textureCoordinates = {
            1.0f, 1.0f,
            1.0f, 0.0f,
            0.0f, 0.0f,
            0.0f, 1.0f 
        };

        int indices[] = {
            0, 1, 3,
            1, 2, 3 
        };

        int vertexShader = processShader("shaders/standard.vt.glsl", GL_VERTEX_SHADER);
        int fragmentShader = processShader("shaders/standard.fs.glsl", GL_FRAGMENT_SHADER);

        int program = glCreateProgram();
        glAttachShader(program, vertexShader);
        glAttachShader(program, fragmentShader);
        glLinkProgram(program);

        // Texture texture = loadTexture("res/textures/checker-gray.png");

        String texturePath = "res/textures/checker-gray.png";
        int textureWidth = 0;
        int textureHeight = 0;
        ByteBuffer textureData = null;

        try {
            BufferedImage image = ImageIO.read(new File(texturePath));

            textureWidth = image.getWidth();
            textureHeight = image.getHeight();
            int[] pixels = new int[textureWidth * textureHeight];

            image.getRGB(0, 0, textureWidth, textureHeight, pixels, 0, textureWidth);

            textureData = BufferUtils.createByteBuffer(textureWidth * textureHeight * 4);

            for (int y = textureHeight - 1; y > 0; y--) {
                for (int x = 0; x < textureWidth; x++) {
                    int pixel = pixels[y * textureWidth + x];

                    textureData.put((byte) ((pixel >> 16) & 0xFF));
                    textureData.put((byte) ((pixel >> 8) & 0xFF));
                    textureData.put((byte) (pixel & 0xFF));
                    textureData.put((byte) ((pixel >> 24) & 0xFF));
                }
            }

            textureData.flip();
        } catch (IOException e) {
            System.err.println("ERROR: Couldn't load the image " + texturePath);
            e.printStackTrace();
            System.exit(-1);
        }

        int texture_0 = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, texture_0);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        if(textureData != null) {
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
            glGenerateMipmap(GL_TEXTURE_2D);
        }

        int vao = glGenVertexArrays();
        glBindVertexArray(vao);

        setIndices(indices);
        setAttribute(0, 3, vertices);
        setAttribute(1, 2, textureCoordinates);

        glBindVertexArray(0);

        glUseProgram(program);
        // Texture uniforms
        glUniform1i(glGetUniformLocation(program, "texture0"), 0);
        glUniform2f(glGetUniformLocation(program, "textureScale"), 10, 10);
        glUseProgram(0);

        float[] cameraPosition = {0, -1, 0};
        float[] position = { 0, 0, 0 };

        while(!glfwWindowShouldClose(window)){
            glClearColor(0.1f, 0.15f, 0.2f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);

            float currentTime = (float) glfwGetTime();
            deltaTime = currentTime - lastTime;
            lastTime = currentTime;

            cameraPosition[2] += 1.0f * deltaTime;

            float[] projectionMatrix = perspective(fov, aspect, near, far);
            float[] viewMatrix = translate(cameraPosition);
            float[] transformationMatrix = translate(position);

            glUseProgram(program);
            glUniformMatrix4fv(glGetUniformLocation(program, "projectionMatrix"), true, projectionMatrix);
            glUniformMatrix4fv(glGetUniformLocation(program, "transformationMatrix"), true, transformationMatrix);
            glUniformMatrix4fv(glGetUniformLocation(program, "viewMatrix"), true, viewMatrix);
            glUseProgram(0);

            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, texture_0);

            glUseProgram(program);

            glBindVertexArray(vao);
            enableAttributes();
            glDrawElements(GL_TRIANGLES, indices.length, GL_UNSIGNED_INT, 0);
            disableAttributes();
            glBindVertexArray(0);

            glUseProgram(0);

            glfwSwapBuffers(window);
            glfwPollEvents();
        }

        for(int vbo : vbos) {
            glDeleteBuffers(vbo);
        }

        glDeleteVertexArrays(vao);

        glDetachShader(program, vertexShader);
        glDetachShader(program, fragmentShader);
        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);
        glDeleteProgram(program);

        glfwTerminate();
        System.exit(0);
    }

    public FloatBuffer createBufferf(float[] data){
        FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
        buffer.put(data);
        buffer.flip();

        return buffer;
    }

    public IntBuffer createBufferi(int[] data) {
        IntBuffer buffer = BufferUtils.createIntBuffer(data.length);
        buffer.put(data);
        buffer.flip();

        return buffer;
    }

    public void setAttribute(int index, int size, float[] data) {
        int vbo = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, createBufferf(data), GL_STATIC_DRAW);
        glVertexAttribPointer(index, size, GL_FLOAT, false, 0, 0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        vbos.add(vbo);
        attributes.add(index);
    }

    public void setIndices(int[] data) {
        int ibo = glGenBuffers();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, createBufferi(data), GL_STATIC_DRAW);
        vbos.add(ibo);
    }

    public void disableAttributes() {
        for (int attributeIndex : attributes) {
            glDisableVertexAttribArray(attributeIndex);
        }
    }

    public void enableAttributes() {
        for (int attributeIndex : attributes) {
            glEnableVertexAttribArray(attributeIndex);
        }
    }

    private int processShader(String path, int type) {
        String typeString;
        String code = loadShader(path);

        switch (type) {
            case GL_FRAGMENT_SHADER:
                typeString = "FRAGMENT_SHADER";
                break;
            case GL_VERTEX_SHADER:
            default:
                typeString = "VERTEX_SHADER";
        }

        int shader = glCreateShader(type);

        glShaderSource(shader, code);
        glCompileShader(shader);

        if (glGetShaderi(shader, GL_COMPILE_STATUS) == GL_FALSE) {
            String info = glGetShaderInfoLog(shader, 1024);
            System.err.println("ERROR::" + typeString + "\n" + info);
            System.exit(-1);
        }

        return shader;
    }

    private String loadShader(String path) {
        StringBuffer buffer = new StringBuffer();

        try {
            BufferedReader reader = new BufferedReader(new FileReader(path));
            String line;

            while ((line = reader.readLine()) != null) {
                buffer.append(line).append("\n");
            }

            reader.close();
        } catch (FileNotFoundException e) {
            System.err.println("ERROR: Shader " + path + " not found");
            e.printStackTrace();
            System.exit(-1);
        } catch (IOException e) {
            System.err.println("ERROR: Couldn't load the file " + path);
            e.printStackTrace();
            System.exit(-1);
        }

        return buffer.toString();
    }

    public float[] perspective(float fov, float aspect, float zNear, float zFar) {
        float halfTanFOV = (float) Math.tan(Math.toRadians(fov) / 2.0f);
        float zRange = zFar - zNear;

        float m00 = 1.0f / (aspect * halfTanFOV);
        float m11 = 1.0f / halfTanFOV;
        float m22 = -((zFar + zNear) / zRange);
        float m32 = -((2.0f * zFar * zNear) / zRange);
        float m23 = -1.0f;

        return new float[] {
            m00, 0.0f,  0.0f, 0.0f, 
            0.0f, m11,  0.0f, 0.0f, 
            0.0f, 0.0f, m22,  m32, 
            0.0f, 0.0f, m23,  0.0f 
        };
    }

    public float[] translate(float[] p) {
        return new float[] {
            1.0f, 0.0f, 0.0f, p[0], 
            0.0f, 1.0f, 0.0f, p[1], 
            0.0f, 0.0f, 1.0f, p[2], 
            0.0f, 0.0f, 0.0f, 1.0f 
        };
    }

    public static void main(String[] args) throws Exception {
        new App();
    }
}

标准.vt.glsl


# version 400 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 uv;

out vec2 textureCoordinate;

uniform vec2 textureScale;

uniform mat4 transformationMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;

void main(){
    gl_Position = projectionMatrix * viewMatrix * transformationMatrix * vec4(position, 1.0);

    textureCoordinate = uv * textureScale;
}

标准fs.glsl


# version 400 core

in vec2 textureCoordinate;

out vec4 FragColor;

uniform sampler2D texture0;

void main(){
    FragColor = texture(texture0, textureCoordinate);
}

拜托,有人能帮我吗?有人经历过吗?或者你知道怎么解决这个问题吗?

5jdjgkvh

5jdjgkvh1#

我发现了问题。就在那一行:

for (int y = textureHeight - 1; y > 0; y--) {

正确的做法是:

for (int y = textureHeight - 1; y >= 0; y--) {

最后一行像素没有实现,这在纹理中生成了黑线。

相关问题