ページ 11

【android】OpenGL ESにてインデックスを使用した場合テクスチャが表示されない

Posted: 2014年9月12日(金) 12:41
by エア
はじめまして、エアと申します。
「AndroidゲームプログラミングA to Z」という本のコードをいじくり回しています。
OpenGL ESにてインデックスを使用し、アルファブレンドを有効にしたテクスチャが表示されず悩んでいます。
赤い塗りつぶし色だけが表示されます。
下記のコードのどこが問題なのか教えて頂けないでしょうか。

コード:

import javax.microedition.khronos.opengles.GL10;

import com.chargetest.framework.Game;
import com.chargetest.framework.Screen;
import com.chargetest.framework.gl.Texture;
import com.chargetest.framework.gl.Vertices;
import com.chargetest.framework.impl.GLGame;
import com.chargetest.framework.impl.GLGraphics;

public class ChargeTest3 extends GLGame{
	
    @Override
    public Screen getStartScreen() {
        return new ChargeScreen3(this);
    }
    
    class ChargeScreen3 extends Screen{
    	GLGraphics glGraphics;
    	Vertices vertices;
    	Texture textureRgba;
 
    	public ChargeScreen3(Game game) {
    		super(game);
    		glGraphics = ((GLGame)game).getGLGraphics();
  
     		textureRgba = new Texture((GLGame)game, "bobargb8888.png");
 
    		vertices = new Vertices(glGraphics, 4, 6, true, true);
    		float[] rects = new float[] {
    				100, 300, 1, 1, 1, 1, 0, 1,
    				228, 300, 1, 1, 1, 1, 1, 1,
    				228, 428, 1, 1, 1, 1, 1, 0,
    				100, 428, 1, 1, 1, 1, 0, 0
    		};
    		vertices.setVertices(rects, 0, rects.length);
    		vertices.setIndices(new short[] {0, 1, 2, 2, 3, 0,
    				}, 0, 6);
    	}
    	
    	@Override
    	public void present(float deltaTime) {
    		GL10 gl = glGraphics.getGL();
    		gl.glViewport(0, 0, glGraphics.getWidth(), glGraphics.getHeight());
    		gl.glClearColor(1,0,0,1);
    		gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    		gl.glMatrixMode(GL10.GL_PROJECTION);
    		gl.glLoadIdentity();
    		gl.glOrthof(0, 320, 0, 480, 1, -1);
 
    		gl.glEnable(GL10.GL_BLEND);
    		gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
  
    		gl.glEnable(GL10.GL_TEXTURE_2D);
   
    		textureRgba.bind();
    		vertices.draw(GL10.GL_TRIANGLES, 0, 6 );
    	}
    	
        @Override
        public void update(float deltaTime) {
            game.getInput().getTouchEvents();
            game.getInput().getKeyEvents();
        }

        @Override
        public void pause() {

        }

        @Override
        public void resume() {

        }

        @Override
        public void dispose() {

        }
    }
}

コード:

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

import com.chargetest.framework.impl.GLGraphics;

public class Vertices {
	final GLGraphics glGraphics;
	final boolean hasColor;
	final boolean hasTexCoords;
	final int vertexSize;
	final IntBuffer vertices;
    final int[] tmpBuffer;
	final ShortBuffer indices;
	
	public Vertices(GLGraphics glGraphics, int maxVertices, int maxIndices, boolean hasColor, boolean hasTexCoords) {
		this.glGraphics = glGraphics;
		this.hasColor = hasColor;
		this.hasTexCoords = hasTexCoords;
		this.vertexSize = (2 + (hasColor?4:0) + (hasTexCoords?2:0)) * 4;
		this.tmpBuffer = new int[maxVertices * vertexSize / 4];
		
		ByteBuffer buffer = ByteBuffer.allocateDirect(maxVertices * vertexSize);
		buffer.order(ByteOrder.nativeOrder());
		vertices = buffer.asIntBuffer();
	
		if(maxIndices > 0) {
			buffer = ByteBuffer.allocateDirect(maxIndices * Short.SIZE / 8);
			buffer.order(ByteOrder.nativeOrder());
			indices = buffer.asShortBuffer();
		} else {
			indices = null;
		}
	}
	
	public void setVertices(float[] vertices, int offset, int length) {
		this.vertices.clear();
		int len = offset + length;
		for(int i=offset, j=0; i < len; i++, j++)
		tmpBuffer[j] = Float.floatToRawIntBits(vertices[i]);
		this.vertices.put(tmpBuffer, 0, length);
		this.vertices.flip();
	}

	public void setIndices(short[] indices, int offset, int length) {
		this.indices.clear();
		this.indices.put(indices, offset, length);	
		this.indices.flip();
	}

	public void bind() {
	    GL10 gl = glGraphics.getGL();
	    
	    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
	    vertices.position(0);
	    gl.glVertexPointer(2, GL10.GL_FLOAT, vertexSize, vertices);
	    
	    if(hasColor) {
	        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
	        vertices.position(2);
	        gl.glColorPointer(4, GL10.GL_FLOAT, vertexSize, vertices);
	    }
	    
	    if(hasTexCoords) {
	        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
	        vertices.position(hasColor?6:2);
	        gl.glTexCoordPointer(2, GL10.GL_FLOAT, vertexSize, vertices);
	    }
	}

	public void draw(int primitiveType, int offset, int numVertices) {        
	    GL10 gl = glGraphics.getGL();
	    
	    if(indices!=null) {
	        indices.position(offset);
	        gl.glDrawElements(primitiveType, numVertices, GL10.GL_UNSIGNED_SHORT, indices);
	    } else {
	        gl.glDrawArrays(primitiveType, offset, numVertices);
	    }        
	}

	public void unbind() {
	    GL10 gl = glGraphics.getGL();
	    if(hasTexCoords)
	        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

	    if(hasColor)
	        gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
	}
}

コード:

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.khronos.opengles.GL10;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;

import com.chargetest.framework.FileIO;
import com.chargetest.framework.impl.GLGame;
import com.chargetest.framework.impl.GLGraphics;

public class Texture {
	GLGraphics glGraphics;
	FileIO fileIO;
	String fileName;
	int textureId;
	int minFilter;
	int magFilter;
    public int width;
    public int height;
	
	public Texture(GLGame glGame, String fileName) {
		this.glGraphics = glGame.getGLGraphics();
		this.fileIO = glGame.getFileIO();
		this.fileName = fileName;
		load();
	}

	private void load() {
		GL10 gl = glGraphics.getGL();
		int[] textureIds = new int[1];
		gl.glGenTextures(1, textureIds, 0);
		textureId = textureIds[0];

		InputStream in = null;
		try {
			in = fileIO.readAsset(fileName);
			Bitmap bitmap = BitmapFactory.decodeStream(in);
			gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
			GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
			setFilters(GL10.GL_NEAREST, GL10.GL_NEAREST);
			gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
            width = bitmap.getWidth();
            height = bitmap.getHeight();
            bitmap.recycle();
		} catch(IOException e) {
			throw new RuntimeException("Couldn't load texture '" + fileName +"'", e);
		} finally {
			if(in != null)
				try { in.close(); } catch (IOException e) { }
		}
	}

	public void reload() {
		load();
		bind();
		setFilters(minFilter, magFilter);
		glGraphics.getGL().glBindTexture(GL10.GL_TEXTURE_2D, 0);
	}

	public void setFilters(int minFilter, int magFilter) {
		this.minFilter = minFilter;
		this.magFilter = magFilter;
		GL10 gl = glGraphics.getGL();
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, minFilter);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, magFilter);
	}

	public void bind() {
		GL10 gl = glGraphics.getGL();
		gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
	}

	public void dispose() {
		GL10 gl = glGraphics.getGL();
		gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
		int[] textureIds = { textureId };
		gl.glDeleteTextures(1, textureIds, 0);
	}
}

Re: 【android】OpenGL ESにてインデックスを使用した場合テクスチャが表示されない

Posted: 2014年9月12日(金) 13:01
by エア
すいません。自己解決しました。
ChargeTest3の49行目にvertices.bind();を入れるとうまく行きました。
閲覧して下さった方、ありがとうございます。