从 0,0 坐标在 OpenGL Android 中绘制纹理

发布于 2025-01-03 16:58:27 字数 6394 浏览 1 评论 0原文

我是 opengGL 的新手,如果问题太天真,请原谅。我正在浏览一些教程来寻求学习这一点的帮助。我写了一个小程序,在 GLSurfaceView 上绘制纹理。

我想从 0,0 坐标开始按顺序绘制许多纹理(位图图像​​)。我还需要屏幕上的图像有一些间隙。请帮忙。我需要更改顶点缓冲区的位置吗?请建议。

这是我的渲染器代码。

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); 

    }
}

这是方形代码,

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);
    }
}

我无法在视图上看到纹理的实际大小。我正在玩 gl.glTranslatef(0.0f, 0.0f, -5.0f);操纵屏幕上纹理的坐标。但仍然无法获取实际图像大小并将纹理图像定位在从 0,0 坐标开始的所需位置。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

白首有我共你 2025-01-10 16:58:27

我通过正确使用 glTranslate() 解决了这个问题。现在我明白翻译采用表面的最后翻译值作为其当前位置。我现在已经对此进行了更改,固定的 x 和 z 坐标以及每次绘制纹理后 y 的变化。我做了以下事情:

        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

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
落在眉间の轻吻 2025-01-10 16:58:27

我认为绘图对象和绘图位图(像素操作)之间存在混淆

根据您的要求“我想从 0,0 坐标开始按顺序绘制多个纹理(位图图像​​)。此外,我还需要图像中有一些间隙请帮助我是否需要更改顶点缓冲区的位置”。
最好应该绘制位图。 请参阅 api glBitmap、glDrawPixels 等

有关纹理, 。您应用的概念/方法是正确的。您正在 (-1,-1) 和 (1,1) 之间绘制一个矩形。纹理映射似乎是正确的。但是,您需要使用 api
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT 或 CLAMP);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
(PS-请适当使用基于 android 的 api)

当您尝试使用 glTranslatef 时,对象也会移动(与纹理一起)。

想象一下你正在画带有图案的衬衫。图案坐标是相对于衬衫而言的。使用纹理 api 将图案定位在衬衫上。
调用translatef会移动世界坐标系,但图案不会改变。

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.

歌枕肩 2025-01-10 16:58:27

如果您使用像素绘制函数(直接绘制到屏幕缓冲区),请使用 glPixelZoom 等 api。您可以使用负值来改变方向

如果您尝试使用模型转换,请使用 glRotate API。使用平移和旋转的组合。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文