在正方形上绘制文本作为纹理不会显示任何内容

发布于 2024-12-04 17:09:36 字数 6358 浏览 2 评论 0原文

我是 OpenGL 新手,正在为 Android 开发增强现实应用程序。

到目前为止,我一直在绘制垂直于相机的白色方块,将用户指向“兴趣点”所在的方向。

现在,我试图在方块中显示一些文本。

我读了很多书,似乎用文本创建纹理是最直接、最简单的方法,所以我在获得兴趣点数据并将它们粘贴到它们的方块上后立即创建纹理。为此,我使用位图。

让我们看一些代码。在我的 onDrawFrame 方法中,我做了这样的事情:

public void onDrawFrame(GL10 gl) {

        // Get sensors matrix
                ...


        //Clear Screen And Depth Buffer
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        // Load remapped matrix
        gl.glMatrixMode(GL10.GL_MODELVIEW);



        // List of Points of interest (modified when some data is downloaded)
        synchronized (poiList) {

            if(mNewData){  // True if new data has been dowloaded)
                if(textures != null)  // Delete old textures
                    gl.glDeleteTextures(textures.length, textures, 0);

                textures = loadGLTexture(gl, soapPoiList.getPoiList());
                mNewData = false;
            }

            int i = 0;
            // Iterate the list
            for (PointOfInterest c : poiList) {

                         gl.glLoadIdentity();
                 gl.glLoadMatrixf(remappedRotationMatrix, 0);

                 // Get bearing
                             ...

                 // Place polygon in the right place
                 gl.glRotatef(-bearing, 0, 0, 1);
                 gl.glTranslatef(0, ICONS_SIZE_RATIO, 0);

                         // Actually draws the polygon with text
                 c.draw(gl, textures[i]);

                 i++;
            }
        }
    }

其中 loadGLTextures 是:

protected int[] loadGLTexture(GL10 gl, List<PointOfInterest> l){
    int res[] = new int[l.size()];
    gl.glGenTextures(res.length, res, 0);
    int i = 0;

    for(PointOfInterest p : l) {
        Bitmap bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.RGB_565);
        bitmap.eraseColor(Color.BLACK);

        Canvas canvas = new Canvas(bitmap);

        Paint textPaint = new Paint();
        textPaint.setTextSize(35);
        textPaint.setFakeBoldText(true);
        textPaint.setAntiAlias(true);
        textPaint.setARGB(255, 255, 255, 255);
        // Draw the text centered
        canvas.drawText(Float.toString(p.getDinstanceToOrigin()) + " m.", 10,35, textPaint);

        // Bind the texture to our array
        gl.glBindTexture(GL10.GL_TEXTURE_2D, res[i]);

        //  Create Nearest Filtered Texture
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_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, bitmap, 0);

        bitmap.recycle();

        i++;
    }
    return res;
}

它基本上为每个兴趣点创建一个位图,并用它生成一个纹理。稍后纹理将应用在白色方块上,如本课程中所示:

    public class PointOfInterest {

        // MEMBERS ----------------------------------------------------------------
            ....
            ....

        // OpenGL necessary variables
        /** The buffer holding the vertices */
        private FloatBuffer vertexBuffer;

        /** The initial vertex definition */
        private float vertices[] = { 
                                    -1.0f, 0.0f, -1.0f, //Bottom Left   V1
                                    -1.0f, 0.0f,  1.0f, //Top Left      V2
                                     1.0f, 0.0f, -1.0f, //Bottom Right  V3
                                     1.0f, 0.0f,  1.0f, //Top Right     V4
                                   };

        private FloatBuffer textureBuffer;
        private float texture[] = {
                                    0.0f, 0.0f,     // V1
                                    1.0f, 0.0f,     // V3
                                    0.0f, 1.0f,     // V2
                                    1.0f, 1.0f      // V4
        };

        // CONSTRUCTORS -----------------------------------------------------------

        public PointOfInterest(Location originLocation){
            currentLocation = originLocation;

            mPoiLocation = new Location(LocationManager.GPS_PROVIDER);

            ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
            byteBuf.order(ByteOrder.nativeOrder());

            vertexBuffer = byteBuf.asFloatBuffer();
            vertexBuffer.put(vertices);
            vertexBuffer.position(0);

            byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
            byteBuf.order(ByteOrder.nativeOrder());

            textureBuffer = byteBuf.asFloatBuffer();
            textureBuffer.put(texture);
            textureBuffer.position(0);
        }

        // PUBLIC METHODS ---------------------------------------------------------

        public void draw(GL10 gl, int textureId){
            // Bind the previously generated texture
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);

            // Point to our buffers
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

            // set the colour for the square
            //gl.glColor4f(0.0f, 0.1f, 0.0f, 0.5f);

            //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'm new to OpenGL and I'm developing an Augmented-reality application for Android.

Until now, I was drawing white squares, perpendicular to the camera, pointing the user to the direction where a "Point of interest" would be.

Now, I'm trying to show some text into the squares.

I've read a lot and it seems that creating a texture with the text is the most direct and easiest approach, so I'm creating the textures as soon as I get data of the Points of interest and stick them to their squares. For that, I use bitmaps.

Let's see some code. Within my onDrawFrame method, I do something like this:

public void onDrawFrame(GL10 gl) {

        // Get sensors matrix
                ...


        //Clear Screen And Depth Buffer
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        // Load remapped matrix
        gl.glMatrixMode(GL10.GL_MODELVIEW);



        // List of Points of interest (modified when some data is downloaded)
        synchronized (poiList) {

            if(mNewData){  // True if new data has been dowloaded)
                if(textures != null)  // Delete old textures
                    gl.glDeleteTextures(textures.length, textures, 0);

                textures = loadGLTexture(gl, soapPoiList.getPoiList());
                mNewData = false;
            }

            int i = 0;
            // Iterate the list
            for (PointOfInterest c : poiList) {

                         gl.glLoadIdentity();
                 gl.glLoadMatrixf(remappedRotationMatrix, 0);

                 // Get bearing
                             ...

                 // Place polygon in the right place
                 gl.glRotatef(-bearing, 0, 0, 1);
                 gl.glTranslatef(0, ICONS_SIZE_RATIO, 0);

                         // Actually draws the polygon with text
                 c.draw(gl, textures[i]);

                 i++;
            }
        }
    }

Where loadGLTextures is:

protected int[] loadGLTexture(GL10 gl, List<PointOfInterest> l){
    int res[] = new int[l.size()];
    gl.glGenTextures(res.length, res, 0);
    int i = 0;

    for(PointOfInterest p : l) {
        Bitmap bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.RGB_565);
        bitmap.eraseColor(Color.BLACK);

        Canvas canvas = new Canvas(bitmap);

        Paint textPaint = new Paint();
        textPaint.setTextSize(35);
        textPaint.setFakeBoldText(true);
        textPaint.setAntiAlias(true);
        textPaint.setARGB(255, 255, 255, 255);
        // Draw the text centered
        canvas.drawText(Float.toString(p.getDinstanceToOrigin()) + " m.", 10,35, textPaint);

        // Bind the texture to our array
        gl.glBindTexture(GL10.GL_TEXTURE_2D, res[i]);

        //  Create Nearest Filtered Texture
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_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, bitmap, 0);

        bitmap.recycle();

        i++;
    }
    return res;
}

It basically creates a bitmap for each Point of Interest, and generate a texture with it. The texture will be applied over a white square later, as it is shown in this class:

    public class PointOfInterest {

        // MEMBERS ----------------------------------------------------------------
            ....
            ....

        // OpenGL necessary variables
        /** The buffer holding the vertices */
        private FloatBuffer vertexBuffer;

        /** The initial vertex definition */
        private float vertices[] = { 
                                    -1.0f, 0.0f, -1.0f, //Bottom Left   V1
                                    -1.0f, 0.0f,  1.0f, //Top Left      V2
                                     1.0f, 0.0f, -1.0f, //Bottom Right  V3
                                     1.0f, 0.0f,  1.0f, //Top Right     V4
                                   };

        private FloatBuffer textureBuffer;
        private float texture[] = {
                                    0.0f, 0.0f,     // V1
                                    1.0f, 0.0f,     // V3
                                    0.0f, 1.0f,     // V2
                                    1.0f, 1.0f      // V4
        };

        // CONSTRUCTORS -----------------------------------------------------------

        public PointOfInterest(Location originLocation){
            currentLocation = originLocation;

            mPoiLocation = new Location(LocationManager.GPS_PROVIDER);

            ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
            byteBuf.order(ByteOrder.nativeOrder());

            vertexBuffer = byteBuf.asFloatBuffer();
            vertexBuffer.put(vertices);
            vertexBuffer.position(0);

            byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
            byteBuf.order(ByteOrder.nativeOrder());

            textureBuffer = byteBuf.asFloatBuffer();
            textureBuffer.put(texture);
            textureBuffer.position(0);
        }

        // PUBLIC METHODS ---------------------------------------------------------

        public void draw(GL10 gl, int textureId){
            // Bind the previously generated texture
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);

            // Point to our buffers
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

            // set the colour for the square
            //gl.glColor4f(0.0f, 0.1f, 0.0f, 0.5f);

            //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 have tried to map the texture as it is taught here and here with no success. I really don't know what to do to get some letters drawn on the squares and am really lost here... Maybe the text is being drawn on the other face of the square, maybe the textures are not being generated... I don't know.

Any kind of help would be very appreciated.

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

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

发布评论

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

评论(1

心奴独伤 2024-12-11 17:09:36

好吧,我忘了启用纹理映射。您可以在任何使用 GL10 对象的方法中执行此操作。我更喜欢在对象的绘制方法中执行此操作,因此任何其他对象都不会受到纹理的影响。就这么简单(只改变了两行,即新的!!):

public void draw(GL10 gl, int textureId){
    gl.glEnable(GL10.GL_TEXTURE_2D);    //NEW !!! Enable Texture Mapping

    // Bind the previously generated texture
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);

    // Point to our buffers
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

    // set the colour for the square
    //gl.glColor4f(0.0f, 0.1f, 0.0f, 0.5f);

    //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.glDisable(GL10.GL_TEXTURE_2D);   ////NEW !!! Disable texture mapping
}

Okay, I had forgotten to enable texture mapping. You can do that within any method that uses the GL10 object. I prefer to do it within the draw method of my objects, so any other object is not affected by the texture. It's as simple as this (just changed 2 lines, the ones that say NEW!!):

public void draw(GL10 gl, int textureId){
    gl.glEnable(GL10.GL_TEXTURE_2D);    //NEW !!! Enable Texture Mapping

    // Bind the previously generated texture
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);

    // Point to our buffers
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

    // set the colour for the square
    //gl.glColor4f(0.0f, 0.1f, 0.0f, 0.5f);

    //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.glDisable(GL10.GL_TEXTURE_2D);   ////NEW !!! Disable texture mapping
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文