Setting up the viewport for 2D OpenGL programming on Android
I'm trying to use OpenGL for 2D programming on the Android. Right now, I'm at the setup stage; trying to configure my viewport. I've got textures loading and drawing, but I'm having trouble getting them to draw like I want. If possible, I want the origin to be at the top left of the screen, increasing downwards, as that's how my code (carried over from when I previously used the canvas) is set up. I figured this would be easy; something along the lines of translate and flip. When I tried modifying the statements that configure the viewport, I was surprised to see that apparently my application isn't even affected by them. See the code below for the onSurfaceChanged() method of the GLRenderer:
public void onSurfaceChanged(GL10 gl, int width, int height) {
this.width = width;
this.height = height;
gl.glViewport(0, 0, width, height);
gl.glLoadIdentity();
GLU.gluOrtho2D(gl, 0, width, height, 0);
gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
}
I can change these val开发者_开发技巧ues, or even comment out these lines (except for the glColor4x one) completely and the graphics still display exactly the same. The graphics display at their expected size, with no distortion, and even in the right spot if you take the bottom-left coordinate to be the origin. Here's the drawing routine for my textures, as part of a class representing one drawable object:
public void draw(GL10 gl, float x, float y) {
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
cropSignature = OpenGLUtil.setTextureCrop(gl,srcRectParam,cropSignature);
((GL11Ext)gl).glDrawTexfOES(x, y, 0, width, height);
}
Where x,y are the coordinates to draw at, and width,height are the dimensions of the texture, specified on instantiation of this object.
Is the glDrawTexfOES completely bypassing the viewport settings I established? If so, how should I be drawing? And how can I set the OpenGL origin to be at the top-left, increasing downwards? Or is that bad practice, and should I be inverting the rest of my code to comply with that?
Change it to something like this:
// call only one time, when texture needs to be loaded
// (also sometimes neccesary after resuming a paused app)
public void loadTexture() {
textureId = gl.glGenTextures(1);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
cropSignature = OpenGLUtil.setTextureCrop(gl,srcRectParam,cropSignature);
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
this.width = width;
this.height = height;
}
public void draw(GL10 gl, float x, float y) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
if(origin_upper_left) {
GLU.gluOrtho2D(gl, 0, width, 0, height);
} else {
GLU.gluOrtho2D(gl, 0, width, height, 0);
}
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
((GL11Ext)gl).glDrawTexfOES(x, y, 0, width, height);
}
精彩评论