问题
I'm new to opengGL and excuse if the questions are too naive. I'm going through some tuturials for seeking help on learning this. I have a small program written where i'm drawing a texture on a GLSurfaceView.
I want to draw a number of textures(bitmap images) in a sequential order starting from 0,0 coordinates. Also I need some gap in images on the screen. Please help. Do I need to change the positioning of vertices buffer. please suggest.
Here is my renderer Code.
public class GlRenderer implements Renderer{
private Square square; // square1
private Context context;
/** Constructor to set the handed over context */
public GlRenderer(Context context) {
this.context = context;
// initialise the square
this.square = new Square();
}
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); // Draw the triangle
//gl.glTranslatef(0.0f, 0.0f, 0.0f); // move 5 units INTO the screen
//square2.draw(gl); // Draw the triangle
}
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_TEXTURE); //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);
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);
}
}
Here is the square code
public class Square {
private FloatBuffer vertexBuffer; // buffer holding the vertices
private float vertices[] = {
-1.0f, -.25f, 0.0f, // V1 - bottom left
-1.0f, .25f, 0.0f, // V2 - top left
1.0f, -.25f, 0.0f, // V3 - bottom right
1.0f, .25f, 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)
};
/** The texture pointer */
private int[] textures = new int[1];
public Square() {
// 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);
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
}
/**
* Load the texture for the square
* @param gl
* @param context
*/
public void loadGLTexture(GL10 gl, Context context) {
// loading texture
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.progressbar_bg);
// 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 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();
}
/** 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);
}
}
I am not able to see the actual size of texture on the view. I was playing with gl.glTranslatef(0.0f, 0.0f, -5.0f); to manipulate the coordinates of texture on screen. But still not able to get the actual image size and position the texture image at desired loaction starting from 0,0 coordinates.
回答1:
I solved the issue by using glTranslate() properly. Now I understand that translate takes the last translated value of the surface for its current position. I have made the changes for that now with fixed x and z coordinates and y changing after each draw of texture. I did the following:
float x = -1.0f;
float y = 1.5f;
float z = -5.0f;
// Drawing
gl.glTranslatef(x, y, z);
square1.draw(gl); // Draw the square
gl.glTranslatef(0.0f, -0.50f, 0.0f);
square2.draw(gl); // Draw the square
gl.glTranslatef(0.0f, -0.50f, 0.0f);
square2.draw(gl); // Draw the square
gl.glTranslatef(0.0f, -0.50f, 0.0f);
square2.draw(gl); // Draw the square
回答2:
I think there is confusion between the drawing objects and drawing bitmaps (Pixel operations)
From you requirements "I want to draw a number of textures(bitmap images) in a sequential order starting from 0,0 coordinates. Also I need some gap in images on the screen. Please help. Do I need to change the positioning of vertices buffer". It is preferreed that you should draw bitmaps. Refer to api glBitmap, glDrawPixels, etc etc
For textures. The concept/approach you applied is correct. You are drawing a rectangle between (-1,-1) and (1,1). The texture is mapping seems correct. However, you need to play around withe api for
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT Or CLAMP);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
(PS-PLease use android based apis appropriately)
When you experiment with glTranslatef, the object also moves (along with the texture).
Imagine you are drawing shirt, with a pattern. The pattern coordinates are with respect to the shirt. Use the texture apis to position the pattern on the shirt. And the translatef calls moves the world coordinate system but the pattern will not change.
回答3:
If you are using the pixel draw functions (where in you are drawing directly to the screen buffer) use apis such glPixelZoom. You can use negative values to change direction
If you are trying to use model transformations use glRotate API. Use a combination of translation and rotation.
来源:https://stackoverflow.com/questions/9188857/draw-texture-in-opengl-android-from-0-0-coordinates