我是OpenGL的新手。我正在使用JOGL。
我下载了这个model。它有一堆纹理。我正在尝试在这里申请“truck_color-blue.jpg”,但我不确定我做得对。这就是我所看到的:
基本上,我正在做的是记录所有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);
我怀疑我没有正确地将纹理坐标与顶点匹配。该模型表示它是UV映射的。这是否意味着我需要以不同的方式做纹理?
我的代码来读取.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));
}
}
类多边形表示类似f 1/2/3 4/5/6 7/8/9
的行。
public class Polygon { private List faces = 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);
}
}
}
答案 0 :(得分:0)
在OpenGL中,纹理原点位于左下方而不是左上方。这可能会弄乱你的纹理。如果这是问题,一个简单的解决方法是从1:glTexCoord2f(texCoords.x, 1.0f - texCoords.y)
中减去y纹理坐标。 (这与垂直翻转纹理相同。)