Search code examples
opengl-esgeometrytexturesdraw

How to draw texture circle opengl-es?


my friend has a problem with draw texture circle in opengl-es, and he can't post his quation in this site and he ask me to do that for him and he will follow up on the post and reply back through my account .

so, if there is no wrong in this thing, or this does not violate the terms of the site please help .

his quation :

how to draw texture circle opengl-es ?

this is his code :

package com.test;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

class TextureBall {
    private FloatBuffer vertexBuffer; // Buffer for vertex-array
    private FloatBuffer texBuffer;    // Buffer for texture-coords-array (NEW)
    private int points=360;
    private float vertices[]={0.0f,0.0f,0.0f};
    private FloatBuffer vertBuff;

    float[] texCoords = { // Texture coords for the above face (NEW)
            0.0f, 1.0f,  // A. left-bottom (NEW)
            1.0f, 1.0f,  // B. right-bottom (NEW)
            0.0f, 0.0f,  // C. left-top (NEW)
            1.0f, 0.0f   // D. right-top (NEW)
    };
    int[] textureIDs = new int[1];   // Array for 1 texture-ID (NEW)
    public TextureBall() {

    // Setup vertex-array buffer. Vertices in float. An float has 4 bytes
        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
        vbb.order(ByteOrder.nativeOrder()); // Use native byte order
        vertexBuffer = vbb.asFloatBuffer(); // Convert from byte to float
        vertexBuffer.put(vertices);         // Copy data into buffer
        vertexBuffer.position(0);           // Rewind


    }
    // Draw the shape
    public void draw(GL10 gl) {


        vertices=new float[(points+1)*3];
        for(int i=3;i<(points+1)*3;i+=3){
            double rad=(i*360/points*3)*(3.14/180);
            vertices[i]=(float)Math.cos(rad);
            vertices[i+1]=(float) Math.sin(rad);
            vertices[i+2]=0;
        }
        ByteBuffer bBuff=ByteBuffer.allocateDirect(vertices.length*4);
        bBuff.order(ByteOrder.nativeOrder());
        vertBuff=bBuff.asFloatBuffer();
        vertBuff.put(vertices);
        vertBuff.position(0);





        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);  // Disable texture-coords-array (NEW)
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisable(GL10.GL_CULL_FACE);
    };

    // Load an image into GL texture
    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 "res\drawable\nehe.png"
        InputStream istream = context.getResources().openRawResource(R.drawable.nehe);
        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();
    }
}

please help him to solve this problem .


Solution

  • Create an array of vertex coordinates and texture coordinates. The first point is the center point. The other points are on the circle:

    vertices  = new float[(points+2) * 3];
    texCoords = new float[(points+2) * 2];
    
    vertices[0] = vertices[1] = vertices[2] = 0;
    texCoords[0] = texCoords[1] = 0.5;
    
    for(int i=0; i <= points; i ++ ){
    
        double rad = (i * 360.0 / points) * (3.14/180);
        vertices[(i+1)*3+0] = (float)Math.cos(rad);
        vertices[(i+1)*3+1] = (float)Math.sin(rad);
        vertices[(i+1)*3+2] = 0;
    
        texCoords[(i+1)*2+0] = 0.5 + 0.5 * Math.cos(rad);
        texCoords[(i+1)*2+1] = 0.5 - 0.5 * Math.sin(rad);
    } 
    

    Define the buffer for the texture coordinates as you do it for the vertex coordinates. e.g.:

    ByteBuffer bTBuff = ByteBuffer.allocateDirect(texCoords .length*4);
    bTBuff.order(ByteOrder.nativeOrder());
    texBuff = bBuff.asFloatBuffer();
    texBuff.put(texCoords );
    texBuff.position(0);
    

    See also Java Code Examples for java.nio.FloatBuffer

    Define an array of vertex data (glVertexPointer) and texture coordinates (glTexCoordPointer):

    gl.glVertexPointer(3, 0, vertBuff); 
    gl.glTexCoordPointer(2, 0, texBuff);
    

    See also Java Code Examples for org.lwjgl.opengl.GL11.glVertexPointer()

    Enable the client state (glEnableClientState) for the vertex coordinates and texture coordinates:

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    

    Bind the texture and enable 2 dimensional texturing (glEnable):

    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[0]); 
    gl.glEnable(GL10.GL_TEXTURE_2D);
    

    See also Java Code Examples for org.lwjgl.opengl.GL11.glEnable()

    Draw the use the primitive type GL_TRIANGLE_FAN and draw the circular shape by glDrawArrays

    gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, points+2);
    

    See also Java Code Examples for org.lwjgl.opengl.GL11.glDrawArrays()