0

I am beginner in openGL. i am created a prism ( each face is equilateral triangle ) in android using openGL library and i am able to rotate the prism successfully. but my requirment is to put three different images in each face of the prism and i am not able to put the images. when i am putting the image it is scaling and mapping to all faces.

MyRenderer Class

public class MyRenderer implements Renderer {

/** Cube instance */

/* Rotation values for all axis */
private float xrot;             //X Rotation ( NEW )
private float yrot;             //Y Rotation ( NEW )
private float zrot;             //Z Rotation ( NEW )

/** The Activity Context ( NEW ) */
private Context context;
private Pyramid pyramid;
/**
 * Instance the Cube object and set 
 * the Activity Context handed over
 */

public MyRenderer(Context context) {
    this.context = context;

    pyramid = new Pyramid(this.context);

}

/**
 * The Surface is created/init()
 */
public void onSurfaceCreated(GL10 gl, EGLConfig config) {       
    //Load the texture for the cube once during Surface creation


    gl.glEnable(GL10.GL_TEXTURE_2D);            //Enable Texture Mapping ( NEW )
    gl.glShadeModel(GL10.GL_SMOOTH);            //Enable Smooth Shading
    gl.glClearColor(1.0f, 1.0f, 1.0f, 0.5f);    //Black Background
    gl.glClearDepthf(1.0f);                     //Depth Buffer Setup
    gl.glEnable(GL10.GL_DEPTH_TEST);            //Enables Depth Testing
    gl.glDepthFunc(GL10.GL_LEQUAL);             //The Type Of Depth Testing To Do

    //Really Nice Perspective Calculations
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 
}

/**
 * Here we do our drawing
 */

public void onDrawFrame(GL10 gl) {

    //Clear Screen And Depth Buffer
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);    
    gl.glLoadIdentity();                    //Reset The Current Modelview Matrix

    //Drawing
    gl.glTranslatef(0.0f, -1.0f, -5.0f);        //Move 5 units into the screen
    gl.glScalef(1.0f, 1.0f, 1.0f);          //Scale the Cube to 80 percent, otherwise it would be too large for the screen

    //Rotate around the axis based on the rotation matrix (rotation, x, y, z)
     gl.glRotatef(yrot, 0.0f, 1.65f, 0.0f); //X

     pyramid.draw(gl, context);

     yrot += 1.0f;

}

/**
 * If the surface changes, reset the view
 */

public void onSurfaceChanged(GL10 gl, int width, int height) {
    if(height == 0) {                       //Prevent A Divide By Zero By
        height = 1;                         //Making Height Equal One
    }

    gl.glViewport(0, 0, width, height);     //Reset The Current Viewport
    gl.glMatrixMode(GL10.GL_PROJECTION);    //Select The Projection Matrix
    gl.glLoadIdentity();                    //Reset The Projection Matrix

    //Calculate The Aspect Ratio Of The Window
    GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);

    gl.glMatrixMode(GL10.GL_MODELVIEW);     //Select The Modelview Matrix
    gl.glLoadIdentity();                    //Reset The Modelview Matrix
}

}

MyPyramid class

public class Pyramid {

/** The buffer holding the vertices */
private FloatBuffer vertexBuffer;
/** The buffer holding the color values */
private FloatBuffer colorBuffer;

private ByteBuffer indexBuffer;

private FloatBuffer textureBuffer;

private int noOfFaces = 3;

private int[] texturesID = new int[3];

private float PyramidVertices [] = {

                                          0.0f, 1.65f, 0.0f,
                                         -1.3f, 0.0f, 1.0f, 
                                          1.3f, 0.0f, 1.0f, 
                                          0.0f, 0.0f, -1.65f, 

};


 private float textures[] = {           
            //Mapping coordinates for the vertices
            0.0f, 1.65f,
            0.0f, 1.65f,
            -1.3f, 0.0f,
            1.3f, 0.0f,

    };



 private float colors[] = {
    1.0f, 0.0f, 0.0f, 1.0f, //Red
    0.0f, 1.0f, 0.0f, 1.0f, //Green
    0.0f, 0.0f, 1.0f, 1.0f, //Blue
    1.0f, 0.0f, 0.0f, 1.0f, //Red

 };


 private byte indices [] =  {   0, 2, 1,
          0, 2, 3,
          0, 1, 3,
        };

/**
 * The Pyramid constructor.
 * 
 * Initiate the buffers.
 */
public Pyramid( Context context) {
    //
    ByteBuffer byteBuf = ByteBuffer.allocateDirect(PyramidVertices.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    vertexBuffer = byteBuf.asFloatBuffer();
    vertexBuffer.put(PyramidVertices);
    vertexBuffer.position(0);

    byteBuf = ByteBuffer.allocateDirect(colors.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    colorBuffer = byteBuf.asFloatBuffer();
    colorBuffer.put(colors);
    colorBuffer.position(0);

    indexBuffer = ByteBuffer.allocateDirect(indices.length);
    indexBuffer.put(indices);
    indexBuffer.position(0);

    byteBuf = ByteBuffer.allocateDirect(textures.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    textureBuffer = byteBuf.asFloatBuffer();
    textureBuffer.put(textures);
    textureBuffer.position(0);
}

/**
 * The object own drawing function.
 * Called from the renderer to redraw this instance
 * with possible changes in values.
 * 
 * @param gl - The GL Context
 */


public void draw(GL10 gl, Context context) {    
    //Set the face rotation
//  gl.glFrontFace(GL10.GL_CW);
    gl.glCullFace(GL10.GL_CCW);

     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    // gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);

        loadTexture(gl, context);

        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

        gl.glEnable(GL10.GL_TEXTURE_2D);

        // Enable the texture state
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        // Point to our buffers
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);


        gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);

    //Disable the client state before leaving
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);


}

      public void loadTexture(GL10 gl, Context context) {

          Bitmap bitmap;

          gl.glGenTextures(3, texturesID, 0); // Generate texture-ID array for 6 IDs

          gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesID[2]);

          InputStream is = context.getResources().openRawResource(R.drawable.forward);

          try {
                //BitmapFactory is an Android graphics utility for images

                bitmap = BitmapFactory.decodeStream(is);

            } finally {
                //Always clear and close
                try {
                    is.close();
                    is = null;
                } catch (IOException e) {
                }
            }


          // Generate OpenGL texture images

       // Create Nearest Filtered Texture
          gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
                  GL10.GL_LINEAR);
          gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
                  GL10.GL_LINEAR);

          // Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
          gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
                  GL10.GL_CLAMP_TO_EDGE);
          gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                  GL10.GL_REPEAT);

             // Build Texture from loaded bitmap for the currently-bind texture ID

          GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);



      }

and i took the help from http://www3.ntu.edu.sg/home/ehchua/programming/android/Android_3D.html http://nehe.gamedev.net/

How to give different images on each face?

genpfault
  • 51,148
  • 11
  • 85
  • 139
Aalok
  • 325
  • 5
  • 14

2 Answers2

0

There are few ways of doing this but here are the simplest two for you to try:

Modify object to your needs

It's quite tricky to use few textures at a time and select them per-face, but the simple solution is to divide your pyramid into few objects. Then, you can assign different texture for each of your objects as you like.

Modify texture to your needs

You can use a technique known as Texture Atlas. In this solution you can take few textures and stitch them together into one, bigger bitmap. Then you use this bitmap as your main texture. You also need to modify your vertices UVs, so one of your triangles uses some part of your bigger texture, while another triangle uses different part of your texture. Using this technique you can get an appearance that different triangles use totally different images as their texture (even that there's just one real texture during rendering).

Let us know if you need more details about it.

kolenda
  • 2,741
  • 2
  • 19
  • 30
  • can u please give me an example of how to divide the my pyramid in objects ?. – Aalok Jun 06 '14 at 04:22
  • Instead of drawing four triangles at once you can modify your pyramid to draw one triangle four times, and each time you can select another texture. You can do all this drawing in the buffer you already have: http://stackoverflow.com/questions/9431923/using-an-offset-with-vbos-in-opengl – kolenda Jun 06 '14 at 10:54
  • i followed the same approach and i found the answer i pasted my solution. – Aalok Jun 06 '14 at 15:29
0

Thanks for response.

I found the solution for my problem. I created a equilateral triangle and then by giving the proper rotation angle i am able to rotate it as well as i put the different texture in each face.

MyPyramid class

public class PyramidNew {

   int []texturesID = new int[3];

   Bitmap []bitmap = new Bitmap[3];

  private FloatBuffer textureBuffer;

   private FloatBuffer vertexBuffer;  // Buffer for vertex-array

   private float[][] colors = {  // Colors of the 6 faces
      {1.0f, 0.5f, 0.0f, 1.0f},  // 0. orange
      {1.0f, 0.0f, 1.0f, 1.0f},  // 1. violet
      {0.0f, 1.0f, 0.0f, 1.0f},  // 2. green
      {0.0f, 0.0f, 1.0f, 1.0f},  // 3. blue
      {1.0f, 0.0f, 0.0f, 1.0f},  // 4. red
      {1.0f, 1.0f, 0.0f, 1.0f}   // 5. yellow
   };

/*   private float[] vertices = {  // Vertices for the front face
      -1.5f,  0.0f, 0.86f,  // 0. left-bottom-front
       1.5f,  0.0f, 0.86f,  // 1. right-bottom-front
       0.0f,  1.86f, 0.0f,  // 2. left-top-front
         // 3. right-top-front
   };*/
   private float[] vertices = {  // Vertices for the front face
              -1.0f,  0.0f, 0.86f,  // 0. left-bottom-front
               1.0f,  0.0f, 0.86f,  // 1. right-bottom-front
               0.0f,  1.86f, 0.0f,  // 2. left-top-front
                 // 3. right-top-front
           };
   private float textures[] = {         
            //Mapping coordinates for the vertices
            0.0f, 0.0f,
            0.0f, 1.0f,
            1.0f, 1.0f,

    };

   // Constructor - Set up the buffers
   public PyramidNew( Context context) {
     // Setup vertex-array buffer. Vertices in float. An float has 4 bytes
      System.out.println("calling Pyramid:::::::::");
      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

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


     InputStream stream1 = context.getResources().openRawResource(R.drawable.splash_screen);
     InputStream stream2 = context.getResources().openRawResource(R.drawable.bg);
     InputStream stream3 = context.getResources().openRawResource(R.drawable.bg1);


      try {
            //BitmapFactory is an Android graphics utility for images

            bitmap[0] = BitmapFactory.decodeStream(stream1);
            bitmap[1] = BitmapFactory.decodeStream(stream2);
            bitmap[2] = BitmapFactory.decodeStream(stream3);

        } finally {
            //Always clear and close
            try {
                stream1.close();
                stream2.close();
                stream3.close();

                stream1 = stream2 = stream3 = null;
            } catch (IOException e) {
            }
        }


   }

   // Draw the color cube
   public void draw(GL10 gl, Context context) {
      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)

      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
      gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);


      //loading the first texture in first face
      loadTexture(gl, context, 0);
      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 3);

      // rotating the face and puting the second texture in face
      gl.glRotatef(120.0f, 0.0f, 1.0f, 0.0f);
      //gl.glColor4f(colors[1][0], colors[1][1], colors[1][2], colors[1][3]);
      loadTexture(gl, context, 1);
      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 3);

      // Back - Rotate another 120 degree about y-axis and then put different texture
      gl.glRotatef(120.0f, 0.0f, 1.0f, 0.0f);
      //gl.glColor4f(colors[2][0], colors[2][1], colors[2][2], colors[2][3]);
      loadTexture(gl, context, 2);
      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 3);

      gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glDisable(GL10.GL_CULL_FACE);
   }


   public void loadTexture(GL10 gl, Context context, int currentImage) {

        //  Bitmap []bitmap = new Bitmap[3];

          gl.glGenTextures(3, texturesID, 0); // Generate texture-ID array for 6 IDs

          gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesID[currentImage]);

          // Generate OpenGL texture images

       // Create Nearest Filtered Texture
          gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
                  GL10.GL_LINEAR);
          gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
                  GL10.GL_LINEAR);

          // Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
          gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
                  GL10.GL_CLAMP_TO_EDGE);
          gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                  GL10.GL_REPEAT);

             // Build Texture from loaded bitmap for the currently-bind texture ID

          GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[currentImage], 0);

            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

            gl.glEnable(GL10.GL_TEXTURE_2D);

            // Enable the texture state
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

            // Point to our buffers
            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);



      }

}

Aalok
  • 325
  • 5
  • 14