OpenGL: я неправильно это текстурирую? - PullRequest
1 голос
/ 25 сентября 2010

Я новичок в OpenGL.Я использую JOGL.

Я скачал эту модель .У него есть куча текстур.Я пытаюсь применить "truck_color-blue.jpg" здесь, но я не уверен, что делаю это правильно.Вот что я вижу:

Side by side: by texture and the site's demo

По сути, я делаю запись всех записей vt, v и vn, затем с помощьюf строк для индексации в них.Это код, который делает вызов glTexCoord*():

           if (facePoint.textureIndex != null) {
                Vector2f texCoords = getTexture(facePoint.textureIndex);
                gl.glTexCoord2f(texCoords.x, texCoords.y);
            }

            // ...

            Point3f vertex = getVertex(facePoint.vertexIndex);
            gl.glVertex3f(vertex.x, vertex.y, vertex.z);

Я подозреваю, что не правильно сопоставляю координаты текстуры с вершинами.Модель говорит, что это УФ-карта.Означает ли это, что мне нужно делать текстуры по-другому?

Мой код для чтения файлов .obj:

public class ObjModel extends WorldEntity {

    // ...

    @Override
    protected void buildDrawList() {
        startDrawList();

        for (Polygon poly : polygons) {

            if (poly.getFaces().size() == 4) {
                gl.glBegin(GL2.GL_QUADS);
            } else {
                gl.glBegin(GL2.GL_POLYGON);
            }

            for (FacePoint facePoint : poly.getFaces()) {
                if (facePoint.vertexIndex == null) {
                    throw new RuntimeException("Why was there a face with no vertex?");
                }

                if (facePoint.textureIndex != null) {
                    Vector2f texCoords = getTexture(facePoint.textureIndex);
                    gl.glTexCoord2f(texCoords.x, texCoords.y);
                }

                if (facePoint.normalIndex != null) { 
                    // why use both Vector3f and Point3f?
                    Vector3f normal = getNormal(facePoint.normalIndex);
                    gl.glNormal3f(normal.x, normal.y, normal.z);
                }

                Point3f vertex = getVertex(facePoint.vertexIndex);
                gl.glVertex3f(vertex.x, vertex.y, vertex.z);
            }
            gl.glEnd();
        }

        endDrawList();
    }

    private Point3f getVertex(int index) {
        if (index >= 0) {
            // -1 is necessary b/c .obj is 1 indexed, but vertices is 0 indexed.
            return vertices.get(index - 1);
        } else {
            return vertices.get(vertices.size() + index);
        }
    }

    private Vector3f getNormal(int index) {
        if (index >= 0) {
            return normals.get(index - 1);
        } else {
            return normals.get(normals.size() + index);
        }
    }

    private Vector2f getTexture(int index) {
        if (index >= 0) {
            return textures.get(index - 1);
        } else {
            return textures.get(textures.size() + index);
        }
    }

    private void readFile(String fileName) {
        try {
            BufferedReader input = new BufferedReader(new FileReader(fileName));
            try {
                String currLine = null;
                while ((currLine = input.readLine()) != null) {

                    int indVn = currLine.indexOf("vn ");
                    if (indVn != -1) {
                        readNormal(currLine);
                        continue;
                    }

                    int indV = currLine.indexOf("v ");
                    if (indV != -1) {
                        readVertex(currLine);
                        continue;
                    }

                    int indF = currLine.indexOf("f ");
                    if (indF != -1) {
                        readPolygon(currLine);
                        continue;
                    }

                    int indVt = currLine.indexOf("vt ");
                    if (indVt != -1) {
                        readTexture(currLine);
                        continue;
                    }
                }
            } finally {
                input.close();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private void readVertex(String newLine) {
        String pieces[] = newLine.split("\\s+");
        Point3f vertex = new Point3f(Float.parseFloat(pieces[1]), Float.parseFloat(pieces[2]), Float.parseFloat(pieces[3]));
        vertices.add(vertex);
    }

    private void readNormal(String newLine) {
        String pieces[] = newLine.split("\\s+");
        Vector3f norm = new Vector3f(Float.parseFloat(pieces[1]), Float.parseFloat(pieces[2]), Float.parseFloat(pieces[3]));
        normals.add(norm);
    }

    private void readTexture(String newLine) {
        String pieces[] = newLine.split("\\s+");
        Vector2f tex = new Vector2f(Float.parseFloat(pieces[1]), Float.parseFloat(pieces[2]));
        textures.add(tex);
    }

    private void readPolygon(String newLine) {
        polygons.add(new Polygon(newLine));
    }
}

Класс Polygon представляет строку типа f 1/2/3 4/5/6 7/8/9.

открытый класс Polygon {private List face = new ArrayList ();

public Polygon(String line) {
    if (line.charAt(0) != 'f') {
        throw new IllegalArgumentException(String.format("Line must be a face definition, but was: '%s'", line));
    }

    String[] facePointDefs = line.split("\\s+");

    // ignore the first piece - it will be "f ". 
    for (int i = 1; i < facePointDefs.length; i++) {
        faces.add(new FacePoint(facePointDefs[i]));
    }
}

public List<FacePoint> getFaces() {
    return Collections.unmodifiableList(faces);
}

}

класс FacePoint представляет точку лица, например 21/342/231.

public class FacePoint {

    private static final String FACE_POINT_REGEX = "^(\\d+)\\/(\\d+)?(\\/(\\d+))?$";

    public Integer vertexIndex;
    public Integer textureIndex;
    public Integer normalIndex;

    public FacePoint(String facePointDef) {
        Matcher matcher = Pattern.compile(FACE_POINT_REGEX).matcher(facePointDef);

        if (!matcher.find()) {
            throw new IllegalArgumentException(String.format("facePointDef is invalid: '%s'", facePointDef));
        }

        String vertexMatch = matcher.group(1);
        if (vertexMatch == null) {
            throw new IllegalArgumentException(String.format("The face point definition didn't contain a vertex: '%s'",
                    facePointDef));
        }
        vertexIndex = Integer.parseInt(vertexMatch);

        String texMatch = matcher.group(2);
        if (texMatch != null) {
            textureIndex = Integer.parseInt(texMatch);
        }

        String normalMatch = matcher.group(4);
        if (normalMatch != null) {
            normalIndex = Integer.parseInt(normalMatch);
        }
    }
}

1 Ответ

0 голосов
/ 25 сентября 2010

В OpenGL источник текстуры находится внизу слева, а не слева вверху. Это может испортить ваши текстуры. Если это проблема, простое решение - вычесть координату текстуры y из 1: glTexCoord2f(texCoords.x, 1.0f - texCoords.y). (Это то же самое, что перевернуть текстуру по вертикали.)

...