将纹理效果从2d复制到3d OpenGL

时间:2014-05-01 05:48:47

标签: java android opengl-es 3d texture-mapping

我有一个2D OpenGL项目,用于安装.png的android作为Square上的纹理。我想在3D立方体的所有6个边上复制效果。我尝试尽可能地匹配格式,但遇到意外的停止问题。

我的第一个代码块:

package book.BouncySquare;
import android.content.Context;
import android.graphics.*;
import android.opengl.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
/**
 * A vertex shaded square.
 */
class Square
{
public Square()
{
    float vertices[] = 
        {
            -1.0f, -1.0f,
            1.0f, -1.0f,
            -1.0f,  1.0f,
            1.0f,  1.0f
        }; 

    byte maxColor=(byte)255;

    byte colors[] = 
        {
            maxColor,maxColor,       0,maxColor,
            0,       maxColor,maxColor,maxColor,
            0,              0,       0,maxColor,
            maxColor,       0,maxColor,maxColor
        }; 

    byte indices[] = 
        {
            0, 3, 1,
            0, 2, 3
        };


    float[] textureCoords =     
        {                       
            0.0f, 0.0f,
            1.0f, 0.0f,
            0.0f, 1.0f,
            1.0f, 1.0f      
        };

    ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    mFVertexBuffer = vbb.asFloatBuffer();
    mFVertexBuffer.put(vertices);
    mFVertexBuffer.position(0);

    mColorBuffer = ByteBuffer.allocateDirect(colors.length);
    mColorBuffer.put(colors);
    mColorBuffer.position(0);

    mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
    mIndexBuffer.put(indices);
    mIndexBuffer.position(0);

    ByteBuffer tbb = ByteBuffer.allocateDirect(textureCoords.length * 4);
    tbb.order(ByteOrder.nativeOrder());
    mTextureBuffer = tbb.asFloatBuffer();
    mTextureBuffer.put(textureCoords);
    mTextureBuffer.position(0); 
}

public void draw(GL10 gl)
{ 
    gl.glVertexPointer(2, GL10.GL_FLOAT, 0, mFVertexBuffer);
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glColorPointer(4, GL10.GL_UNSIGNED_BYTE, 0, mColorBuffer);
    gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

    gl.glEnable(GL10.GL_TEXTURE_2D);                //1
    gl.glEnable(GL10.GL_BLEND);                 //2 

    gl.glBlendFunc(GL10.GL_ONE, GL10.GL_SRC_COLOR);         //3
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);      //4 

    gl.glTexCoordPointer(2, GL10.GL_FLOAT,0, mTextureBuffer);   //5
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);        //6 

    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);          //7

    gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);       //8
}

private int[] textures = new int[1];

public int createTexture(GL10 gl, Context contextRegf, int resource) 
{
    Bitmap tempImage = BitmapFactory.decodeResource(contextRegf.getResources(), resource); // 1

    gl.glGenTextures(1, textures, 0); // 2
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); // 3

    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, tempImage, 0); // 4

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); // 5a
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); // 5b   

    tempImage.recycle();//6

    return resource;
}

private Float mTransY;
public FloatBuffer  mTextureBuffer;
private FloatBuffer mFVertexBuffer;
private ByteBuffer  mColorBuffer;
private ByteBuffer  mIndexBuffer;

}

我的第二个代码块:

package book.BouncyCube1;

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

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;

import android.view.MotionEvent;

/**
 * A vertex shaded cube.
 */
class Cube
{

    float[] mVertices = 
    {
            -1.0f,  1.0f, 1.0f,
             1.0f,  1.0f, 1.0f,
             1.0f, -1.0f, 1.0f,
            -1.0f, -1.0f, 1.0f,

            -1.0f,  1.0f,-1.0f,
             1.0f,  1.0f,-1.0f,
             1.0f, -1.0f,-1.0f,
            -1.0f, -1.0f,-1.0f
    }; 

    float maxColor=1.0f;

    float[] mColors = 
    {
            maxColor,   maxColor,      0.0f,maxColor,
            0.0f,       maxColor,  maxColor,maxColor,
            0.0f,           0.0f,      0.0f,maxColor,
            maxColor,       0.0f,  maxColor,maxColor,

            maxColor,       0.0f,      0.0f,maxColor,
            0.0f,       maxColor,      0.0f,maxColor,
            0.0f,           0.0f,  maxColor,maxColor,
            0.0f,           0.0f,      0.0f,maxColor
    }; 

    float[] mNormals = 
    {
        0.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 1.0f,

        1.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f,


        0.0f, 1.0f, 0.0f,
        0.0f, 1.0f, 0.0f,

        0.0f, 0.0f, -1.0f,
        0.0f, 0.0f, -1.0f,  

        0.0f, -1.0f, 0.0f,
        0.0f, -1.0f, 0.0f,

        -1.0f, 0.0f, 0.0f,
        -1.0f, 0.0f, 0.0f,

    };

    byte[] tfan1 =                  
    {
            1,0,3,
            1,3,2,
            1,2,6,
            1,6,5,
            1,5,4,
            1,4,0               
    };

    byte[] tfan2 =                  
    {
            7,4,5,
            7,5,6,
            7,6,2,
            7,2,3,
            7,3,0,
            7,0,4
    };

    public Cube()
    {      
        mTfan1 = ByteBuffer.allocateDirect(tfan1.length);
        mTfan1.put(tfan1);
        mTfan1.position(0);

        mTfan2 = ByteBuffer.allocateDirect(tfan2.length);
        mTfan2.put(tfan2);
        mTfan2.position(0);
    }

    public void draw(GL10 gl)
    {
        gl.glVertexPointer(3, GL11.GL_FLOAT, 0,makeFloatBuffer(mVertices));
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        gl.glColorPointer(4, GL11.GL_FLOAT, 0,makeFloatBuffer(mColors));
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

        gl.glNormalPointer(GL11.GL_FLOAT, 0,makeFloatBuffer(mNormals));
        gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

        gl.glDrawElements( gl.GL_TRIANGLE_FAN, 6 * 3, gl.GL_UNSIGNED_BYTE, mTfan1);
        gl.glDrawElements( gl.GL_TRIANGLE_FAN, 6 * 3, gl.GL_UNSIGNED_BYTE, mTfan2);
    }

     protected static FloatBuffer makeFloatBuffer(float[] arr) 
     {
          ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
          bb.order(ByteOrder.nativeOrder());
          FloatBuffer fb = bb.asFloatBuffer();
          fb.put(arr);
          fb.position(0);
          return fb;
     }


    private FloatBuffer mFVertexBuffer;
    private FloatBuffer mNormalBuffer;
    private ByteBuffer  mColorBuffer;
    private ByteBuffer  mIndexBuffer;
    private ByteBuffer  mTfan1;
    private ByteBuffer  mTfan2;


}

1 个答案:

答案 0 :(得分:0)

OpenGL仅支持绘制调用的一组索引,这些索引用于处理所有顶点属性(位置,颜色,法线)。看看你的第二个版本,你有8个位置,8种颜色和12个法线。注意这不起作用的一种方法是索引的范围是0..7,因此并非所有12个法线都被使用。

您需要做的是为位置,颜色和法线的每个独特组合创建一个OpenGL顶点。对于立方体,最终会有24个顶点。虽然立方体只有8个角,但每个角有3个不同的法线,8 * 3 = 24.虽然立方体只有6个不同的法线,但每个法线用于4个角,6 * 4 = 24。 p>

因此,定义一个包含24个位置的数组,一个包含24种颜色的数组,以及一个包含24个法线的数组,匹配以定义所有24个顶点。或者一个数组,其中所有这三个属性都是交错的。然后定义索引数组以将24个顶点与正确的三角形连接起来,并绘制。