I began to try to draw VBO using JOGL. Prior to that, I drew with the help of glBegin and glEnd, and everything worked. And then I see only a black screen. What could be the problem? I read somewhere that using VBO for drawing requires shaders. Is it so?
Code:
public class Main implements GLEventListener {
public static DisplayMode dm, dm_old;
private GLU glu = new GLU();
private float xrot,yrot,zrot;
private int texture;
Texture t;
#Override
public void display(GLAutoDrawable drawable) {
final GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity(); // Reset The View
gl.glTranslatef(0f, 0f, -5.0f);
gl.glBindTexture(GL2.GL_TEXTURE_2D, texture);
final float[] coordData = {
0, 0, //
1, 0, //
0, 1, //
};
final float[] vertices = {
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
};
// Setup the vertices into the buffer
FloatBuffer verts = Buffers.newDirectFloatBuffer(vertices.length);
verts.put(vertices).position(0);
// Setup the texture coordinates
FloatBuffer coords = Buffers.newDirectFloatBuffer(coordData.length);
coords.put(coordData).position(0);
gl.glVertexPointer(3, GL2.GL_FLOAT, 0, verts);
gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, coords);
gl.glDrawArrays(GL2.GL_TRIANGLES, 0, 3);
//change the speeds here
xrot += 5f;
}
#Override
public void init(GLAutoDrawable drawable) {
final GL2 gl = drawable.getGL().getGL2();
gl.glShadeModel(GL2.GL_SMOOTH);
gl.glClearColor(0f, 0f, 0f, 0f);
gl.glClearDepth(1.0f);
gl.glEnable(GL2.GL_DEPTH_TEST);
gl.glDepthFunc(GL2.GL_LEQUAL);
gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
gl.glEnable(GL2.GL_TEXTURE_2D);
try {
File im = new File("/home/congard/pic/t.jpeg");
t = TextureIO.newTexture(im, true);
texture= t.getTextureObject(gl);
}catch(IOException e){
e.printStackTrace();
}
}
#Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
// some code
}
}
You didn't enable the client-side capabilities for vertex and texture coordinates. See Client-Side Vertex Arrays
and glEnableClientState.
Add the following to your code:
gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
gl.glVertexPointer(3, GL2.GL_FLOAT, 0, verts);
gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, coords);
Related
I've been trying to resolve this problem for the past three days, but in vain. Therefore, I'd be very grateful for any help. I am currently learning how to draw triangles with VBOs and VAOs, so all of the code is included in one single "test" class.
package quad;
import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import static org.lwjgl.system.MemoryUtil.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.GL_FALSE;
import static org.lwjgl.opengl.GL11.GL_TRUE;
import static org.lwjgl.opengl.GL.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
public class Quad {
private long window;
private final String WINDOW_TITLE = "The Quad: glDrawArrays";
private final int WIDTH = 1920;
private final int HEIGHT = 1080;
// Quad variables
private int vaoId = 0;
private int vboId = 0;
private int vertexCount = 0;
private boolean running = false;
public static void main(String[] args) {
new Quad().start();
}
public void start() {
running = true;
setupOpenGL();
setupQuad();
while (running) {
loopCycle();
update();
if(glfwWindowShouldClose(window)) {
running = false;
}
}
destroyOpenGL();
}
public void setupOpenGL() {
if(!glfwInit()) {
throw new IllegalStateException("Unable to initialize GLFW!");
}
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
window = glfwCreateWindow(WIDTH, HEIGHT, WINDOW_TITLE, NULL, NULL);
if (window == NULL) {
throw new RuntimeException("Cannot create window!");
}
glfwMakeContextCurrent(window);
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, (vidmode.width() - WIDTH) / 2, (vidmode.height() - HEIGHT) / 2);
glfwShowWindow(window);
GL.createCapabilities();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
public void setupQuad() {
float[] vertices = {
// Left bottom triangle
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
// Right top triangle
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f,
-0.5f, 0.5f, 0f
};
FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
verticesBuffer.put(vertices);
verticesBuffer.flip();
vertexCount = 6;
// Create a new Vertex Array Object in memory and select it (bind)
// A VAO can have up to 16 attributes (VBO's) assigned to it by default
vaoId = glGenVertexArrays();
glBindVertexArray(vaoId);
// Create a new Vertex Buffer Object in memory and select it (bind)
// A VBO is a collection of Vectors which in this case resemble the location of each vertex.
vboId = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);
// Put the VBO in the attributes list at index 0
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
// Deselect (bind to 0) the VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Deselect (bind to 0) the VAO
glBindVertexArray(0);
}
public void loopCycle() {
glClear(GL_COLOR_BUFFER_BIT);
// Bind to the VAO that has all the information about the quad vertices
glBindVertexArray(vaoId);
glEnableVertexAttribArray(0);
// Draw the vertices
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
// Put everything back to default (deselect)
glDisableVertexAttribArray(0);
glBindVertexArray(0);
}
public void destroyOpenGL() {
// Disable the VBO index from the VAO attributes list
glDisableVertexAttribArray(0);
// Delete the VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(vboId);
// Delete the VAO
glBindVertexArray(0);
glDeleteVertexArrays(vaoId);
glfwDestroyWindow(window);
glfwTerminate();
}
public void update() {
glfwSwapBuffers(window);
glfwPollEvents();
}
}
Note: I've modernised this tutorial code example so LWJGL3 is used (none of the old Displays etc).
Everything functions correctly at the first glance, but when the code is run, only a window with black colour (which is set by glClearColor(0.0f, 0.0f, 0.0f, 0.0f) inside the setupOpengl() method.
Why are the quads not showing up?
I am try to use EffectFactory in Android for some Image Manipulation.
I tried out the sample and it works.
Here the Sample: https://android.googlesource.com/platform/development/+/master/samples/HelloEffects/src/com/example/android/mediafx/HelloEffects.java
But how can I load an image from my smartphone?
The thing is that I don't have an ImageView here but a GLSurfaceView.
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.puppy);
which method do I have to use to get a custom bitmap?
Use this BitmapRenderer class to draw Bitmap in OpenGL
private static class BitmapRenderer implements GLSurfaceView.Renderer {
private int[] textures;
private Resources resources;
public BitmapRenderer(Resources resources) {
this.resources = resources;
}
private static final float[] VERTEX_COORDINATES = new float[] {
-1.0f, +1.0f, 0.0f,
+1.0f, +1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
+1.0f, -1.0f, 0.0f
};
private static final float[] TEXTURE_COORDINATES = new float[] {
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f
};
private static final Buffer TEXCOORD_BUFFER = ByteBuffer.allocateDirect(TEXTURE_COORDINATES.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer().put(TEXTURE_COORDINATES).rewind();
private static final Buffer VERTEX_BUFFER = ByteBuffer.allocateDirect(VERTEX_COORDINATES.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer().put(VERTEX_COORDINATES).rewind();
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
textures = new int[1];
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
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_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
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_CLAMP_TO_EDGE);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher), 0);
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
}
#Override
public void onDrawFrame(GL10 gl) {
gl.glActiveTexture(GL10.GL_TEXTURE0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, VERTEX_BUFFER);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, TEXCOORD_BUFFER);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
}
}
Set your Bitmap as below:
glSurfaceView.setEGLContextClientVersion(1);
glSurfaceView.setRenderer(new BitmapRenderer(getResources()));
glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
Following code works perfectly on older Android versions, but only shows a black screen on newer versions (I guess 4.2 and higher).
Im very new to OpenGL and I used to work with Canvas/SurfaceView, but now I need GLSurfaceView for the performance, so I leeched some code from here and there without exactly knowing what it does. I didnt start a whole new project, I just rewrote some of my "Canvas-Code" to a GLSurfaceView loop. Thats why it might look strange and inefficient.
Explanation for the code:
The class "Sprite" contains a Bitmap, xPos and yPos. In "defineStuff();" I append a few different "Sprites" to a List and the GLSurfaceView draws everything from the List.
This is not the whole code, I removed pretty much to make it more clear.
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN); //so its Fullscreen
defineStuff();
glSurfaceView = new GLSurfaceView(this);
glSurfaceView.setRenderer(new GlRenderer());
glSurfaceView.setOnTouchListener(this);
setContentView(glSurfaceView);
}
The Sprite class:
public class Sprite {
private FloatBuffer vertexBuffer; // buffer holding the vertices
private FloatBuffer textureBuffer; // buffer holding the texture coordinates
private float texture[];
private float vertices[];
public Bitmap bmp;
public boolean visible;
public String name;
public float posX;
public float posY;
public Sprite(String name, Bitmap bitmap, float posX, float posY, boolean visible) {
this.name = name;
this.visible = visible;
setBuffers(bitmap, posX, posY);
}
public void setBuffers(Bitmap bitmap, float posX, float posY) {
bmp = bitmap;
}
this.posX = posX;
this.posY = posY;
float tempVertices[] = {
posX, posY + bitmap.getHeight(), 0.0f, // V1 - bottom left
posX, posY, 0.0f, // V2 - top left
posX + bitmap.getWidth(), posY + bitmap.getHeight(), 0.0f, // V3 - bottom right
posX + bitmap.getWidth(), posY, 0.0f // V4 - top right
};
vertices = new float[tempVertices.length];
System.arraycopy(tempVertices, 0, vertices, 0, tempVertices.length);
// a float has 4 bytes so we allocate for each coordinate 4 bytes
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
// allocates the memory from the byte buffer
vertexBuffer = byteBuffer.asFloatBuffer();
// fill the vertexBuffer with the vertices
vertexBuffer.put(vertices);
// set the cursor position to the beginning of the buffer
vertexBuffer.position(0);
float tempTexture[] = {
// 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)
};
texture = new float[tempTexture.length];
System.arraycopy(tempTexture, 0, texture, 0, tempTexture.length);
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) { // every Sprite has to be loaded before being drawn
// 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, bmp, 0);
}
public void draw(GL10 gl, float interpolation) {
gl.glPushMatrix();
gl.glTranslatef (speedInX * interpolation, speedInY * interpolation, 0f);
// 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);
gl.glPopMatrix();
}
}
My renderer:
public class GlRenderer implements Renderer {
#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
updateLogic(gl); //there was very much code around this but I removed it to make it more clear
float interpolation = (float) (SystemClock.uptimeMillis() + SKIP_TICKS - nextGameTick) / SKIP_TICKS;
spriteList.toFirst();
while (spriteList.getObject() != null) {
((Sprite) spriteList.getObject()).draw(gl, interpolation);
spriteList.next();
}
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION); // or some matrix uniform if using shaders
gl.glLoadIdentity();
gl.glOrthof(0, width, height, 0, -1, 1); // this will allow to pass vertices in 'canvas pixel' coordinates
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glDisable(GL10.GL_DITHER);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
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); //Set 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
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); // So alpha works, but it still doesnt work everytime :)
spriteList.toFirst();
while (spriteList.getObject() != null) {
((Sprite) spriteList.getObject()).loadGLTexture(gl);
spriteList.next();
}
}
}
brecause you have
gl.glOrthof(0,width,height,0,-1,1);
your code doesnt require depth testing, try getting rid of
| GL10.GL_DEPTH_BUFFER_BIT
gl.glClearDepthf(1.0f);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glTranslatef(0.0f, 0.0f, -5.0f);
I am workiong on the Android platform. I have just started with OpenGL and am trying to put an image on a rectangle. This is my code:
public class IntroActivity extends Activity {
private GLSurfaceView glsv = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
glsv = new GLSurfaceView(this);
glsv.setRenderer(new IntroRenderer());
setContentView(glsv);
}
#Override
protected void onResume() {
// Ideally a game should implement onResume() and onPause()
// to take appropriate action when the activity looses focus
super.onResume();
glsv.onResume();
}
#Override
protected void onPause() {
// Ideally a game should implement onResume() and onPause()
// to take appropriate action when the activity looses focus
super.onPause();
glsv.onPause();
}
Here IntroRenderer is an inner class.
class IntroRenderer implements GLSurfaceView.Renderer{
#Override
public void onDrawFrame(GL10 gl) {
gl.glClearColor(0,1.0f,1.0f,1.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
float positions[] = {
0.0f,1.0f,0.0f,
0.0f, 0.0f, 0.0f,
1.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,
1.0f,1.0f, 0.0f,
1.0f,0.0f,0.0f
};
ByteBuffer bb = ByteBuffer.allocateDirect(positions.length*4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(positions);
fb.position(0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3,GL10.GL_FLOAT, 0, fb);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3*2);
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.rect2985);
Bitmap bmp256 = Bitmap.createScaledBitmap(bmp, 256,256,false);
gl.glEnable(GL10.GL_TEXTURE_2D);
int[] buffers = new int[1];
gl.glGenTextures(1,buffers,0);
int texture = buffers[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,bmp256,0);
//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_NEAREST);
bmp.recycle();
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
}
}
}
On running this activity, the background rectangle is rendered but ther eis no image. What am I doing wrong?
I modified your renderer a bit:
class IntroRenderer implements GLSurfaceView.Renderer {
private boolean textureReady = false;
public void onDrawFrame(GL10 gl) {
if (!this.textureReady) {
this.prepareTexture(gl); // only initialize once
}
gl.glClearColor(0, 0.4f, 0.4f, 1.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
float positions[] = {
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f };
float texCoords[] = { // define texture coordinates
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 1.0f,
1.0f, 0.0f };
ByteBuffer bb = ByteBuffer.allocateDirect(positions.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(positions);
fb.position(0);
// create buffer for texture coordinates
ByteBuffer texCoordByteBuffer = ByteBuffer.allocateDirect(texCoords.length * 4);
texCoordByteBuffer.order(ByteOrder.nativeOrder());
FloatBuffer texCoordBuffer = texCoordByteBuffer.asFloatBuffer();
texCoordBuffer.put(texCoords);
texCoordBuffer.position(0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fb);
// enable texture buffer
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texCoordBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3 * 2);
}
private void prepareTexture(GL10 gl) {
int[] buffers = new int[1];
gl.glGenTextures(1, buffers, 0);
int texture = buffers[0];
// enable texturing and bind texture
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
Bitmap bmp = BitmapFactory.decodeResource(IntroActivity.this.getResources(), R.drawable.rect2985);
Bitmap bmp256 = Bitmap.createScaledBitmap(bmp, 256, 256, false);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp256, 0);
// setup 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_NEAREST);
bmp.recycle();
this.textureReady = true;
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
}
}
I added comments at the modified parts:
You have to define texture coordinates and create a buffer (like you did for vertex positions)
Enable texturing with gl.glEnable(GL10.GL_TEXTURE_2D);
You need min/mag filters
As oren suggested you should do the initialization only once.
The texture coordinates define how the texture is mapped to your triangles. You can think of a coordinate system from 0.0 to 1.0 in x and y axis where the corners (0,0; 1,0; 1,1; 0,1) define the corners of your texture. You have to assign a texture coordinate to each vertex you define.
Maybe this can help you to understand how texture coordinates work: http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node52.html
I'm not sure why is doesn't render, but your code is inefficient.
You are loading the bitmap and binding it on EVERY frame.
You should do it only once.
Also, this link can help you with great examples with this Nehe port for Android:
Nehe Port for Android
Good luck :)
I tried to implement Open GLs Vertex Buffer Objects the first time, and all i get is a black screen.
I tried it with glOrtho instead of glPerspective, but it didnt work as well.
thanks for helping
Heres my code:
public class VBufferTest {
public static final int WIN_WIDTH = 640;
public static final int WIN_HEIGHT = 480;
public int vBufferId;
public static void main(String args[]){
VBufferTest foo = new VBufferTest();
foo.initLWJGLFrame();
foo.initBuffer();
while (!Display.isCloseRequested()){
foo.render();
}
}
public void initLWJGLFrame(){
try {
DisplayMode[] possible = Display.getAvailableDisplayModes();
DisplayMode chosen = null;
for (int i = 0; i < possible.length; i += 1){
if (possible[i].getWidth() == WIN_WIDTH && possible[i].getHeight() == WIN_HEIGHT){
chosen = possible[i];
break;
}
}
if (chosen != null){
Display.setDisplayMode(chosen);
Display.setTitle("TestFrame1");
Display.create();
}
else {
throw new LWJGLException("Couldn't find the appropriate display mode.");
}
}
catch (LWJGLException e){
}
}
public void initGL(){
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL11.glClearColor(104.f/255.0f, 136.0f/255.0f, 252.0f/255.0f, 1.0f);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GLU.gluPerspective(50.0f, Display.getDisplayMode().getWidth()/Display.getDisplayMode().getHeight(), 0.5f, 1000.0f);
GL11.glViewport(0, 0, Display.getDisplayMode().getWidth(), Display.getDisplayMode().getHeight());
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
}
public void initBuffer(){
FloatBuffer vertices = BufferUtils.createFloatBuffer(4*3);
vBufferId = genNewId();
vertices.put(new float[]{-1.0f, -1.0f, 0.0f});
vertices.put(new float[]{1.0f, -1.0f, 0.0f});
vertices.put(new float[]{1.0f, 1.0f, 0.0f});
vertices.put(new float[]{-1.0f, 1.0f, 0.0f});
vertices.flip();
bufferData(vBufferId, vertices);
}
public void render(){
GL11.glColor3f(1.0f, 0.0f, 1.0f);
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, this.vBufferId);
GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0);
GL11.glDrawArrays(GL11.GL_QUADS, 0, 4);
Display.update();
}
public static int genNewId(){
IntBuffer buffer = BufferUtils.createIntBuffer(1);
ARBVertexBufferObject.glGenBuffersARB(buffer);
return buffer.get(0);
}
public static void bufferData(int id, FloatBuffer buffer){
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, id);
ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, buffer, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
}
}
You have depth-testing enabled, but you don't clear the z-buffer once per frame using glClear (at the beginning of your render method). Same for clearing the color buffer.
EDIT: Also, initGl() seems to be never called?