我一直在尝试添加纹理,但纹理如下所示:
这是我添加坐标和添加纹理坐标的代码。
for(int i=0; i<outerVertexCount; i++) {
float percent=(i/(float)(outerVertexCount));
float rad= (float) (percent*2*Math.PI);
float outerX= (float) (centerX+radius*Math.cos(rad));
float outerY=(float)(centerY+radius*Math.sin(rad));
int previous=idx;
circleCoordinates[idx++]=outerX;
circleCoordinates[idx++]=outerY;
circleCoordinates[idx++]=(circleCoordinates[previous])/(radius*2);
circleCoordinates[idx++] = (circleCoordinates[previous+1])/(radius*2);
}
请帮帮我。
您正在绘制一个圆并使用“标准化”几乎相同的坐标来获取纹理坐标。所以你需要做的是将纹理坐标标准化为纹理空间[0,1]。最简单的方法是检查顶部和左侧的纹理坐标是否分别为(0.5,0.0)和(0.0,0.5)。底部和右侧也应分别为(0.5,1.0)和(1.0,0.5)。 (接触边缘的点)。
您的代码中的问题是:
circleCoordinates[idx++] = (circleCoordinates[previous])/(radius*2);
circleCoordinates[idx++] = (circleCoordinates[previous+1])/(radius*2);
当您在圆圈中创建点时,这些点将低于0,在某些象限中将采用错误的纹理点。你也可以通过centerX and centerY
来抵消你的圆圈,这也会移动你的纹理。
工作代码应该是:
circleCoordinates[idx++] = (circleCoordinates[previous])/(radius*2) + 0.5 - centerX / (radius * 2);
circleCoordinates[idx++] = (circleCoordinates[previous+1])/(radius*2) + 0.5 - centerY / (radius * 2);
0.5是因为你已经使用radius * 2
对其进行了标准化而没有添加centerPoint,它将映射到[-0.5,0.5]但是你还添加了你的中心点并对其进行了标准化,因此你必须减去center(XY) / (radius * 2)
来删除神器。
TLDR;你的(0,0)是你想要它在上面,左边的第一个图像中的白色交叉点。相应地归一化。
这是一个例子:
public class Circle {
private int[] textureIDs = new int[1];
private int numberOfVertices = 30;
private final float[][] vertices = new float[numberOfVertices][2];
private final float[][] texVertices = new float[numberOfVertices][2];
private FloatBuffer vertexBuffer; // Buffer for vertex-array
private FloatBuffer texBuffer; // Buffer for texture-coords-array (NEW)
public Circle() {
setUpVertices(1.0f);
// Setup vertex-array buffer. Vertices in float. A float has 4 bytes
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4 * 2);
vbb.order(ByteOrder.nativeOrder()); // Use native byte order
vertexBuffer = vbb.asFloatBuffer(); // Convert byte buffer to float
// Loop through the vertices and put them in the vertexbuffer
for (int i = 0; i < numberOfVertices; i++) {
for (int j = 0; j <= 1; j++) {
vertexBuffer.put(vertices[i][j]); // Copy data into buffer
}
}
vertexBuffer.position(0); // Rewind
setUpTextureVertices(1.0f);
// Setup texture-coords-array buffer, in float. An float has 4 bytes
ByteBuffer tbb = ByteBuffer.allocateDirect(vertices.length * 4 * 2);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
// Loop through the vertices and put them in the vertexbuffer
for (int i = 0; i < numberOfVertices; i++) {
for (int j = 0; j <= 1; j++) {
texBuffer.put(texVertices[i][j]); // Copy data into buffer
}
}
texBuffer.position(0);
}
public void draw(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW); // Front face in counter-clockwise orientation
gl.glEnable(GL10.GL_CULL_FACE); // Enable cull face
gl.glCullFace(GL10.GL_BACK); // Cull the back face (don't display)
// Enable vertex-array and define its buffer
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // Enable texture-coords-array
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuffer); // Define texture-coords
// Draw the primitives from the vertex-array directly
gl.glPushMatrix();
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, numberOfVertices);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
}
public void loadTexture(GL10 gl, Context context) {
gl.glGenTextures(1, textureIDs, 0); // Generate texture-ID array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[0]); // Bind to texture ID
// Set up texture filters
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
// Construct an input stream to texture image
@SuppressLint("ResourceType")
InputStream istream = context.getResources().openRawResource(R.drawable.circle);
Bitmap bitmap;
try {
// Read and decode input as bitmap
bitmap = BitmapFactory.decodeStream(istream);
} finally {
try {
istream.close();
} catch (IOException e) {
}
}
// Build Texture from loaded bitmap for the currently-bind texture ID
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
private void setUpTextureVertices(float radius) {
float theta0 = (float) (2 * Math.PI / (numberOfVertices - 1));
for (int i = 0; i < numberOfVertices; i++) {
float theta = i * theta0;
float c = (float) Math.cos(theta);
float s = (float) Math.sin(theta);
float x = radius * c;
float y = radius * s;
texVertices[i][0] = (x * 0.5f) + 0.5f;
texVertices[i][1] = (y * 0.5f) + 0.5f;
}
}
private void setUpVertices(float radius) {
float theta0 = (float) (2 * Math.PI / (numberOfVertices - 1));
for (int i = 0; i < numberOfVertices; i++) {
float theta = i * theta0;
float c = (float) Math.cos(theta);
float s = (float) Math.sin(theta);
float x = radius * c;
float y = radius * s;
vertices[i][0] = x;
vertices[i][1] = y;
}
}
}