I have an GlSurfaceView that is drawing a square that i am trying to texturize with a image.png I have played with two different png files both in the same drawable folder.. When i reference one it loads just fine but if i switch the R.image.png to the other, my sqaure just turns white.. can anyone help? below is my square class, and my glView.
Square:
package com.eliddell.AR;
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;
public class Square {
private FloatBuffer vertexBuffer; // buffer holding the vertices
private float vertices[] = {
-1.0f, -1.0f, 0.0f, // V1 - bottom left
-1.0f, 1.0f, 0.0f, // V2 - top left
1.0f, -1.0f, 0.0f, // V3 - bottom right
1.0f, 1.0f, 0.0f // V4 - top right
};
private FloatBuffer textureBuffer; // buffer holding the texture coordinates
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
public Square() {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuffer.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
}
/** The texture pointer */
private int[] textures = new int[1];
public void loadGLTexture(GL10 gl, Context context) {
// loading texture
InputStream is = context.getResources().openRawResource(R.drawable.android);
Bitmap bitmap = BitmapFactory.decodeStream(is);
//Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.android);
// 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);
// Use 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();
}
public void draw(GL10 gl) {
// bind the previously generated texture
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_CW);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
}
and my GLSurfaceView and Render:
package com.eliddell.AR;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLU;
import android.content.Context;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.view.SurfaceHolder;
public class GLLayer extends GLSurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback, Renderer {
private Context context;
private Square square; // the triangle to be drawn
public GLLayer(Context context) {
super(context);
this.context = context;
this.square = new Square();
// settings for translucent glView
this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
// set render to inline
this.setRenderer(this);
}
#Override
public void onDrawFrame(GL10 gl) {
// clear Screen and Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glLoadIdentity();
// Drawing
gl.glTranslatef(0.0f, 0.0f, -5.0f); // move 5 units INTO the screen
// is the same as moving the camera 5 units away
square.draw(gl); // Draw the triangle
}
#Override
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
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
// Load the texture for the square
square.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.0f); //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);
}
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
// TODO Auto-generated method stub
}
}
Propably your texture dosent have power of two dimensions.
Opengl can load only textures witch have pot(power of two) size like: 32X32 , 64X64 , 128X128 ..... and not 36X36 , 48X48 ....
Change your image size.
Related
I have next problem.
I'm write some android app which uses opengl es 1.0
I'm using GLSurfaceView and custom Renderer. Here are methods of my custom renderer onDrawFrame, onSurfaceChanged, onSurfaceChanged:
#Override
public void onDrawFrame(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// clear Screen and Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glLoadIdentity();
// Drawing
gl.glTranslatef(0f, 0f, -3.0f); // move 5 units INTO the screen
// is the same as moving the camera 5 units away
// gl.glScalef(0.5f, 0.5f, 0.5f); // scale the square to 50%
// otherwise it will be too large
square.draw(gl, mScrollable.getIndexA(), mScrollable.getIndexB(), mScrollable.getAlphaValue()); // Draw the triangle
}
#Override
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, mWidth, mHeight); //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
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Load the texture for the square
square.loadGLTexture(gl, this.context);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
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);
}
And my Square class to render textures:
private int[] textures;
private GL10 mGl;
private FloatBuffer vertexBuffer; // buffer holding the vertices
private float vertices[] = {
-1.0f, -1.8f, 0.0f, // V1 - bottom left
-1.0f, 1.3f, 0.0f, // V2 - top left
1.0f, -1.8f, 0.0f, // V3 - bottom right
1.0f, 1.3f, 0.0f // V4 - top right
};
private FloatBuffer textureBuffer; // buffer holding the texture coordinates
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
private GlAnimationCache cacheHelper;
public void loadGLTexture(GL10 gl, Context context) {
// loading texture
mGl = gl;
gl.glGenTextures(mImageEntityList.size(), textures, 0);
cacheHelper = new GlAnimationCache(mContext, mImageEntityList, mGlRenderer, mGlSurfaceView);
cacheHelper.initCache(); //it init cache in background thread
}
public void removeTextureAt(int position){
mGl.glDeleteTextures(1, textures, position);
}
public void bindTextureAt(final Bitmap bitmap, int position){
// generate one texture poi, 0);
// ...and bind it to our array
mGl.glBindTexture(GL10.GL_TEXTURE_2D, textures[position]);
mGl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
mGl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// create nearest filtered texture
mGl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
mGl.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 Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLUtils.getInternalFormat(bitmap), bitmap, GLUtils.getType(bitmap), 0);
bitmap.recycle();
}
private int prevIndex = 0;
/** The draw method for the square with the GL context */
public void draw(GL10 gl, int indexA, int indexB, float alpha) {
// bind the previously generated texture
if(prevIndex != indexA){
cacheHelper.synchronizeCache(indexA);
prevIndex = indexA;
}
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[indexA]);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glColor4f(1, 1, 1, 1f);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[indexB]);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glColor4f(1, 1, 1, Math.abs(alpha));
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
So, the problem is next: On Samsung S5, Alcatel One Touch 4033D and Motorolla Droid Razr textures are rendered fine. But on Samsung Galaxy Nexus I see only 'white box'.
I have tried to change size of texture to power of 2(512 x 512) but it not helpes.
In Square class add function:
public boolean isNPOTSupported(GL10 gl) {
String extensions = gl.glGetString(GL10.GL_EXTENSIONS);
return extensions.indexOf("GL_OES_texture_npot") != -1;
}
And when you Generate textures, add this:
final boolean isNPOTSupported = isNPOTSupported(gl);
if(isNPOTSupported) {
gl.glGenTextures(mImageEntityList.size(), textures, 0);
}else{
for(int i = 0; i < mImageEntityList.size(); i++){
gl.glGenTextures(1, textures, i);
}
}
Instead this:
gl.glGenTextures(mImageEntityList.size(), textures, 0);
This is the actual code from NeHe's ports but it isn't drawing anything. Why ??
My main activity class :
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
/**
* Our OpenGL program's main activity
*/
public class Main extends Activity {
private GLSurfaceView glView; // Use GLSurfaceView
// Call back when the activity is started, to initialize the view
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
glView = new GLSurfaceView(this); // Allocate a GLSurfaceView
glView.setEGLContextClientVersion(1);
glView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
glView.setRenderer(new mainRenderer(this)); // Use a custom renderer
this.setContentView(glView); // This activity sets to GLSurfaceView
}
// Call back when the activity is going into the background
#Override
protected void onPause() {
super.onPause();
glView.onPause();
}
// Call back after onPause()
#Override
protected void onResume() {
super.onResume();
glView.onResume();
}
}
My renderer class :
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
/**
* OpenGL Custom renderer used with GLSurfaceView
*/
public class mainRenderer implements GLSurfaceView.Renderer {
Context context; // Application's context
Patrat quad;
// Constructor with global application context
public mainRenderer(Context context) {
this.context = context;
quad = new Patrat();
}
// Call back when the surface is first created or re-created
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0.0f, 0.0f, 0.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.f);
gl.glMatrixMode(GL10.GL_MODELVIEW); // Select model-view matrix
gl.glLoadIdentity(); // Reset
// You OpenGL|ES display re-sizing code here
// ......
}
// 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);
// You OpenGL|ES rendering code here
// ......
gl.glLoadIdentity();
quad.draw(gl);
}
}
My square class :
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
/*
* A square drawn in 2 triangles (using TRIANGLE_STRIP).
*/
public class Patrat {
private FloatBuffer vertexBuffer; // Buffer for vertex-array
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
};
// Constructor - Setup the vertex buffer
public Patrat() {
// Setup vertex array buffer. Vertices in float. A 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
}
// Render the shape
public void draw(GL10 gl) {
// Enable vertex-array and define its buffer
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
// Draw the primitives from the vertex-array directly
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
Any solutions please ? I can't undersant why this doesn't work ...
1st off change vertices set 10% from yours:
private float[] vertices = { // Vertices for the square
-0.1f, -0.1f, 0.0f, // 0. left-bottom
0.1f, -0.1f, 0.0f, // 1. right-bottom
-0.1f, 0.1f, 0.0f, // 2. left-top
0.1f, 0.1f, 0.0f // 3. right-top
};
After that I found problem in your onDrawFrame(GL10 gl):
You don't have nor glTranslatef neitherglScalef
change it to:
#Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glLoadIdentity();
// Drawing
gl.glTranslatef(0.0f, 0.0f, -1.0f); // move 5 units INTO the screen
// is the same as moving the camera 5 units away
gl.glScalef(0.5f, 0.5f, 0.5f); // scale the triangle to 50%
// otherwise it will be too large
quad.draw(gl);
}
I'm building an Android app with OpenGL.I created 2 squares, each with their own textures(PNG), and overlayed them. From hints i got from a previous question, i used gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
My problem is that the transparency effect, affects the second square, therefor i can see the background through the second square's texture.Is there a way arround this?
Here is the Renderer and at the Bottom the Square.java class :
package hello.project;
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;
public class Square {
private FloatBuffer vertexBuffer; // buffer holding the vertices
static int sex=R.drawable.girl;
private FloatBuffer textureBuffer; // buffer holding the texture coordinates
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
private float vertices[] = {
-1.0f, -2.0f, 0.0f, // V1 - bottom left
-1.0f, 2.0f, 0.0f, // V2 - top left
0.8f, -2.0f, 0.0f, // V3 - bottom right
0.8f, 2.0f, 0.0f // V4 - top right
};
public Square() {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuffer.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
}
/** The draw method for the square with the GL context */
public void draw(GL10 gl) {
// bind the previously generated texture
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_CW);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
/** The texture pointer */
private int[] textures = new int[1];
public void loadGLTexture(GL10 gl, Context context,int sex ) {
// loading texture
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
sex);
// 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);
// Use 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();
}
public static int getSex() {
return sex;
}
public static void setSex(int sex) {
Square.sex = sex;
}
}
---------------------------------------------------------------------------
package hello.project;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
public class HelloOpenGLES10Renderer implements Renderer {
private Square square; // the square
private Square2 square2; // the square
private Context context;
/** Constructor to set the handed over context */
public HelloOpenGLES10Renderer(Context context) {
this.square = new Square();
this.square2 = new Square2();
this.context=context;
}
public void onDrawFrame(GL10 gl) {
// clear Screen and Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glLoadIdentity();
// Drawing
gl.glTranslatef(0.0f, 0.0f, -5.0f); // move 5 units INTO the screen
square.draw(gl);
square2.draw(gl);
}
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
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Load the texture for the square
square.loadGLTexture(gl, this.context,Square.getSex());
square2.loadGLTexture(gl, this.context,Square2.getSex());
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //Black Background
gl.glClearDepthf(1.0f); //Depth Buffer Setup
gl.glDepthFunc(GL10.GL_NEVER); //The Type Of Depth Testing To Do
//Really Nice Perspective Calculations
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
}
Don't you just have a problem with the graphics pipeline state? Remember whichever square you tell to get drawn first gets drawn using the blend function that's currently active (and this will remain active until you change the OpenGL state). Maybe you want to add some more state changes to the blend function, or change the order of drawing to get the effect you want? You might want to also try enabling/disabling the depth test between drawing calls to make a square opaque.
Hope this helps a bit, you might need to provide a bit more detail to your question.
I'm trying to do some pixel work in a texture old school by accessing it using an array. My approach is to generate a texture, then use that texture each successive frame write and modify my texture as necessary. However, when I run this code in the Android Emulator, all I get is a white image. My texture size is a power of two, so I was a bit surprised. If anything, I would have expected to see a completely black image. Here is my custom renderer code:
package com.gltest;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
public class OpenGLRenderer implements Renderer {
private ByteBuffer buf;
private int cwidth, cheight;
private FloatBuffer vertexBuffer, texelBuffer;
private ShortBuffer indexBuffer;
int[] textures = new int[1];
float vertices[] = {
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f
};
private float texels[] = {
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f
};
private short[] indices = { 0, 1, 2, 0, 2, 3 };
#Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
updateTexture(gl);
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluOrtho2D(gl, 0, width, 0, height);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
buf = ByteBuffer.allocateDirect(128 * 128 * 3).order(ByteOrder.nativeOrder());
cwidth = width;
cheight= height;;
for( int i=0; i<vertices.length; i+=3 ) {
vertices[i] *= cwidth;
vertices[i+1] *= cheight;
}
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glGenTextures(1, textures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, 3, 128, 128, 0, GL10.GL_RGB, GL10.GL_UNSIGNED_BYTE, buf);
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
ByteBuffer tbb = ByteBuffer.allocateDirect(texels.length * 4);
tbb.order(ByteOrder.nativeOrder());
texelBuffer = tbb.asFloatBuffer();
texelBuffer.put(texels);
texelBuffer.position(0);
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(1.0f, 0.0f, 0.0f, 0.5f);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
void updateTexture(GL10 gl)
{
// Update pixels
// write random r g or b values to random locations
for(int y = 0; y < 128; ++y)
for(int x = 0; x < 128; ++x)
buf.put(x+y*128, (byte)(Math.random()*255));
buf.position(0);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glBindTexture(gl.GL_TEXTURE_2D, textures[0]);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexSubImage2D(GL10.GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL10.GL_RGB, GL10.GL_UNSIGNED_BYTE, buf);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texelBuffer);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
}
Honestly I do not believe it is a very convenient solution performance wise.
This kind of alteration/effects should be done in a programmable pipeline model such as OPENGL ES 2.0 using vertex and fragment shaders.
The solution you are trying to achieve is not convenient for the following reasons:
The load is entirely on the CPU and you are not using the power of the GPU at all
Texture data manipulation functions are well known to be a performance killer for nowadays GPUs
I strongly suggest you to implement the effects possibly in a fragment shader to have the best performances possible.
After some poking around, I've discovered that gl.glTexSubImage2D is not supported in GLES 1.1 on Android (it's built in but it doesn't do anything: https://www.google.com/search?ix=hea&sourceid=chrome&ie=UTF-8&q=android+opengl+glTexSubImage2D)
Also, so no one else wastes their time in the future, forget about trying to use glDrawPixels to send to the framebuffer. That isn't support either, in any GLES 1.1 / 2.0 implementation (Android, iPhone) etc.
The solution is to use the NDK as outlined in this excellent article by some coder named "Richard Quirk" who has his own blog: http://quirkygba.blogspot.com/2010/10/android-native-coding-in-c.html and, as it happens, also is a Stack Overflow regular: https://stackoverflow.com/users/4596/richq
Thanks Richard!
I'm putting together a simple test made up of two tutorials available online for OpenGL ES on Android. This is really just so that I can learn about the basics of OpenGL ES to better understand how I have to design my program.
Right now, when it tries to render, the mouse movement effect works, but I get no square drawn on the screen.
Here are the two source files I'm dealing with:
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
//Simple clear-screen renderer.
class ClearRenderer implements GLSurfaceView.Renderer {
private float mRed;
private float mGreen;
private float mBlue;
private TileUI testTile;
public ClearRenderer() {
this.testTile = new TileUI();
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
public void onSurfaceChanged(GL10 gl, int w, int h) {
gl.glViewport(0, 0, w, h);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
// Calculate The Aspect Ratio Of The Window
GLU.gluPerspective(gl, 45.0f, (float)w / (float)h, 0.1f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
public void onDrawFrame(GL10 gl) {
gl.glClearColor(mRed, mGreen, mBlue, 1.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, 0.0f);
testTile.draw(gl);
}
public void setColor(float r, float g, float b) {
mRed = r;
mGreen = g;
mBlue = b;
}
}
The second one is the tile object itself:
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
public class TileUI {
private float[] vertices = {
-1.0f, -1.0f, 0.0f, // Bottom left
1.0f, -1.0f, 0.0f, // Bottom right
-1.0f, 1.0f, 0.0f, // Top left
1.0f, 1.0f, 0.0f // Top right
};
private FloatBuffer vertexBuffer;
public TileUI() {
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
}
// Performs the actual drawing of a Tile.
public void draw(GL10 gl) {
// Set the face rotation.
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
// Enable vertex buffer.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// Draw the vertices as a triangle strip.
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
// Disable the client state before leaving.
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
I will definitely apologize in advance, this is a bit of a Frankenstein, any help and explanation about what's going on here would be greatly appreciated.
I think that the line that's causing you problems is gl.glTranslatef(0.0f, 0.0f, 0.0f);. That means that you are drawing your quad at the origin and that's also where the camera is so you don't see it. Try something like gl.glTranslatef(0.0f, 0.0f, -10.0f);. That should move the quad into the screen and put it in front of your camera. Alternatively, if you're doing 2D drawing you could use glOrtho() instead of gluPerspective() and that will give you an orthographic, or flat, projection.