Java OpenGL ES,将纹理添加到圆

Java OpenGL ES,将纹理添加到圆,java,android,opengl-es,Java,Android,Opengl Es,我正在OpenGL ES中绘制一个圆,当添加纹理时,它被“添加”4次而不是1次(参见下图) 换句话说,这就是我的图片x4。我想要的是以圆圈中的一张图片为中心的核弹符号 下面是我使用纹理绘制圆的方法(在Circle类中) public void drawTexture(GL10 gl) { gl.glFrontFace(GL10.GL_CCW); // Front face in counter-clockwise orientation gl.glEnable(GL10.

我正在OpenGL ES中绘制一个圆,当添加纹理时,它被“添加”4次而不是1次(参见下图)

换句话说,这就是我的图片x4。我想要的是以圆圈中的一张图片为中心的核弹符号

下面是我使用纹理绘制圆的方法(在Circle类中)

public void drawTexture(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);

}
目前,texBuffer与vertexBuffer相同(可能是问题?),因为它必须具有相同数量的点,如果不是顶点,我不知道哪些点

下面是加载纹理的方法以及设置纹理顶点的方法

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
    InputStream istream = context.getResources().openRawResource(R.drawable.nuke);
    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 theta = (float) (2 * Math.PI / (numberOfVertices-1));
    float c = (float) Math.cos(theta);
    float s = (float) Math.sin(theta);
    float x = radius;
    float y = 0;

    for (int i = 0; i < numberOfVertices; i++) {
        texVertices[i][0] = x;
        texVertices[i][1] = y;
        float t = x;
        x = (c * x - s * y + 1) * 0.5f;
        y = (s * t + c * y + 1) * 0.5f;
    }
}

private void setUpVertices(float radius) {
    float theta = (float) (2 * Math.PI / (numberOfVertices-1));
    float c = (float) Math.cos(theta);
    float s = (float) Math.sin(theta);
    float x = radius;
    float y = 0;

    for (int i = 0; i < numberOfVertices; i++) {
        vertices[i][0] = x;
        vertices[i][1] = y;
        float t = x;
        x = c * x - s * y;
        y = s * t + c * y;
    }
}
public void loadTexture(GL10 gl,上下文){
gl.glGenTextures(1,textureID,0);//生成纹理ID数组
gl.glBindTexture(GL10.gl_TEXTURE_2D,textureId[0]);//绑定到纹理ID
//设置纹理过滤器
gl.glTexParameterf(GL10.gl\u纹理\u 2D,GL10.gl\u纹理\u最小\u过滤器,GL10.gl\u最近);
gl.glTexParameterf(GL10.gl\u纹理\u 2D,GL10.gl\u纹理\u MAG\u过滤器,GL10.gl\u线性);
//构造纹理图像的输入流
InputStream istream=context.getResources().openRawResource(R.drawable.nuke);
位图;
试一试{
//以位图形式读取和解码输入
位图=BitmapFactory.decodeStream(istream);
}最后{
试一试{
istream.close();
}捕获(IOE异常){
}
}
//根据加载的位图为当前绑定纹理ID生成纹理
GLUtils.texImage2D(GL10.GL_纹理_2D,0,位图,0);
bitmap.recycle();
}
专用空心设置纹理顶点(浮动半径){
浮点θ=(浮点)(2*Math.PI/(顶点数-1));
float c=(float)Math.cos(θ);
float s=(float)Math.sin(θ);
浮动x=半径;
浮动y=0;
对于(int i=0;i
编辑:为Circle类添加了构造函数

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 Circle(){
设置顶点(1.0f);
//设置顶点数组缓冲区。浮点中的顶点。浮点有4个字节
ByteBuffer vbb=ByteBuffer.allocateDirect(顶点.length*4*2);
vbb.order(ByteOrder.nativeOrder());//使用本机字节顺序
vertexBuffer=vbb.asFloatBuffer();//将字节缓冲区转换为浮点
//循环遍历顶点并将它们放入vertexbuffer
对于(int i=0;i对于(int j=0;j您的问题是uv从-1变为1。请确保它们从0变为1

窦的最低值为-1,最高值为1

公式是

 x = (c * x - s * y +1) *0.5f;
 y = ( s * t + c * y +1)*0.5f;

这仅适用于纹理的顶点还是整个圆?我是否应该制定一种方法来设置纹理顶点,这是唯一的区别?这仅适用于纹理的“顶点:)。纹理空间中的坐标称为UV(因此在glTexCoordPointer函数调用中传递的缓冲区)。顶点(多个顶点)是由两个位置(XYZ)和UV.Okey组成的,因为结果相当粗糙,虽然看起来只有一张图片被渲染,但不可能看到图片重组的内容。我将补充我问题中的代码。这可能与您使用三角形扇形方法有关(你可以看到圆的中心在右侧,顶点1位于右侧)。尝试在中心创建第一个顶点(因此0,0为位置,0.5,0.5为UV),然后根据你的算法生成其他顶点。此外,对于纹理,“半径”始终为1.0f(当你想画一个更大的圆时,请记住这一点)。顺便说一句,我想我找到了其他的东西。对于UV,x应该是x=(sin(θ)+1)/2,而y=(cos(θ)+1)/2。你的公式似乎在2D中旋转点,你不想这样。所以textextextexts[0][0]=0.5,textextextextextextextextexts[0][1]=0.5,然后textextextextextextextextexts[1..[1][]=(sin(θ+1))/2,textextextexts[1..n][1]=(cos(θ+1))/2。这将根据三角形扇形为您提供UV,第一个顶点位于中心。确保您的顶点位置公式也遵循相同的规则,否则您可能会得到另一个模糊外观纹理。首先绘制一个5顶点的圆以获得更清晰的效果(一个正方形)!