I recently used moho example to create a cube in android with OpenGLES 1.1 and I don't know why it works on some devices and not work on others with same Android version.
If someone can help me...
This is MyGLRenderer:
public class MyGLRenderer implements GLSurfaceView.Renderer {
Context context; // Application's context
private Cube cube;
private Triangle triangle;
private final float[] mRotationMatrix = new float[16];
// Constructor with global application context
public MyGLRenderer(Context context) {
this.context = context;
this.cube = new Cube();
this.triangle = new Triangle();
initRotationMatrix();
}
private void initRotationMatrix() {
mRotationMatrix[0] = 1;
mRotationMatrix[4] = 1;
mRotationMatrix[8] = 1;
mRotationMatrix[12] = 1;
}
// Call back when the surface is first created or re-created
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Set color's clear-value to black
gl.glClearDepthf(1.0f); // Set depth's clear-value to farthest
gl.glEnable(GL10.GL_DEPTH_TEST); // Enables depth-buffer for hidden surface removal
gl.glDepthFunc(GL10.GL_LEQUAL); // The type of depth testing to do
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); // nice perspective view
gl.glShadeModel(GL10.GL_SMOOTH); // Enable smooth shading of color
gl.glDisable(GL10.GL_DITHER); // Disable dithering for better performance
// You OpenGL|ES initialization code here
// ......
}
// Call back after onSurfaceCreated() or whenever the window's size changes
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if (height == 0) height = 1; // To prevent divide by zero
float aspect = (float)width / height;
// Set the viewport (display area) to cover the entire window
gl.glViewport(0, 0, width, height);
// Setup perspective projection, with aspect ratio matches viewport
gl.glMatrixMode(GL10.GL_PROJECTION); // Select projection matrix
gl.glLoadIdentity(); // Reset projection matrix
// Use perspective projection
GLU.gluPerspective(gl, 45, aspect, 0.1f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); // Select model-view matrix
gl.glLoadIdentity(); // Reset
}
// Call back to draw the current frame.
#Override
public void onDrawFrame(GL10 gl) {
// Clear color and depth buffers using clear-value set earlier
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// ----- Render the Color Cube -----
gl.glLoadIdentity(); // Reset the model-view matrix
gl.glTranslatef(cube.getPosX(), cube.getPosY(), cube.getPosZ()); // Translate
gl.glScalef(0.8f, 0.8f, 0.8f); // Scale down (NEW)
gl.glRotatef(cube.getAngleX(), 1.0f, 0.0f, 0.0f); // rotate about the axis (1, 1, 1) (NEW)
gl.glRotatef(cube.getAngleY(), 0.0f, 1.0f, 0.0f); // rotate about the axis (1, 1, 1) (NEW)
gl.glRotatef(cube.getAngleZ(), 0.0f, 0.0f, 1.0f); // rotate about the axis (1, 1, 1) (NEW)
gl.glMultMatrixf(mRotationMatrix, 0);
//cube.setAngleX(cube.getAngleX() - 1.5f);
//cube.setAngleY(cube.getAngleY() - 1.5f);
//cube.setAngleZ(cube.getAngleZ() - 1.5f);
// LIGHT
// float[] position = {0f, -5f, 0f, 1f};
// float[] ambient = {1f, 1f, 1f, 1f};
// float[] direction = {0f, 1f, 0f};
// gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, position, 0);
// gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, ambient, 0);
// gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPOT_DIRECTION, direction, 0);
// gl.glLightf(GL10.GL_LIGHT0, GL10.GL_SPOT_CUTOFF, 100.0f);
//
// gl.glEnable(GL10.GL_LIGHTING);
// gl.glEnable(GL10.GL_LIGHT0);
cube.draw(gl);
// triangle.draw(gl);
}
public Cube getCube() {
return cube;
}
public float[] getmRotationMatrix() {
return mRotationMatrix;
}
}
This is my Cube class:
public class Cube {
private FloatBuffer vertexBuffer; // Buffer for vertex-array
private int numFaces = 6;
private float posX = 0.0f, posY = 0.0f, posZ = -6.0f;
private float angleX = 0.0f, angleY = 0.0F, angleZ = 0.0f;
/*
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. purple
{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[][] colors = { // Colors of the 6 faces
{0.0f, 1.0f, 0.0f, 1.0f}, // green
{0.0f, 1.0f, 0.0f, 1.0f}, // green
{0.0f, 1.0f, 0.0f, 1.0f}, // green
{0.0f, 1.0f, 0.0f, 1.0f}, // green
{0.0f, 1.0f, 0.0f, 1.0f}, // green
{0.0f, 1.0f, 0.0f, 1.0f} // green
};
private float[] vertices = { // Vertices of the 6 faces
// FRONT
-1.0f, -1.0f, 1.0f, // 0. left-bottom-front
1.0f, -1.0f, 1.0f, // 1. right-bottom-front
-1.0f, 1.0f, 1.0f, // 2. left-top-front
1.0f, 1.0f, 1.0f, // 3. right-top-front
// BACK
1.0f, -1.0f, -1.0f, // 6. right-bottom-back
-1.0f, -1.0f, -1.0f, // 4. left-bottom-back
1.0f, 1.0f, -1.0f, // 7. right-top-back
-1.0f, 1.0f, -1.0f, // 5. left-top-back
// LEFT
-1.0f, -1.0f, -1.0f, // 4. left-bottom-back
-1.0f, -1.0f, 1.0f, // 0. left-bottom-front
-1.0f, 1.0f, -1.0f, // 5. left-top-back
-1.0f, 1.0f, 1.0f, // 2. left-top-front
// RIGHT
1.0f, -1.0f, 1.0f, // 1. right-bottom-front
1.0f, -1.0f, -1.0f, // 6. right-bottom-back
1.0f, 1.0f, 1.0f, // 3. right-top-front
1.0f, 1.0f, -1.0f, // 7. right-top-back
// TOP
-1.0f, 1.0f, 1.0f, // 2. left-top-front
1.0f, 1.0f, 1.0f, // 3. right-top-front
-1.0f, 1.0f, -1.0f, // 5. left-top-back
1.0f, 1.0f, -1.0f, // 7. right-top-back
// BOTTOM
-1.0f, -1.0f, -1.0f, // 4. left-bottom-back
1.0f, -1.0f, -1.0f, // 6. right-bottom-back
-1.0f, -1.0f, 1.0f, // 0. left-bottom-front
1.0f, -1.0f, 1.0f // 1. right-bottom-front
};
// Constructor - Set up the buffers
public Cube() {
// 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) {
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);
// Render all the faces
for (int face = 0; face < numFaces; face++) {
// Set the color for each of the faces
gl.glColor4f(colors[face][0], colors[face][1], colors[face][2], colors[face][3]);
// Draw the primitive from the vertex-array directly
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, face * 4, 4);
}
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
}
public float getPosX() {
return posX;
}
public void setPosX(float posX) {
this.posX = posX;
}
public float getPosY() {
return posY;
}
public void setPosY(float posY) {
this.posY = posY;
}
public float getPosZ() {
return posZ;
}
public void setPosZ(float posZ) {
this.posZ = posZ;
}
public float getAngleX() {
return angleX;
}
public void setAngleX(float angleX) {
this.angleX = angleX;
}
public float getAngleY() {
return angleY;
}
public void setAngleY(float angleY) {
this.angleY = angleY;
}
public float getAngleZ() {
return angleZ;
}
public void setAngleZ(float angleZ) {
this.angleZ = angleZ;
}
The code is ok. I think it's related to your device. Whether your device support OpenGLES1.1? Did you try to use some code like
mGlSurfaceView.setEGLContextClientVersion(1);
to define the version. Maybe the device's default OpenGLES version is 2.0(or the device do not support version 1.1). I am not sure about this, but I think it maybe an idea.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
package com.example.assignment1;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
public class Tetrahedron {
private FloatBuffer vertexBuffer; // Buffer for vertex-array
private int numFaces = 4;
//color codes for 4 faces
private float[][] colors = { // Colors of the 4 faces
{1.0f, 0.0f, 0.0f, 1.0f}, // 0. red
{1.0f, 1.0f, 1.0f, 1.0f}, // 1. white
{0.0f, 0.0f, 1.0f, 1.0f}, // 2. blue
{0.5019f, 0.5019f, 0.5019f, 1.0f}, // 3. grey
};
//coordinates of vertices of faces
//did i specified sequence correctly?
private float[] vertices = { // Vertices of the 4 faces
// FRONT Face
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
//Right face
-1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
// Left Face
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
// BOTTOM
-1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f
};
// Constructor - Set up the buffers
public Tetrahedron() {
// 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) {
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);
// Render all the faces
for (int face = 0; face < numFaces; face++) {
// Set the color for each of the faces
gl.glColor4f(colors[face][0], colors[face][1], colors[face][2], colors[face][3]);
// Draw the primitive from the vertex-array directly
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, face*4, 3);
}
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
}
}
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, face*4, 3);
should probably be
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, face*3, 3);
I am displaying images using openGL library. How to Display Different images on each face of cube in openGL ?
This is my mainactivity class.
package com.nea.nehe.lesson06;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
/**
* The initial Android Activity, setting and initiating
* the OpenGL ES Renderer Class #see Lesson06.java
*
* #author Savas Ziplies (nea/INsanityDesign)
*/
public class Run extends Activity {
/** The OpenGL View */
private GLSurfaceView glSurface;
/**
* Initiate the OpenGL View and set our own
* Renderer (#see Lesson06.java)
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Create an Instance with this Activity
glSurface = new GLSurfaceView(this);
//Set our own Renderer and hand the renderer this Activity Context
glSurface.setRenderer(new Lesson06(this));
//Set the GLSurface as View to this Activity
setContentView(glSurface);
}
/**
* Remember to resume the glSurface
*/
#Override
protected void onResume() {
super.onResume();
glSurface.onResume();
}
/**
* Also pause the glSurface
*/
#Override
protected void onPause() {
super.onPause();
glSurface.onPause();
}
}
This my Renderer class.
public class Lesson06 implements Renderer {
/** Cube instance */
private Cube cube;
/* 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;
/**
* Instance the Cube object and set
* the Activity Context handed over
*/
public Lesson06(Context context) {
this.context = context;
cube = new Cube();
}
/**
* The Surface is created/init()
*/
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//Load the texture for the cube once during Surface creation
cube.loadGLTexture(gl, this.context);
gl.glEnable(GL10.GL_TEXTURE_2D); //Enable Texture Mapping ( NEW )
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.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
gl.glActiveTexture(gl.GL_TEXTURE0);
//Drawing
gl.glTranslatef(0.0f, 0.0f, -5.0f); //Move 5 units into the screen
gl.glScalef(0.8f, 0.8f, 0.8f); //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(xrot, 1.0f, 0.0f, 0.0f); //X
gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f); //Y
gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f); //Z
cube.draw(gl); //Draw the Cube
//Change rotation factors (nice rotation)
xrot += 0.3f;
yrot += 0.2f;
zrot += 0.4f;
}
/**
* 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
}
}
And finally this is my cube class for drawing cube.
package com.nea.nehe.lesson06;
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;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/**
* This class is an object representation of
* a Cube containing the vertex information,
* texture coordinates, the vertex indices
* and drawing functionality, which is called
* by the renderer.
*
* #author Savas Ziplies (nea/INsanityDesign)
*/
public class Cube {
/** The buffer holding the vertices */
private FloatBuffer vertexBuffer;
/** The buffer holding the texture coordinates */
private FloatBuffer textureBuffer;
/** The buffer holding the indices */
private ByteBuffer indexBuffer;
/** Our texture pointer */
private int[] textures = new int[1];
/**
* The initial vertex definition
*
* Note that each face is defined, even
* if indices are available, because
* of the texturing we want to achieve
*/
private float vertices[] = {
//Vertices according to faces
-1.0f, -1.0f, 1.0f, //Vertex 0
1.0f, -1.0f, 1.0f, //v1
-1.0f, 1.0f, 1.0f, //v2
1.0f, 1.0f, 1.0f, //v3
1.0f, -1.0f, 1.0f, //...
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
};
/** The initial texture coordinates (u, v) */
private float texture[] = {
//Mapping coordinates for the vertices
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
};
/** The initial indices definition */
private byte indices[] = {
//Faces definition
0,1,3, 0,3,2, //Face front
4,5,7, 4,7,6, //Face right
8,9,11, 8,11,10, //...
12,13,15, 12,15,14,
16,17,19, 16,19,18,
20,21,23, 20,23,22,
};
/**
* The Cube constructor.
*
* Initiate the buffers.
*/
public Cube() {
//
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
//
byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
textureBuffer = byteBuf.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
//
indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.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) {
//Bind our only previously generated texture in this case
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
//Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//Set the face rotation
gl.glFrontFace(GL10.GL_CCW);
//Enable the vertex and texture state
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
//Draw the vertices as triangles, based on the Index Buffer information
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);
}
/**
* Load the textures
*
* #param gl - The GL Context
* #param context - The Activity context
*/
public void loadGLTexture(GL10 gl, Context context) {
//Get the texture from the Android resource directory
InputStream is = context.getResources().openRawResource(R.drawable.nehe);
Bitmap bitmap = null;
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 one texture pointer...
gl.glGenTextures(1, textures, 0);
//...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
//Create Nearest Filtered Texture
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);
//Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
//Use the Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
//Clean up
bitmap.recycle();
}
}
Im trying to make a basic shape ( Hexigon ) to start and learn some basics about OpenGL on the Android platform and i have a little problem.
I have successfully made a pointy Hexagon, but when i convert it into a flat Hexygon it doesnt render correctly. Here is some code, for you guys to figure out the problem ( probably a easy fix.. )
vertices / indices
//flat hexagon
private float verticesFlat[] = {
0.0f, 0.0f, 0.0f, //center
-0.5f, 1.0f, 0.0f, // left top
0.5f, 1.0f, 0.0f, // right top
1.0f, 0.0f, 0.0f, // right
0.5f, 1.0f, 0.0f, // right bottom
-0.5f, -1.0f, 0.0f, // left bottom
-1.0f, 0.0f, 0.0f, // left
};
private short[] indices = { 0, 1, 2, 3, 4, 5, 6, 1 };
standard vertex / index Buffers..
// a float is 4 bytes, therefore we multiply the number if
// vertices with 4.
ByteBuffer vbb = ByteBuffer.allocateDirect(verticesFlat.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(verticesFlat);
vertexBuffer.position(0);
// short is 2 bytes, therefore we multiply the number if
// vertices with 2.
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
The onDraw(GL10 gl):
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glDrawElements(GL10.GL_TRIANGLE_FAN, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
The result im getting is illustrated in the image below:
Should be
private float verticesFlat[] = {
0.0f, 0.0f, 0.0f, //center
-0.5f, 1.0f, 0.0f, // left top
0.5f, 1.0f, 0.0f, // right top
1.0f, 0.0f, 0.0f, // right
0.5f, -1.0f, 0.0f, // right bottom (notice sign)
-0.5f, -1.0f, 0.0f, // left bottom
-1.0f, 0.0f, 0.0f, // left
};
I am just trying to understand what is going on here. I have a textured quad on the screen but I am really confused why it takes up the entire screen. If my texture is 64X64 and I wanted a quad at the top left of the screen that was 64X64 what would I need to change? Is my viewport or my vertices positions causing it to take up the whole screen?
With changes so far:
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
myquad.loadGLTexture(gl, this.context);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(gl.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glDisable(GL10.GL_DEPTH_TEST);
}
public void onSurfaceChanged(GL10 gl, int w, int h) {
width=w;
height=h;
gl.glViewport(0, 0, w, h);
gl.glLoadIdentity();
gl.glOrthof(0.0f, w, 0, h, -1.0f, 1.0f);
}
public void onDrawFrame(GL10 gl) {
// define the color we want to be displayed as the "clipping wall"
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// clear the color buffer to show the ClearColor we called above...
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
gl.glLoadIdentity();
myquad.Draw(gl);
//gl.glTranslatef(.5f, 2.0f, 0.0f);
//gl.glScalef(.5f, .5f, 0);
}
private float vertices[] = {
// Vertices for the square
-1.0f, -1.0f, 0.0f, // 0. left-bottom
1.0f, -1.0f, 0.0f, // 1. right-bottom
-1.0f, 1.0f, 0.0f, // 2. left-top
1.0f, 1.0f, 0.0f // 3. right-top
};
private float texture[] = {
//Mapping coordinates for the vertices
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
};
public void Draw(GL10 gl)
{
// set the color for the triangle
gl.glColor4f(0.0f, 1.0f, 0.0f, 0.5f);
//Enable the vertex and texture state
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texturebuffer);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexbuffer);
//gl.glTranslatex(-20, 0, 0);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
}
Right now you have your projection set up wrong. If you want to draw as if you were dealing with pixels, you would want...
this line
gl.glOrthof(0.0f, w, -h, 0.0f, -1.0f, 1.0f);
to be more like this
gl.glOrthof(0.0f, width, 0.0f, height, -1.0f, 1.0f);
where width and height are the size of your context in pixels.
EDIT:
gl.glOrthof(0.0f, w, -h, 0.0f, -1.0f, 1.0f);
has to be called after each call to glLoadIdentity().
Now you have to adjust your vertex coords. As right now they are set up to render a 1px by 1px box 1px outside the bottom left corner of the screen.
I wrote opengl android code to show a bitmap on a square. But bitmap was drawn in reverse. When i change texture array combination to the commented code it is drawn correctly. But i insist my texture array must be as below . Am i thinking wrong ?
/** The initial vertex definition */
private float vertices[] = {
-1.0f, 1.0f, 0.0f, //Top Left
-1.0f, -1.0f, 0.0f, //Bottom Left
1.0f, -1.0f, 0.0f, //Bottom Right
1.0f, 1.0f, 0.0f //Top Right
};
/** Our texture pointer */
private int[] textures = new int[1];
/** The initial texture coordinates (u, v) */
private float texture[] = {
//Mapping coordinates for the vertices
// 1.0f, 0.0f,
// 1.0f, 1.0f,
// 0.0f, 1.0f,
// 0.0f, 0.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
};
/** The initial indices definition */
private byte indices[] = {
//2 triangles
0,1,2, 2,3,0,
};
Whereas Android uses the top-left corner as being 0,0 of the coordinate system, OpenGL uses the bottom-left corner being 0,0 which is why your texture gets flipped.
A common solution to this is to flip your texture at load time,
Matrix flip = new Matrix();
flip.postScale(1f, -1f);
Bitmap bmp = Bitmap.createBitmap(resource, 0, 0, resource.getWidth(), resource.getHeight(), flip, true);
Actually, I think Will Kru's solution should have flipped the background around both axes
flip.postScale(-1f, -1f);
That solution worked for me!
This worked for me. (no need to create another bitmap and scale)
private float vertices[] = {
1.0f, -1.0f, 0.0f, //Bottom Right
1.0f, 1.0f, 0.0f, //Top Right
-1.0f, 1.0f, 0.0f, //Top Left
-1.0f, -1.0f, 0.0f, //Bottom Left
};