# Rendern von 3D Obj



## !GH!Budd (15. Apr 2014)

Vielleicht passt es hier auch besser rein.
Bei den mobilen Geräten gab's bisher keine Antwort. (Sorry Mods...)

Hallo zusammen!

Ich hab hier mal dann und wann mitgelesen und auch schon den einen oder anderen Post geschrieben, allergdings noch kein eigenes Problem gehabt. Ich wage mich in die Welt der OpenGL-Programmierung unter Android. Vielleicht ist es hier dafür nicht der richtige Bereich, wir werden sehen.

Ich habe aus einem Buch ein Stück Quelltext verändert, das mir ein mit Blender erstelltes 3D-Objekt samt Textur laden und rendern soll. Im Buch wird zunächst ein framework implementiert, das einen OBJ-Parser enthält, den ich auch verwende. 
Mein Problem ist, dass das fertig gerenderte Objekt so aussieht:







Das ist der entsprechende Quelltext:


Spoiler: Quelltext





```
package com.badlogic.androidgames.gladvanced;

import javax.microedition.khronos.opengles.GL10;

import com.badlogic.androidgames.framework.Game;
import com.badlogic.androidgames.framework.Screen;
import com.badlogic.androidgames.framework.gl.Camera2D;
import com.badlogic.androidgames.framework.gl.EulerCamera;
import com.badlogic.androidgames.framework.gl.ObjLoader;
import com.badlogic.androidgames.framework.gl.PointLight;
import com.badlogic.androidgames.framework.gl.SpriteBatcher;
import com.badlogic.androidgames.framework.gl.Texture;
import com.badlogic.androidgames.framework.gl.TextureRegion;
import com.badlogic.androidgames.framework.gl.Vertices3;
import com.badlogic.androidgames.framework.impl.GLGame;
import com.badlogic.androidgames.framework.impl.GLScreen;
import com.badlogic.androidgames.framework.math.Vector2;
import com.badlogic.androidgames.framework.math.Vector3;

public class ObjTest extends GLGame {

	@Override
	public Screen getStartScreen() {
		return new ObjScreen(this);
	}

	class ObjScreen extends GLScreen {

		//Texture crateTexture;
		Texture carTexture;
		//Vertices3 cube;
		Vertices3 car;
		PointLight light;
		EulerCamera camera;
		Texture buttonTexture;
		SpriteBatcher batcher;
		Camera2D guiCamera;
		TextureRegion buttonRegion;
		Vector2 touchPos;
		float lastX = -1;
		float lastY = -1;

		public ObjScreen(Game game) {
			super(game);

			//crateTexture = new Texture(glGame, "crate.png", true);
			carTexture = new Texture(glGame, "car.png", true);
			//cube = ObjLoader.load(glGame, "cube.obj");
			car = ObjLoader.load(glGame, "car.obj");
			light = new PointLight();
			light.setPosition(3, 3, -3);
			camera = new EulerCamera(67, glGraphics.getWidth()
					/ (float) glGraphics.getHeight(), 1, 100);
			camera.getPosition().set(0, 1, 3);

			buttonTexture = new Texture(glGame, "button.png");
			batcher = new SpriteBatcher(glGraphics, 1);
			guiCamera = new Camera2D(glGraphics, 480, 320);
			buttonRegion = new TextureRegion(buttonTexture, 0, 0, 64, 64);
			touchPos = new Vector2();
		}

		@Override
		public void resume() {
			//crateTexture.reload();
			carTexture.reload();
		}

		@Override
		public void update(float deltaTime) {
			game.getInput().getTouchEvents();
			float x = game.getInput().getTouchX(0);
			float y = game.getInput().getTouchY(0);
			guiCamera.touchToWorld(touchPos.set(x, y));

			if (game.getInput().isTouchDown(0)) {
				if (touchPos.x < 64 && touchPos.y < 64) {
					Vector3 direction = camera.getDirection();
					camera.getPosition().add(direction.mul(deltaTime));
				} else {
					if (lastX == -1) {
						lastX = x;
						lastY = y;
					} else {
						camera.rotate((x - lastX) / 10, (y - lastY) / 10);
						lastX = x;
						lastY = y;
					}
				}
			} else {
				lastX = -1;
				lastY = -1;
			}
		}

		@Override
		public void present(float deltaTime) {
			GL10 gl = glGraphics.getGL();
			gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
			gl.glViewport(0, 0, glGraphics.getWidth(), glGraphics.getHeight());

			camera.setMatrices(gl);

			gl.glEnable(GL10.GL_DEPTH_TEST);
			gl.glEnable(GL10.GL_TEXTURE_2D);
			gl.glEnable(GL10.GL_LIGHTING);
			gl.glEnable(GL10.GL_COLOR_MATERIAL);

			
			
			//crateTexture.bind();
			//cube.bind();
			carTexture.bind();
			car.bind();
			light.enable(gl, GL10.GL_LIGHT0);

			
					gl.glPushMatrix();
					gl.glTranslatef(0, 0, -4);
					
					//cube.draw(GL10.GL_TRIANGLES, 0, cube.getNumVertices());
					car.draw(GL10.GL_TRIANGLES, 0, car.getNumVertices());
					
					gl.glPopMatrix();
			
		

			//cube.unbind();
			car.unbind();
			
			gl.glDisable(GL10.GL_COLOR_MATERIAL);
			gl.glDisable(GL10.GL_LIGHTING);
			gl.glDisable(GL10.GL_DEPTH_TEST);

			gl.glEnable(GL10.GL_BLEND);
			gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

			guiCamera.setViewportAndMatrices();
			batcher.beginBatch(buttonTexture);
			batcher.drawSprite(32, 32, 64, 64, buttonRegion);
			batcher.endBatch();

			gl.glDisable(GL10.GL_BLEND);
			gl.glDisable(GL10.GL_TEXTURE_2D);
		}

		@Override
		public void pause() {

		}

		@Override
		public void dispose() {
		}
	}
}
```



Ich kann natürlich auch gerne noch mehr Quelltexte posten (z.B. von dem ObjLoader), aber ich denke wenn sich jemand schonmal damit beschäftigt hat, ist demjenigen vielleicht schnell klar, woran es liegen könnte.

Falls noch andere Informationen gebraucht werden, gerne nachfragen.

Vielen Dank für zahlreiche hilfreiche Antworten im Vorraus! :toll:


----------



## Joose (15. Apr 2014)

!GH!Budd hat gesagt.:


> Mein Problem ist, dass das fertig gerenderte Objekt so aussieht:
> 
> ....
> 
> Ich kann natürlich auch gerne noch mehr Quelltexte posten (z.B. von dem ObjLoader), aber ich denke wenn sich jemand schonmal damit beschäftigt hat, ist demjenigen vielleicht schnell klar, woran es liegen könnte.



Dein Problem ist ein das fertig gerenderte Objekt, wie sollte es denn ausschauen?
Einfach nur "Mein Problem ist, das fertig gerenderte Objekt" ist etwas dürftig 

Wenn du besagten Quellcode aus dem Buch unverändert ausführst, wird das Objekt richtig gerendert? 
Kann es sein dass es richtig gerendert wird nur die "car.obj" Datei fehlerhaft ist?

Sollte das Objekt richtig dargestellt werden bei unveränderten Code, dann baue deine Änderungen Stück für Stück ein und kontrolliere sie. Dann solltest du herausfinden welche deiner Änderungen den Fehler verursacht.


----------



## !GH!Budd (15. Apr 2014)

Das richtig gerenderte Objekt sollte so aussehen wie in Blender:






Hätte ich vielleicht dazu sagen sollen. Also die Perspektive lässt sich ja anpassen. Nur das mit den Dreiecken ist nicht so toll. Das Meiste wird ja richtig gerendert. Ich möchte nur wissen, wie es sein kann, dass der vorgegebene "cube" keine Probleme macht, mein "car" aber schon. Liegt es an der Anzahl der Ecken? Oder muss ich noch was anderes beachten?

Der code ist ja unverändert. Ich habe nur "cube" durch "car" ersetzt.


----------



## Joose (16. Apr 2014)

!GH!Budd hat gesagt.:


> der code ist ja unverändert. Ich habe nur "cube" durch "car" ersetzt.



und "car" ist von dir selbst erstellt worden? 
Ich gehe einfach davon aus (da der Code unverändert ist) das es einen Fehler in der Datei gibt, bzw. der Code einfach die Datei anders interpretiert als Blender.

Ist das Bild oben von dir? Die gleiche Datei wie dein Program verwendet nur in Blender geöffnet?


----------



## !GH!Budd (16. Apr 2014)

Genau. Es ist ganz genau die gleiche Datei. Und auch die gleiche Textur. Oben als Screenshot meines Android-Handys und unten das von Blender gerenderte Bild. Von daher: Wie kann die OBJ-Datei fehlerhaft sein. Mag sein, dass der OBJ-Parser das anders interpretiert, aber was muss ich denn dann nun ändern?


----------



## !GH!Budd (16. Apr 2014)

Habs rausgefunden. Der Parser kann nur Objects mit Dreiecken rendern. Mein Objekt hatte auch andere Polygone. Gibts dafür in Blender vielleicht eine Funktion zum Umwandeln?


----------

