我有一个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;
}
答案 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个顶点与正确的三角形连接起来,并绘制。