Android OpenGL尝试纹理多个不同的位图

时间:2014-04-30 16:40:24

标签: android opengl-es bitmap textures

我有一些小立方体组成一个网格来制作3D立方体。在每个小立方体上我使用位图来纹理表面,但我想使用多于一张图片。我可以在loadTextures中构建更多纹理,并将它们添加到final int[] textureHandle = new int[1];并返回它们。我如何将它们实例化为我正在绘制的每个小立方体?

@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
{


mLastRequestedCubeFactor = mActualCubeFactor = 3;
generateCubes(mActualCubeFactor, false, false);         

// Set the background clear color to black.
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

// Use culling to remove back faces.
GLES20.glEnable(GLES20.GL_CULL_FACE);

// Enable depth testing
GLES20.glEnable(GLES20.GL_DEPTH_TEST);                      

// Position the eye in front of the origin.
final float eyeX = 0.0f;
final float eyeY = 0.0f;
final float eyeZ = -0.5f;

// We are looking toward the distance
final float lookX = 0.0f;
final float lookY = 0.0f;
final float lookZ = -5.0f;

// Set our up vector. This is where our head would be pointing were we holding the camera.
final float upX = 0.0f;
final float upY = 1.0f;
final float upZ = 0.0f;

// Set the view matrix. This matrix can be said to represent the camera position.
// NOTE: In OpenGL 1, a ModelView matrix is used, which is a combination of a model and
// view matrix. In OpenGL 2, we can keep track of these matrices separately if we choose.
Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);        

final String vertexShader = RawResourceReader.readTextFileFromRawResource(mLessonSevenActivity, R.raw.lesson_seven_vertex_shader);          
final String fragmentShader = RawResourceReader.readTextFileFromRawResource(mLessonSevenActivity, R.raw.lesson_seven_fragment_shader);

final int vertexShaderHandle = ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, vertexShader);       
final int fragmentShaderHandle = ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShader);     

mProgramHandle = ShaderHelper.createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle, 
        new String[] {"a_Position",  "a_Normal", "a_TexCoordinate"});                   

// Load the texture
mAndroidDataHandle = TextureHelper.loadTexture(mLessonSevenActivity, R.drawable.usb_android);       
GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);          

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mAndroidDataHandle);     
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);       

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mAndroidDataHandle);     
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR_MIPMAP_LINEAR);     

// Initialize the accumulated rotation matrix
Matrix.setIdentityM(mAccumulatedRotation, 0);        
}

public class TextureHelper
{
    public static int loadTexture(final Context context, final int resourceId)
    {
        final int[] textureHandle = new int[1];

        GLES20.glGenTextures(1, textureHandle, 0);

        if (textureHandle[0] != 0)
        {
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inScaled = false;   // No pre-scaling

            // Read in the resource
            final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options);

            // Bind to the texture in OpenGL
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);

            // Set filtering
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);

            // Load the bitmap into the bound texture.
            GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

            // Recycle the bitmap, since its data has been loaded into OpenGL.
            bitmap.recycle();                       
        }

        if (textureHandle[0] == 0)
        {
            throw new RuntimeException("Error loading texture.");
        }

        return textureHandle[0];
    }
}

1 个答案:

答案 0 :(得分:1)

  

如何将它们实例化到我绘制的每个小立方体?

简而言之,你不会。

即使在桌面GL中,vertex instancing是核心功能,也无法在不将绘图分割为多个绘制调用的情况下更改纹理绑定。

您可以使用纹理图集,数组纹理或几何着色器从不同的( 已绑定的 )纹理或单个纹理的不同部分进行采样。或者,您可以使用无绑定纹理。我提到的每一件事都需要比上一版更新的GL版本。

在ES中执行此操作的唯一方法是将多个绘制调用或纹理图集/绑定纹理添加到多个纹理单元。但由于实例化不是核心特征,动态计算纹理坐标/单位是一个巨大的痛苦,并将涉及复制顶点数据。

最重要的是, 真正 对实例化多维数据集意味着什么?您是在尝试在单个操作中绘制500个立方体,还是通过调用多维数据集类中的某个方法来单独绘制它们?根据具体情况,实例化具有不同的含义。