拉伸的LWJGL 3D纹理

时间:2018-08-01 04:50:11

标签: lwjgl

我正在使用LWJGL制作3D游戏,但是我的渲染系统有问题。每当我渲染模型时,纹理就会被拉伸/扭曲。在其他3D查看器中渲染时,所有模型均显示良好。 .obj加载程序:

public class OBJLoader {

public static RawModel loadObjModel(String fileName, Loader loader) {
    FileReader fr = null;
    try {
        fr = new FileReader(new File("res/" + fileName + ".obj"));
    } catch (FileNotFoundException e) {
        System.err.println("Couldn't load file!");
        e.printStackTrace();
    }
    BufferedReader reader = new BufferedReader(fr);
    String line;
    List<Vector3f> vertices = new ArrayList<Vector3f>();
    List<Vector2f> textures = new ArrayList<Vector2f>();
    List<Vector3f> normals = new ArrayList<Vector3f>();
    List<Integer> indices = new ArrayList<Integer>();
    float[] verticesArray = null;
    float[] normalsArray = null;
    float[] textureArray = null;
    int[] indicesArray = null;
    try {

        while (true) {
            line = reader.readLine();
            String[] currentLine = line.split(" ");
            if (line.startsWith("v ")) {
                Vector3f vertex = new Vector3f(Float.parseFloat(currentLine[1]),
                        Float.parseFloat(currentLine[2]), Float.parseFloat(currentLine[3]));
                vertices.add(vertex);
            } else if (line.startsWith("vt ")) {
                Vector2f texture = new Vector2f(Float.parseFloat(currentLine[1]),
                        Float.parseFloat(currentLine[2]));
                textures.add(texture);
            } else if (line.startsWith("vn ")) {
                Vector3f normal = new Vector3f(Float.parseFloat(currentLine[1]),
                        Float.parseFloat(currentLine[2]), Float.parseFloat(currentLine[3]));
                normals.add(normal);
            } else if (line.startsWith("f ")) {
                textureArray = new float[vertices.size() * 2];
                normalsArray = new float[vertices.size() * 3];
                break;
            }
        }

        while (line != null) {
            if (!line.startsWith("f ")) {
                line = reader.readLine();
                continue;
            }
            String[] currentLine = line.split(" ");
            String[] vertex1 = currentLine[1].split("/");
            String[] vertex2 = currentLine[2].split("/");
            String[] vertex3 = currentLine[3].split("/");

            processVertex(vertex1,indices,textures,normals,textureArray,normalsArray);
            processVertex(vertex2,indices,textures,normals,textureArray,normalsArray);
            processVertex(vertex3,indices,textures,normals,textureArray,normalsArray);
            line = reader.readLine();
        }
        reader.close();

    } catch (Exception e) {
        e.printStackTrace();
    }

    verticesArray = new float[vertices.size()*3];
    indicesArray = new int[indices.size()];

    int vertexPointer = 0;
    for(Vector3f vertex:vertices){
        verticesArray[vertexPointer++] = vertex.x;
        verticesArray[vertexPointer++] = vertex.y;
        verticesArray[vertexPointer++] = vertex.z;
    }

    for(int i=0;i<indices.size();i++){
        indicesArray[i] = indices.get(i);
    }
    return loader.loadToVAO(verticesArray, textureArray, normalsArray, indicesArray);

}

private static void processVertex(String[] vertexData, List<Integer> indices,
        List<Vector2f> textures, List<Vector3f> normals, float[] textureArray,
        float[] normalsArray) {
    int currentVertexPointer = Integer.parseInt(vertexData[0]) - 1;
    indices.add(currentVertexPointer);
    Vector2f currentTex = textures.get(Integer.parseInt(vertexData[1])-1);
    textureArray[currentVertexPointer*2] = currentTex.x;
    textureArray[currentVertexPointer*2+1] = 1 - currentTex.y;
    Vector3f currentNorm = normals.get(Integer.parseInt(vertexData[2])-1);
    normalsArray[currentVertexPointer*3] = currentNorm.x;
    normalsArray[currentVertexPointer*3+1] = currentNorm.y;
    normalsArray[currentVertexPointer*3+2] = currentNorm.z; 
}

}

渲染器:

public class Loader {

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

public RawModel loadToVAO(float[] positions,float[] textureCoords,float[] normals,int[] indices){
    int vaoID = createVAO();
    bindIndicesBuffer(indices);
    storeDataInAttributeList(0,3,positions);
    storeDataInAttributeList(1,2,textureCoords);
    storeDataInAttributeList(2,3,normals);
    unbindVAO();
    return new RawModel(vaoID,indices.length);
}

public RawModel loadToVAO(float[] positions, int dimensions) {
    int vaoID = createVAO();
    this.storeDataInAttributeList(0, dimensions, positions);
    unbindVAO();
    return new RawModel(vaoID, positions.length/dimensions);
}

public int loadTexture(String fileName) {
    Texture texture = null;
    try {
        texture = TextureLoader.getTexture("PNG",
                new FileInputStream("res/" + fileName + ".png"));
        GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
        GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, -0.4f);
    } catch (Exception e) {
        e.printStackTrace();
        System.err.println("Tried to load texture " + fileName + ".png , didn't work");
        System.exit(-1);
    }
    textures.add(texture.getTextureID());
    return texture.getTextureID();
}

public void cleanUp(){
    for(int vao:vaos){
        GL30.glDeleteVertexArrays(vao);
    }
    for(int vbo:vbos){
        GL15.glDeleteBuffers(vbo);
    }
    for(int texture:textures){
        GL11.glDeleteTextures(texture);
    }
}

public int loadCubeMap(String[] textureFiles)  {
    int texID = GL11.glGenTextures();
    GL13.glActiveTexture(GL13.GL_TEXTURE0);
    GL11.glBindTexture(GL13.GL_TEXTURE_CUBE_MAP, texID);

    for(int i=0;i<textureFiles.length;i++) {
        TextureData data = decodeTextureFile("res/" + textureFiles[i] + ".png");
        GL11.glTexImage2D(GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 
        GL11.GL_RGBA, data.getWidth(), data.getHeight(), 0, 
        GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, data.getBuffer());
    }
    GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
    GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
    GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
    GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
    textures.add(texID);

    return texID;
}

private TextureData decodeTextureFile(String fileName) {
    int width = 0;
    int height = 0;
    ByteBuffer buffer = null;
    try {
        FileInputStream in = new FileInputStream(fileName);
        PNGDecoder decoder = new PNGDecoder(in);
        width = decoder.getWidth();
        height = decoder.getHeight();
        buffer = ByteBuffer.allocateDirect(4 * width * height);
        decoder.decode(buffer, width * 4, org.newdawn.slick.opengl.PNGDecoder.RGBA);
        buffer.flip();
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
        System.err.println("Tried to load texture " + fileName + ", didn't work");
        System.exit(-1);
    }
    return new TextureData(buffer, width, height);
}

private int createVAO(){
    int vaoID = GL30.glGenVertexArrays();
    vaos.add(vaoID);
    GL30.glBindVertexArray(vaoID);
    return vaoID;
}

private void storeDataInAttributeList(int attributeNumber, int coordinateSize,float[] data){
    int vboID = GL15.glGenBuffers();
    vbos.add(vboID);
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
    FloatBuffer buffer = storeDataInFloatBuffer(data);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
    GL20.glVertexAttribPointer(attributeNumber,coordinateSize,GL11.GL_FLOAT,false,0,0);
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}

private void unbindVAO(){
    GL30.glBindVertexArray(0);
}

private void bindIndicesBuffer(int[] indices){
    int vboID = GL15.glGenBuffers();
    vbos.add(vboID);
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboID);
    IntBuffer buffer = storeDataInIntBuffer(indices);
    GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
}

private IntBuffer storeDataInIntBuffer(int[] data){
    IntBuffer buffer = BufferUtils.createIntBuffer(data.length);
    buffer.put(data);
    buffer.flip();
    return buffer;
}

private FloatBuffer storeDataInFloatBuffer(float[] data){
    FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
    buffer.put(data);
    buffer.flip();
    return buffer;
}
}

0 个答案:

没有答案