Opengl ES 3D Textur mapping

Hallo
Ich habe einen 3D Körper, ein Quader der hochkant steht und dassen Höhe : Breite/Tiefe = 2 : 1 ich will jede der SEITENflächen mit jeweils einer Textur die hochkant ist im Verhältnis y:x = 2:1 bedecken.Aber Es wird nicht jede Seite mit dieser Textur bedeckt, nein, es wird nur eine Seite bedeckt und die anderen bleiben leer. Die bedeckte Seite wird nicht etwa einfach mit der Textur bedeckt, die Textur wird vorher herunter sakaliert, dann wird die textur gedreht, sodass sie quer liegt, und mit diesen querliegenden bildchen die komplette Seite ausgefüllt.
Code:
Koordinaten(Objekt/Textur)
Die Koordinaten werden im Konstruktor noch in FloatBuffers gesteckt

private float[] vertices1 = {  
		      // FRONT
		      -1.0f, -2.0f,  1.0f,  // 0. left-bottom-front
		       1.0f, -2.0f,  1.0f,  // 1. right-bottom-front
		      -1.0f,  2.0f,  1.0f,  // 2. left-top-front
		       1.0f,  2.0f,  1.0f,  // 3. right-top-front
		      // BACK
		       1.0f, -2.0f, -1.0f,  // 6. right-bottom-back
		      -1.0f, -2.0f, -1.0f,  // 4. left-bottom-back
		       1.0f,  2.0f, -1.0f,  // 7. right-top-back
		      -1.0f,  2.0f, -1.0f,  // 5. left-top-back
		      // LEFT
		      -1.0f, -2.0f, -1.0f,  // 4. left-bottom-back
		      -1.0f, -2.0f,  1.0f,  // 0. left-bottom-front 
		      -1.0f,  2.0f, -1.0f,  // 5. left-top-back
		      -1.0f,  2.0f,  1.0f,  // 2. left-top-front
		      // RIGHT
		       1.0f, -2.0f,  1.0f,  // 1. right-bottom-front
		       1.0f, -2.0f, -1.0f,  // 6. right-bottom-back
		       1.0f,  2.0f,  1.0f,  // 3. right-top-front
		       1.0f,  2.0f, -1.0f,  // 7. right-top-back
		      // TOP
		      -1.0f,  2.0f,  1.0f,  // 2. left-top-front
		       1.0f,  2.0f,  1.0f,  // 3. right-top-front
		      -1.0f,  2.0f, -1.0f,  // 5. left-top-back
		       1.0f,  2.0f, -1.0f,  // 7. right-top-back
		      // BOTTOM
		      -1.0f, -2.0f, -1.0f,  // 4. left-bottom-back
		       1.0f, -2.0f, -1.0f,  // 6. right-bottom-back
		      -1.0f, -2.0f,  1.0f,  // 0. left-bottom-front
		       1.0f, -2.0f,  1.0f   // 1. right-bottom-front
		   };
	
	
	float[][] texCoords = { 
		     {-1.0f, -2.0f,
		      -1.0f,  2.0f,
		       1.0f, -2.0f,
		       1.0f,  2.0f}, 
		     { 1.0f, -2.0f,
		       1.0f,  2.0f,
		      -1.0f, -2.0f,
		      -1.0f,  2.0f},
		     {-1.0f, -2.0f,
			  -1.0f,  2.0f,
		      -1.0f, -2.0f,
		      -1.0f,  2.0f},
		     { 1.0f, -2.0f,
			   1.0f,  2.0f,
		       1.0f, -2.0f,
		       1.0f,  2.0f}
		   };

Laden der Textur:

Texture = loadBitmapFromResource(R.drawable.bild, context, true);

public Bitmap loadBitmapFromResource( int resourceID, Context context, boolean scaleToPO2 ) {

		    // pull in the resource
		    Bitmap bitmap = null;
		    Resources resources = context.getResources();

		    Drawable image = resources.getDrawable(resourceID);
		    float density = resources.getDisplayMetrics().density;

		    int originalWidth = (int)(image.getIntrinsicWidth() / density);
		    int originalHeight = (int)(image.getIntrinsicHeight() / density);

		    int powWidth = getNextHighestPO2( originalWidth );
		    int powHeight = getNextHighestPO2( originalHeight );

		    if ( scaleToPO2 ) {
		        image.setBounds( 0, 0, powWidth, powHeight );
		    } else {
		        image.setBounds( 0, 0, originalWidth, originalHeight );
		    }
		    bitmap = Bitmap.createBitmap( powWidth, powHeight, Bitmap.Config.ARGB_4444 );
		    Canvas canvas = new Canvas(bitmap);
		    bitmap.eraseColor(0);

		    image.draw( canvas ); // draw the image onto our bitmap

		    return bitmap;
		}
	   
	   public static int getNextHighestPO2( int n ) {
		    n -= 1;
		    n = n | (n >> 1);
		    n = n | (n >> 2);
		    n = n | (n >> 4);
		    n = n | (n >> 8);
		    n = n | (n >> 16);
		    n = n | (n >> 32);
		    return n + 1;
		}
loadTexture(Texture, gl);

public void loadTexture(Bitmap texture, GL10 gl){ 
		   gl.glGenTextures(1, textures, 0);
		   gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
		   gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                   GL10.GL_TEXTURE_MAG_FILTER,
                   GL10.GL_NEAREST); 
		   gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                   GL10.GL_TEXTURE_MIN_FILTER,
                   GL10.GL_NEAREST);
		   GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0);
	   }

Zeichnen

gl.glScalef(0.5f, 0.5f, 0.5f);
	      gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	      gl.glFrontFace(GL10.GL_CCW);
	      gl.glEnable(GL10.GL_CULL_FACE);
	      gl.glCullFace(GL10.GL_BACK);
	      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
	      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer1);
	      gl.glEnable(GL10.GL_TEXTURE_2D);
	      gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
	      gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
	      gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBufferFront);
	      gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
	      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
	      gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
	      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);
	      gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
	      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);
	      gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
	      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);
	      
	      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);
	      
	      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);
	      
	      gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
	      gl.glDisable(GL10.GL_TEXTURE_2D);
	      gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	      gl.glDisable(GL10.GL_CULL_FACE);

Ohne KSKB gibt es nur zweieinhalb Möglichkeiten:

  1. Selbst ein KSKB aus den geposteten Codestücken erstellen

  2. Hemdsärmelige Tipps geben
    2.5: @Fancy erwähnen und darauf vertrauen, dass er die Antwort mal wieder durch scharfes Hinschauen findet

  3. ist mir im Moment zu aufwändig, 2.5 schon erledigt, und zu 2.:

Erstmal nur die Seite malen, die funktioniert, und schauen, dass man da die Texturkoordinaten richtig bekommt. Wenn die Textur “gedreht” und “skaliert” ist, bedeutet das, dass die Texturkoordinaten nicht stimmen. Ohne da sooo tief drin zu sein: Texturkoordinaten wie ((-1.0f, -2.0f), (-1.0f, 2.0f),…) sehen suspekt aus. Je nachdem, auf welche vertices die gemappt werden (hab’ ich jetzt nicht gelesen), bedeutet das, dass man die Textur dort “zwei mal übereinander” anzeigt. Wenn man sich das in 2D vorstellt, und die Eckpunkte der Fläche ganz klassisch bei
(0,0), (0,2), (1,2), (1,0)
liegen, dann sollte man dort die besagte Textur mit den Koordinaten
(0,0), (0,1), (1,1), (1,0)
draufmappen können.

Danach schauen, warum sie nur auf einer Seite angezeigt wird. Ob DAS an falschen Texturkoordinaten liegt (oder liegen kann) weiß ich gerade nicht, aber das kann man vielleicht eingrenzen, wenn man mal NUR eine Fläche malt, die im Moment NICHT gefüllt wird, und schaut, dass man die zum Laufen bringt.

(BTW: Dass man zum Zeichnen eines Quaders so viele draw-Aufrufe macht, ist zum Testen/Debuggen/“Lernen” wohl OK, aber wenn man “viele” Objekte zeichnen will, bremst das aus. Dafür gibt’s dann Instancing und Multi-Draw-Calls, und anderen @Fancy stuff :D)

Danke, mithilfe einiger Anpassungen bei den Texturkoordinaten konnte ich es schaffen, dass auf einer Seite die Textur richtig angezeigt wird. Doch wie schaffe ich es, dass es auf den anderen vier Seiten genauso ist ?

Moin,

ich habe leider von ES keine Ahnung, befürchte also auch nicht wirklich helfen zu können. Das wichtigste schrieb Marco aber bereits: Erstmal nur eine Seite sauber hin bekommen, dann die zweite, dann die dritte, usw. Dann sieht man sofort welche Koordinaten falsch sind. Dabei liegen Texturkoordinaten normalerweise immer zwischen 0 und 1 und die Vertices sollten entgegen dem Uhrzeigersinn angeordnet sein. Bei Strips entsprechend:

Viele Grüße
Fancy

Eine Seite hab ich ja richtig hingekriegt, nur die anderen nicht

Wenn man will, dass eine Textur auf einer Fläche zweimal übereinader ist, wären die Koordinaten aber (0,0),(1,0),(1,2),(2,0) !? (Ist hier nicht der Fall, weil die Textur schon 2:1 hat, aber da bin ich kurz drüber gestolpert…)

Ja, deshalb hab ich das schwammige „normalerweise“ eingefügt. :wink:

Ob OpenGL die Textur wirklich wiederholt, hängt von den Werten für GL_TEXTURE_WRAP_S und GL_TEXTURE_WRAP_T ab. Zumindest gibt es unter ES als Werte dazu GL_REPEAT und GL_CLAMP_TO_EDGE, wenn GL_REPEAT der Default-Wert ist (vermutlich), dann sollte das Verhalten wohl so sein wie Du es beschreibst.

Viele Grüße
Fancy

Ok, ich habs geschaft, dass alle Seiten eine Textur haben. nur sind die Texturen statt dunkelblau, türkis eingefärbt, was mir sehr suspekt ist(keine gl.glColor4f aufrufe, die Textur ist in der fotogallerie ganz normal gefärbt).