2016-08-11 11 views
0

Я новичок в разработке android opengl. Я хочу заполнить многоугольник изображением, как показано ниже, используя opengl-es 2.0 в android. Я могу рисовать квадрат, треугольник, но не смог заполнить его повторяющимся изображением. Кто-нибудь знает, пожалуйста, помогите мне.как заполнить многоугольник с изображением в opengles 2.0 android

Square.java

public class Square { 

private final String vertexShaderCode = 
     "uniform mat4 uMVPMatrix;" + 
     "attribute vec4 vPosition;" + 
     "attribute vec2 a_TextureCoordinates;" + 
     "varying vec2 v_TextureCoordinates;" + 
     "void main() {" +      
     " gl_Position = uMVPMatrix * vPosition;" + 
     " v_TextureCoordinates = a_TextureCoordinates;" + 
     "}";  
private final String fragmentShaderCode = 
     "precision mediump float;" + 
     "uniform sampler2D u_TextureUnit;"+ 
     "varying vec2 v_TextureCoordinates;" + 
     "void main() {" + 
     " gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);" + 
     "}"; 
private final FloatBuffer vertexBuffer; 
private final FloatBuffer textureBuffer; 
private final ShortBuffer drawListBuffer; 
private final int mProgram; 
private int mPositionHandle; 
private int mColorHandle; 
private int mMVPMatrixHandle; 
static final int COORDS_PER_VERTEX = 3; 
static float squareCoords[] = { 

    -1.0f, 1.0f, 0.0f, // top left 
    1.0f, 1.0f, 0.0f, // top right 
    1.0f, -1.0f, 0.0f, // bottom right 
    -1.0f, -1.0f, 0.0f // bottom left 
    }; 

final float[] previewTextureCoordinateData = 
    { 
     0.0f,0.0f, // top left 
     1.0f,0.0f, // Top-right 
     1.0f,1.0f, // Bottom-right   
     0.0f,1.0f, // Bottom-left 
    }; 
private int textureDataHandle; 
private int textureUniformHandle; 
private int textureCoordinateHandle; 

private final short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; 
float color[] = { 0.2f, 0.709803922f, 0.898039216f, 1.0f }; 
private int loadTexture(final Context context, final int resourceId){ final int[] textureHandle = new int[1]; 

GLES20.glGenTextures(1, textureHandle, 0); 

if (textureHandle[0] != 0) 
{ 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inScaled = false; // No pre-scaling 

    // Read in the resource 
    final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options); 

    // Bind to the texture in OpenGL 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]); 

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); 

    // Set filtering 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 

    // Load the bitmap into the bound texture. 
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 

    // Recycle the bitmap, since its data has been loaded into OpenGL. 
    bitmap.recycle(); 
} 

if (textureHandle[0] == 0) 
{ 
    throw new RuntimeException("Error loading texture."); 
} 

return textureHandle[0];} 

public Square(Context c) { 
    // initialize vertex byte buffer for shape coordinates 
    ByteBuffer bb = ByteBuffer.allocateDirect(
    // (# of coordinate values * 4 bytes per float) 
      squareCoords.length * 4); 
    bb.order(ByteOrder.nativeOrder()); 
    vertexBuffer = bb.asFloatBuffer(); 
    vertexBuffer.put(squareCoords); 
    vertexBuffer.position(0); 

    // initialize byte buffer for the draw list 
    ByteBuffer dlb = ByteBuffer.allocateDirect(
      // (# of coordinate values * 2 bytes per short) 
      drawOrder.length * 2); 
    dlb.order(ByteOrder.nativeOrder()); 
    drawListBuffer = dlb.asShortBuffer(); 
    drawListBuffer.put(drawOrder); 
    drawListBuffer.position(0); 

    ByteBuffer texCoordinates = ByteBuffer.allocateDirect(previewTextureCoordinateData.length * 4); 
    texCoordinates.order(ByteOrder.nativeOrder()); 
    textureBuffer = texCoordinates.asFloatBuffer(); 
    textureBuffer.put(previewTextureCoordinateData); 
    textureBuffer.position(0); 


    // prepare shaders and OpenGL program 
    int vertexShader = MyGLRenderer.loadShader(
      GLES20.GL_VERTEX_SHADER, 
      vertexShaderCode); 
    int fragmentShader = MyGLRenderer.loadShader(
      GLES20.GL_FRAGMENT_SHADER, 
      fragmentShaderCode); 

    textureDataHandle = loadTexture(c, R.drawable.air_hockey_surface); 

    mProgram = GLES20.glCreateProgram();    // create empty OpenGL Program 
    GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program 
    GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program 
    GLES20.glLinkProgram(mProgram);     // create OpenGL program executables 
} 

public void draw(float[] mvpMatrix) { 
    // Add program to OpenGL environment 
    GLES20.glUseProgram(mProgram); 

    // get handle to vertex shader's vPosition member 
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); 

    // Enable a handle to the triangle vertices 
    GLES20.glEnableVertexAttribArray(mPositionHandle); 

    // Prepare the triangle coordinate data 
    GLES20.glVertexAttribPointer(
      mPositionHandle, COORDS_PER_VERTEX, 
      GLES20.GL_FLOAT, false, 
      vertexStride, vertexBuffer); 

    textureCoordinateHandle = GLES20.glGetAttribLocation(mProgram, "a_TextureCoordinates"); 
    GLES20.glVertexAttribPointer(textureCoordinateHandle, 2, GLES20.GL_FLOAT, false, 
      0, textureBuffer); 
    GLES20.glEnableVertexAttribArray(textureCoordinateHandle); 

    textureUniformHandle = GLES20.glGetUniformLocation(mProgram, "u_TextureUnit"); 
    MyGLRenderer.checkGlError("glGetUniformLocation"); 
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureDataHandle); 
    GLES20.glUniform1i(textureUniformHandle, 0);  

    // get handle to shape's transformation matrix 
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); 
    MyGLRenderer.checkGlError("glGetUniformLocation"); 

    // Apply the projection and view transformation 
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0); 
    MyGLRenderer.checkGlError("glUniformMatrix4fv"); 

    // Draw the square 
    GLES20.glDrawElements(
      GLES20.GL_TRIANGLES, drawOrder.length, 
      GLES20.GL_UNSIGNED_SHORT, drawListBuffer); 

    // Disable vertex array 
    GLES20.glDisableVertexAttribArray(mPositionHandle); 
}} 

Fill polygon with Image

+1

Что вы пробовали? Вы, кажется, знаете о текстурах, так как вы отметили их вопрос. Так что посмотрите на некоторые текстурные уроки. Для текстуры, чтобы повторить все, что вам нужно, это установить координаты таким образом и использовать параметр повторения на текстуре. –

+0

@ MaticOblak..Я хочу заполнить простой квадрат с изображением. Я хочу эту текстуру или узор в многоугольнике, используя opengl-es –

+1

Снова: Вы искали рисование текстуры? Если нет, то взгляните на него. Если да, то уточните, где находится ваша проблема. –

ответ

3

Если вы хотите, чтобы текстура повторить вам необходимо установить такие координаты текстуры. Координата текстуры является относительным положением пикселей в текстуре, где (0.0, 0,0) - верхнее левое положение на изображении, а (1.0, 1.0) - нижний правый. Теперь, независимо от координат вершин, отображаемая текстурная часть всегда будет одинаковой. В вашем случае тогда

final float[] previewTextureCoordinateData = 
    { 
     0.0f,0.0f, // top left 
     1.0f,0.0f, // Top-right 
     1.0f,1.0f, // Bottom-right   
     0.0f,1.0f, // Bottom-left 
    }; 

означает, что вы будете рисовать целую текстуру на объекте. Для того, чтобы сделать его повторить, например, 3 раза в каждом из измерений нужно умножить эти:

final float[] previewTextureCoordinateData = 
    { 
     0.0f,0.0f, // top left 
     1.0f*3.0,0.0f, // Top-right 
     1.0f*3.0,1.0f*3.0, // Bottom-right   
     0.0f,1.0f*3.0, // Bottom-left 
    }; 

Повторяющийся уже включен на текстуре, так что должно быть.

+0

... спасибо за вашу поддержку. Это работает. –