精华内容
下载资源
问答
  • 主要介绍了Android openGl 绘制简单图形的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • OpenGL ES2.0实现文字绘制Android

    千次阅读 2018-10-15 11:55:32
    OpenGL ES2.0是无法直接绘制文字的,我采用的方法是将文字转为Bitmap,然后以图贴的方式进行渲染。看到网上也有人是将文字生成点,一个个进行绘制的,个人觉得这种方法还是挺麻烦的。文章分为两部分,一部分是在...

    OpenGL ES2.0是无法直接绘制文字的,我采用的方法是将文字转为Bitmap,然后以图贴的方式进行渲染。看到网上也有人是将文字生成点,一个个进行绘制的,个人觉得这种方法还是挺麻烦的。文章分为两部分,一部分是在canvas中绘图转Bitmap,第二部分是贴图纹理绘制。

    文字转Bitmap

    这部分比较麻烦,网上介绍的canvas.drawText()的资料太多,看了都让人一头雾水,我也看了一天才明白。

    • 基于文本的样式和大小,动态获取占用的宽度和高度
            Paint p = new Paint();
            p.setColor(glText.color);
            p.setTypeface(glText.font);
            p.setTextSize(glText.size);
            //获取高度
            Paint.FontMetricsInt metrics = p.getFontMetricsInt();
            int height=metrics.bottom-metrics.top;
        
            //获取宽度
            Rect rect=new Rect();
            p.getTextBounds(glText.text, 0, glText.text.length(), rect);
            int width = rect.width();//文本的宽度
    • 根据文字大小生成对应大小的Bitmap,如果统一Bitmap大小会出现文字变形和失真的现象。
            //根据文字高度宽度生成bitmap
            Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
    • 根据文字大小生成对应的OpenGL绘制矩形坐标范围大小
            float mHeight=RADIO*this.height;
            float mWidth=RADIO*this.width;
    
            return new GLRectangle(glPoint,
                    new GLPoint(glPoint.getX(),glPoint.getY()+mHeight),
                    new GLPoint(glPoint.getX()+mWidth,glPoint.getY()+mHeight)
            );

     

    •  绘制背景色和文字,drawText()中的x,y设置比较麻烦,设置不正确容易文字显示不全,这里我采用的是
            if (glText.backGroundColor != 0) {
                //如果有背景色就绘制背景色
                canvas.drawColor(glText.backGroundColor);
            }
            canvas.drawText(glText.text, 0,-metrics.ascent, p);
            canvas.save();

    OpenGL渲染绘制纹理图片

    顶点着色器

    final static String VERTEX =
                    "uniform mat4 u_Matrix;" +
                            "attribute vec4 a_Position;" +
                            "attribute vec2 a_TextureCoordinates;" +
                            "varying vec2 v_TextureCoordinates;" +
    
                            "void main()" +
                            "{" +
                            "    gl_Position =  u_Matrix * a_Position;" +
                            "    v_TextureCoordinates = a_TextureCoordinates;" +
                            "}";

    片元着色器

    final static String FRAGMENT =
                    "precision mediump float;" +
                            "uniform sampler2D u_TextureUnit;" +
                            "varying vec2 v_TextureCoordinates;" +
                            "void main()" +
                            "{" +
                            "    gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);                           \t\t\n" +
                            "}";

    处理点数据

       vertexData = ByteBuffer
                    .allocateDirect(data.length * BYTES_PER_FLOAT)
                    .order(ByteOrder.nativeOrder()).asFloatBuffer();
            vertexData.put(data);
     pointCount = 4;
            STRIDE = (POSITION_COMPONENT_COUNT + TEXTURE_COORDINATES_COMPONENT_COUNT) * BYTES_PER_FLOAT;
    
          //开启颜色混合,解决图片背景黑色问题
                glEnable(GL_BLEND);
    //            glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
                glPixelStorei(GL_UNPACK_ALIGNMENT,1);
                glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
                vertexShader = ShaderHelper.compileVertexShader(ShaderCode.VERTEX);
                fragmentShader = ShaderHelper
                        .compileFragmentShader(ShaderCode.FRAGMENT);
    
                program = ShaderHelper.linkProgram(vertexShader, fragmentShader);
                glUseProgram(program);
    
                aPositionLocation = glGetAttribLocation(program, A_POSITION);
                uMatrixLocation = glGetUniformLocation(program, U_MATRIX);
                uTextureUnitLocation = glGetUniformLocation(program, U_TEXTURE_UNIT);
                aTextureCoordinatesLocation = glGetAttribLocation(program, A_TEXTURE_COORDINATES);
                storeImage(bitmap);
                glUniform1i(uTextureUnitLocation, 0);
                vertexData.position(0);
                glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT,
                        false, STRIDE, vertexData);
    
                glEnableVertexAttribArray(aPositionLocation);
    
                vertexData.position(POSITION_COMPONENT_COUNT);
                glVertexAttribPointer(aTextureCoordinatesLocation, TEXTURE_COORDINATES_COMPONENT_COUNT, GL_FLOAT,
                        false, STRIDE, vertexData);
    
                glEnableVertexAttribArray(aTextureCoordinatesLocation);
    //材质纹理处理
      protected static void storeImage(Bitmap bitmap) {
            int[] texture = new int[1];
            glGenTextures(1, texture, 0);
            glActiveTexture(GLES20.GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, texture[0]);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
            texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
            glGenerateMipmap(GL_TEXTURE_2D);
            bitmap.recycle();
        }
    
    //设置投影转换
      glUniformMatrix4fv(uMatrixLocation, 1, false, matrix, 0);
            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    最后的效果图如下所示

     

    展开全文
  • Android OpenGL 文本显示 LabelMaker

    千次阅读 2019-04-18 10:59:27
    AndroidApiDemos 里有个LabelMaker, 封装了...LabelMaker:OpenGL text labels通过创建Bitmap、将所有text labels绘制到Bitmap、将Bitmap转换为alpha texture 以及使用gldrawtexios绘制部分texture来实现。 Ex...

    Android ApiDemos 里有个LabelMaker, 封装了OpenGl 的text lables的生产和显示,用起来非常方便:

    LabelMaker: OpenGL text labels通过创建Bitmap、将所有text labels绘制到Bitmap、将Bitmap转换为alpha texture 以及使用gldrawtexios绘制部分texture来实现。

     

    Example code:

    import android.app.Activity;
    import android.graphics.Paint;
    import android.opengl.GLSurfaceView;
    import android.os.Bundle;
    
    import javax.microedition.khronos.egl.EGLConfig;
    import javax.microedition.khronos.opengles.GL10;
    
    public class TextLablesActivity extends Activity implements GLSurfaceView.Renderer{
    
        private GLSurfaceView mGLView;
        private LabelMaker mLabels;
        private int mWidth;
        private int mHeight;
        private int mLabelId1;  //text label id
        private int mLabelId2;  //text label id
        @Override
        protected void onCreate( Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            mGLView = new GLSurfaceView(this);
            mGLView.setRenderer(this);
            setContentView(mGLView);
        }
    
    
        @Override
        public void onDrawFrame(GL10 gl) {
            mLabels.beginDrawing(gl,mWidth,mHeight);
            mLabels.draw(gl,600,600, mLabelId1);     //指定坐标,显示label 1 
            mLabels.draw(gl,600,700, mLabelId2);     //指定坐标,显示label 2
            mLabels.endDrawing(gl);
    
        }
    
        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            //调用LabelMaker 生成text label
            mLabels = new LabelMaker(true, 1080, 256); //Bitmap的宽和高, 可以根据你的text lable来调整大小
            Paint labelPaint = new Paint();  //text label的画笔
            labelPaint.setTextSize(32);
            labelPaint.setAntiAlias(true);
            labelPaint.setARGB(0xff, 0xff, 0x00, 0x00);
    
            mLabels.initialize(gl);
            mLabels.beginAdding(gl);
            mLabelId1 = mLabels.add(gl,"OpenGL 显示的文字",labelPaint);  //add lable1
            mLabelId2 = mLabels.add(gl,"Hello world !",labelPaint);  //add label2
            mLabels.endAdding(gl);
        }
    
        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            mWidth = width;
            mHeight = height;
            gl.glViewport(0, 0, width, height);
            float ratio = (float) width / height;
            gl.glMatrixMode(GL10.GL_PROJECTION);
            gl.glLoadIdentity();
            gl.glFrustumf(-ratio, ratio, -1, 1, 1, 15);
            gl.glMatrixMode(GL10.GL_MODELVIEW);
            gl.glLoadIdentity();
        }
    }

     

    LabelMaker code:

    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.Paint.Style;
    import android.graphics.drawable.Drawable;
    import android.opengl.GLUtils;
    
    import java.util.ArrayList;
    
    import javax.microedition.khronos.opengles.GL10;
    import javax.microedition.khronos.opengles.GL11;
    import javax.microedition.khronos.opengles.GL11Ext;
    
    /**
     * An OpenGL text label maker.
     *
     *
     * OpenGL labels are implemented by creating a Bitmap, drawing all the labels
     * into the Bitmap, converting the Bitmap into an Alpha texture, and drawing
     * portions of the texture using glDrawTexiOES.
     *
     * The benefits of this approach are that the labels are drawn using the high
     * quality anti-aliased font rasterizer, full character set support, and all the
     * text labels are stored on a single texture, which makes it faster to use.
     *
     * The drawbacks are that you can only have as many labels as will fit onto one
     * texture, and you have to recreate the whole texture if any label text
     * changes.
     *
     */
    public class LabelMaker {
        /**
         * Create a label maker
         * or maximum compatibility with various OpenGL ES implementations,
         * the strike width and height must be powers of two,
         * We want the strike width to be at least as wide as the widest window.
         *
         * @param fullColor true if we want a full color backing store (4444),
         * otherwise we generate a grey L8 backing store.
         * @param strikeWidth width of strike
         * @param strikeHeight height of strike
         */
        public LabelMaker(boolean fullColor, int strikeWidth, int strikeHeight) {
            mFullColor = fullColor;
            mStrikeWidth = strikeWidth;
            mStrikeHeight = strikeHeight;
            mTexelWidth = (float) (1.0 / mStrikeWidth);
            mTexelHeight = (float) (1.0 / mStrikeHeight);
            mClearPaint = new Paint();
            mClearPaint.setARGB(0, 0, 0, 0);
            mClearPaint.setStyle(Style.FILL);
            mState = STATE_NEW;
        }
    
        /**
         * Call to initialize the class.
         * Call whenever the surface has been created.
         *
         * @param gl
         */
        public void initialize(GL10 gl) {
            mState = STATE_INITIALIZED;
            int[] textures = new int[1];
            gl.glGenTextures(1, textures, 0);
            mTextureID = textures[0];
            gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
    
            // Use Nearest for performance.
            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);
    
            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);
    
            gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
                    GL10.GL_REPLACE);
        }
    
        /**
         * Call when the surface has been destroyed
         */
        public void shutdown(GL10 gl) {
            if ( gl != null) {
                if (mState > STATE_NEW) {
                    int[] textures = new int[1];
                    textures[0] = mTextureID;
                    gl.glDeleteTextures(1, textures, 0);
                    mState = STATE_NEW;
                }
            }
        }
    
        /**
         * Call before adding labels. Clears out any existing labels.
         *
         * @param gl
         */
        public void beginAdding(GL10 gl) {
            checkState(STATE_INITIALIZED, STATE_ADDING);
            mLabels.clear();
            mU = 0;
            mV = 0;
            mLineHeight = 0;
            Bitmap.Config config = mFullColor ?
                    Bitmap.Config.ARGB_4444 : Bitmap.Config.ALPHA_8;
            mBitmap = Bitmap.createBitmap(mStrikeWidth, mStrikeHeight, config);
            mCanvas = new Canvas(mBitmap);
            mBitmap.eraseColor(0);
        }
    
        /**
         * Call to add a label
         *
         * @param gl
         * @param text the text of the label
         * @param textPaint the paint of the label
         * @return the id of the label, used to measure and draw the label
         */
        public int add(GL10 gl, String text, Paint textPaint) {
            return add(gl, null, text, textPaint);
        }
    
        /**
         * Call to add a label
         *
         * @param gl
         * @param text the text of the label
         * @param textPaint the paint of the label
         * @return the id of the label, used to measure and draw the label
         */
        public int add(GL10 gl, Drawable background, String text, Paint textPaint) {
            return add(gl, background, text, textPaint, 0, 0);
        }
    
        /**
         * Call to add a label
         * @return the id of the label, used to measure and draw the label
         */
        public int add(GL10 gl, Drawable drawable, int minWidth, int minHeight) {
            return add(gl, drawable, null, null, minWidth, minHeight);
        }
    
        /**
         * Call to add a label
         *
         * @param gl
         * @param text the text of the label
         * @param textPaint the paint of the label
         * @return the id of the label, used to measure and draw the label
         */
        public int add(GL10 gl, Drawable background, String text, Paint textPaint,
                int minWidth, int minHeight) {
            checkState(STATE_ADDING, STATE_ADDING);
            boolean drawBackground = background != null;
            boolean drawText = (text != null) && (textPaint != null);
    
            Rect padding = new Rect();
            if (drawBackground) {
                background.getPadding(padding);
                minWidth = Math.max(minWidth, background.getMinimumWidth());
                minHeight = Math.max(minHeight, background.getMinimumHeight());
            }
    
            int ascent = 0;
            int descent = 0;
            int measuredTextWidth = 0;
            if (drawText) {
                // Paint.ascent is negative, so negate it.
                ascent = (int) Math.ceil(-textPaint.ascent());
                descent = (int) Math.ceil(textPaint.descent());
                measuredTextWidth = (int) Math.ceil(textPaint.measureText(text));
            }
            int textHeight = ascent + descent;
            int textWidth = Math.min(mStrikeWidth,measuredTextWidth);
    
            int padHeight = padding.top + padding.bottom;
            int padWidth = padding.left + padding.right;
            int height = Math.max(minHeight, textHeight + padHeight);
            int width = Math.max(minWidth, textWidth + padWidth);
            int effectiveTextHeight = height - padHeight;
            int effectiveTextWidth = width - padWidth;
    
            int centerOffsetHeight = (effectiveTextHeight - textHeight) / 2;
            int centerOffsetWidth = (effectiveTextWidth - textWidth) / 2;
    
            // Make changes to the local variables, only commit them
            // to the member variables after we've decided not to throw
            // any exceptions.
    
            int u = mU;
            int v = mV;
            int lineHeight = mLineHeight;
    
            if (width > mStrikeWidth) {
                width = mStrikeWidth;
            }
    
            // Is there room for this string on the current line?
            if (u + width > mStrikeWidth) {
                // No room, go to the next line:
                u = 0;
                v += lineHeight;
                lineHeight = 0;
            }
            lineHeight = Math.max(lineHeight, height);
            if (v + lineHeight > mStrikeHeight) {
                throw new IllegalArgumentException("Out of texture space.");
            }
    
            int u2 = u + width;
            int vBase = v + ascent;
            int v2 = v + height;
    
            if (drawBackground) {
                background.setBounds(u, v, u + width, v + height);
                background.draw(mCanvas);
            }
    
            if (drawText) {
                mCanvas.drawText(text,
                        u + padding.left + centerOffsetWidth,
                        vBase + padding.top + centerOffsetHeight,
                        textPaint);
            }
    
            // We know there's enough space, so update the member variables
            mU = u + width;
            mV = v;
            mLineHeight = lineHeight;
            mLabels.add(new Label(width, height, ascent,
                    u, v + height, width, -height));
            return mLabels.size() - 1;
        }
    
        /**
         * Call to end adding labels. Must be called before drawing starts.
         *
         * @param gl
         */
        public void endAdding(GL10 gl) {
            checkState(STATE_ADDING, STATE_INITIALIZED);
            gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap, 0);
            // Reclaim storage used by bitmap and canvas.
            mBitmap.recycle();
            mBitmap = null;
            mCanvas = null;
        }
    
        /**
         * Get the width in pixels of a given label.
         *
         * @param labelID
         * @return the width in pixels
         */
        public float getWidth(int labelID) {
            return mLabels.get(labelID).width;
        }
    
        /**
         * Get the height in pixels of a given label.
         *
         * @param labelID
         * @return the height in pixels
         */
        public float getHeight(int labelID) {
            return mLabels.get(labelID).height;
        }
    
        /**
         * Get the baseline of a given label. That's how many pixels from the top of
         * the label to the text baseline. (This is equivalent to the negative of
         * the label's paint's ascent.)
         *
         * @param labelID
         * @return the baseline in pixels.
         */
        public float getBaseline(int labelID) {
            return mLabels.get(labelID).baseline;
        }
    
        /**
         * Begin drawing labels. Sets the OpenGL state for rapid drawing.
         *
         * @param gl
         * @param viewWidth
         * @param viewHeight
         */
        public void beginDrawing(GL10 gl, float viewWidth, float viewHeight) {
            checkState(STATE_INITIALIZED, STATE_DRAWING);
            gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
            gl.glShadeModel(GL10.GL_FLAT);
            gl.glEnable(GL10.GL_BLEND);
            gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
            gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
            gl.glMatrixMode(GL10.GL_PROJECTION);
            gl.glPushMatrix();
            gl.glLoadIdentity();
            gl.glOrthof(0.0f, viewWidth, 0.0f, viewHeight, 0.0f, 1.0f);
            gl.glMatrixMode(GL10.GL_MODELVIEW);
            gl.glPushMatrix();
            gl.glLoadIdentity();
            // Magic offsets to promote consistent rasterization.
            gl.glTranslatef(0.375f, 0.375f, 0.0f);
        }
    
        /**
         * Draw a given label at a given x,y position, expressed in pixels, with the
         * lower-left-hand-corner of the view being (0,0).
         *
         * @param gl
         * @param x
         * @param y
         * @param labelID
         */
        public void draw(GL10 gl, float x, float y, int labelID) {
            checkState(STATE_DRAWING, STATE_DRAWING);
            Label label = mLabels.get(labelID);
            gl.glEnable(GL10.GL_TEXTURE_2D);
            ((GL11)gl).glTexParameteriv(GL10.GL_TEXTURE_2D,
                    GL11Ext.GL_TEXTURE_CROP_RECT_OES, label.mCrop, 0);
            ((GL11Ext)gl).glDrawTexiOES((int) x, (int) y, 0,
                    (int) label.width, (int) label.height);
        }
    
        /**
         * Ends the drawing and restores the OpenGL state.
         *
         * @param gl
         */
        public void endDrawing(GL10 gl) {
            checkState(STATE_DRAWING, STATE_INITIALIZED);
            gl.glDisable(GL10.GL_BLEND);
            gl.glMatrixMode(GL10.GL_PROJECTION);
            gl.glPopMatrix();
            gl.glMatrixMode(GL10.GL_MODELVIEW);
            gl.glPopMatrix();
        }
    
        private void checkState(int oldState, int newState) {
            if (mState != oldState) {
                throw new IllegalArgumentException("Can't call this method now.");
            }
            mState = newState;
        }
    
        private static class Label {
            public Label(float width, float height, float baseLine,
                    int cropU, int cropV, int cropW, int cropH) {
                this.width = width;
                this.height = height;
                this.baseline = baseLine;
                int[] crop = new int[4];
                crop[0] = cropU;
                crop[1] = cropV;
                crop[2] = cropW;
                crop[3] = cropH;
                mCrop = crop;
            }
    
            public float width;
            public float height;
            public float baseline;
            public int[] mCrop;
        }
    
        private int mStrikeWidth;
        private int mStrikeHeight;
        private boolean mFullColor;
        private Bitmap mBitmap;
        private Canvas mCanvas;
        private Paint mClearPaint;
    
        private int mTextureID;
    
        private float mTexelWidth;  // Convert texel to U
        private float mTexelHeight; // Convert texel to V
        private int mU;
        private int mV;
        private int mLineHeight;
        private ArrayList<Label> mLabels = new ArrayList<Label>();
    
        private static final int STATE_NEW = 0;
        private static final int STATE_INITIALIZED = 1;
        private static final int STATE_ADDING = 2;
        private static final int STATE_DRAWING = 3;
        private int mState;
    }
    

     

    展开全文
  • android opengl es 绘制位图字体

    千次阅读 2012-07-03 10:19:47
    Android绘制字体,用到了canvas,下面代码里面为我写的实例,几乎每行代码都有注释。 1.Activity 类 import android.app.Activity; import android.opengl.GLSurfaceView; import android.os.Bundle; public ...

    Android中绘制字体,用到了canvas,下面代码里面为我写的实例,几乎每行代码都有注释。

    1.Activity 类

    import android.app.Activity;
    import android.opengl.GLSurfaceView;
    import android.os.Bundle;
    
    public class FontOpenglActivity extends Activity {
       GLSurfaceView gView ;
       FontRenderer fontRenderer;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            gView = new GLSurfaceView(this);
            fontRenderer = new FontRenderer();
            gView.setRenderer(fontRenderer);
            setContentView(gView);
        }
    }

    2.渲染类

    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.nio.FloatBuffer;
    
    import javax.microedition.khronos.egl.EGLConfig;
    import javax.microedition.khronos.opengles.GL;
    import javax.microedition.khronos.opengles.GL10;
    
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Typeface;
    import android.opengl.GLUtils;
    import android.opengl.GLSurfaceView.Renderer;
    
    public class FontRenderer implements Renderer {
    	//位图
    	private Bitmap bitmap;
    	//四边形的顶点坐标系
    	private float[] vertex = new float[]{
    			-2.5f,-2.5f,0,
    			2.5f,-2.5f,0,
    			-2.5f,2.5f,0,
    			2.5f,2.5f,0
    	};
    	//纹理坐标系
    	private float[] coord = new float[]{
    			0,1.0f,
    			1.0f,1.0f,
    			0,0,
    			1.0f,0
    	};
    	//纹理存储定义,一般用来存名称
    	private int[] textures = new int[1];
    	//顶点、纹理缓冲
    	FloatBuffer vertexBuffer;
    	FloatBuffer coordBuffer;
    	
    	@Override
    	public void onDrawFrame(GL10 gl) {
    		gl.glClear(GL10.GL_DEPTH_BUFFER_BIT|GL10.GL_COLOR_BUFFER_BIT);
    		gl.glLoadIdentity();
    		
    		//准备顶点缓冲
    		ByteBuffer bb = ByteBuffer.allocateDirect(vertex.length * 4);
    		bb.order(ByteOrder.nativeOrder());
    		vertexBuffer = bb.asFloatBuffer();
    		vertexBuffer.put(vertex);
    		vertexBuffer.position(0);
    		//准备纹理缓冲
    		ByteBuffer coordbb = ByteBuffer.allocateDirect(coord.length * 4);
    		coordbb.order(ByteOrder.nativeOrder());
    		coordBuffer = coordbb.asFloatBuffer();
    		coordBuffer.put(coord);
    		coordBuffer.position(0);
    		//开启顶点和纹理缓冲
    		gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
    		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    		
    		//往里面进去一点
    		gl.glTranslatef(0.0f, 0.0f, -6.0f);
    		//设置顶点和纹理的位置、类型
    		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
    		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, coordBuffer);
    		//绘图
    		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
    		//取消缓冲
    		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    		gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    		//结束绘图
    		gl.glFinish();
    	}
    
    	@Override
    	public void onSurfaceChanged(GL10 gl, int width, int height) {
    		//设置场景大小
    		gl.glViewport(0, 0, width, height);
    		float ratio = (float) width / height;
    		//投影矩阵
    		gl.glMatrixMode(GL10.GL_PROJECTION);
    		//重置视图
    		gl.glLoadIdentity();
    		//设置视图的大小
    		gl.glFrustumf(-ratio, ratio, -1, 1, 1, 15);
    		// 设置观察模型
    		gl.glMatrixMode(GL10.GL_MODELVIEW);
    		gl.glLoadIdentity();
    	}
    
    	@Override
    	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    		initFontBitmap();
    		
    		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
    		// 黑色背景色
    		gl.glClearColorx(0, 0, 0, 0);
    		// 启用阴影平滑
    		gl.glShadeModel(GL10.GL_SMOOTH);
    		// 启用深度测试
    		gl.glEnable(GL10.GL_DEPTH_TEST);
    		// 深度测试类型
    		gl.glDepthFunc(GL10.GL_LEQUAL);
    		// 设置深度缓存
    		gl.glClearDepthf(1.0f);
    
    		// 启用纹理
    		gl.glEnable(GL10.GL_TEXTURE_2D);
    		// 创建纹理
    		 gl.glGenTextures(1, textures, 0);
    		// 绑定纹理
    		 gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
    		 //生成纹理
    		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 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);//缩小时	
    	}
    	/**
    	 * android中绘制字体,使用画布canvas
    	 */
    	public void initFontBitmap(){
    		String font = "需要渲染的文字测试!";
    		bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.ARGB_8888);
    		Canvas canvas = new Canvas(bitmap);
    		//背景颜色
    		canvas.drawColor(Color.LTGRAY);
    		Paint p = new Paint();
    		//字体设置
    		String fontType = "宋体";
    		Typeface typeface = Typeface.create(fontType, Typeface.BOLD);
    		//消除锯齿
    		p.setAntiAlias(true);
    		//字体为红色
    		p.setColor(Color.RED);
    		p.setTypeface(typeface);
    		p.setTextSize(28);
    		//绘制字体
    		canvas.drawText(font, 0, 100, p);
    	}
    }

    3、运行效果



    展开全文
  • opengl显示RGB数据,自己测试代码,虽杂乱但是比较简单,可以从中扣自己要的代码。
  • 提供一个类似Android Canvas类的使用OpenGL来实现实现的canvasGL。可以像传统自定义View那样直接继承GLViews,再使用这个canvas替换需要的东西。 提供类似GPUImage里的Filter的API,可以在使用画布GL画东西时实现...
  • 上篇文章准备了opengl渲染图像的环境。这片文章要做的是把freetype加载到程序中,并可以从路径中加载字体。 编译Android平台上的freetype https://www.cnblogs.com/freedreamnight/p/14930341.html这篇文章写的十分...

    上篇文章准备了opengl渲染图像的环境。这片文章要做的是把freetype加载到程序中,并可以从路径中加载字体。

    编译Android平台上的freetype

    https://www.cnblogs.com/freedreamnight/p/14930341.html这篇文章写的十分详细,要注意的是,他这里用的是静态库,我自己使用的是动态库,只需要删除–enable-static这个参数就行了。

    集成freetype到项目中

    在项目app/src/main/cpp,把头文件放入对应的目录,其实不用在意,只要在CMakeLists.txt中能找到对应的目录就行了。

    在这里插入图片描述
    修改CMakeList.txt
    这里申明一个freetype的第三方库,后面在链接的时候,添加上GLESv2和EGL,还有自己的freetype。这里还有一个重要的依赖“andorid”,这个这个其实是上一篇中ANativeWindow_fromSurface函数所在的位置。

    add_library(freetype SHARED IMPORTED)
    set_target_properties(freetype
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/freetype/lib/android/${ANDROID_ABI}/libfreetype.so)
    include_directories(
            ${CMAKE_SOURCE_DIR}/freetype/include )
            
    target_link_libraries( # Specifies the target library.
                           native-lib
                            android
                            GLESv2 EGL
                            freetype
                           # Links the target library to the log library
                           # included in the NDK.
                           ${log-lib} )
    

    添加freetype头文件

    上篇文章中忘记说头文件的事情,这里把所有依赖的头文件全部列出来。

    #include <EGL/egl.h>
    #include <GLES3/gl3.h>
    #include <android/native_window_jni.h>
    #include <android/asset_manager_jni.h>
    #include <android/asset_manager.h>
    #include "ft2build.h"
    #include FT_FREETYPE_H
    

    加载字体文件

    在android体系中,已经不再允许读取当前app沙盒以外的文件了,所以,freetype只能从内存中读取字体,这里还是利用AssetsManager从native c++层读取文件,在kotlin中,创建以下函数,然后让ide自己创建对应的native c++函数

    external fun initAsserts(assertManager: AssetManager?)
    

    在onCreate函数中添加initAsserts的调用语句

    initAsserts(getApplicationContext().resources.assets)
    

    native c++层就可以调用freetype加载字体了,值得注意的是这里的arial.ttf,需要放在android项目中的assets目录,如果项目中没有则需要自己添加一个(不能是普通目录叫做assets,需要把目录类型改成assets)。这里arial.ttf字体文件,可以从网上下载到,或者在系统中拷贝一下就行。

    AAssetManager *g_pAssetManager = AAssetManager_fromJava(env, assert_manager);
    FT_Library ft;
    if (FT_Init_FreeType(&ft))
        printf("ERROR::FREETYPE: Could not init FreeType Library");
    
    FT_Face face;
    if(g_pAssetManager){
        AAsset* fontAsset = AAssetManager_open(g_pAssetManager, "arial.ttf", AASSET_MODE_UNKNOWN);
        if (fontAsset)
        {
            size_t assetLength = AAsset_getLength(fontAsset);
            char* buffer = (char*) malloc(assetLength);
            AAsset_read(fontAsset, buffer, assetLength);
            AAsset_close(fontAsset);
            FT_New_Memory_Face(ft,(const FT_Byte *)buffer,assetLength,0,&face);
        }
    }
    
    展开全文
  • androidOpenGL实现3d动画

    热门讨论 2012-08-31 16:47:12
    这是用androidOpenGL 实现的3D 动画 导入工程即可运行。
  • Learning opengl 中关于文字渲染的部分,写的非常详细,但是在android jni环境下如何利用opengl的能力,渲染出文字,找了一圈,确实没有特别讲这块的内容,这里涉及到几点比较重要的点,首先如何把surface设置到c++...
  • 背景 公司记录仪项目,在录制视频的时候,需要添加时间水印...2 用opengles在surface上面绘制文字。 可行性分析 方案1消耗CPU来操作数据,效率不高。加上我们平台性能受限,因此舍弃。 因为我这边本身就要通过opengles
  • AndroidOpenGL开发示例

    2018-04-11 22:51:21
    主要讲解androidopengles开发相关技能,代码中有详细的注释
  • 前言前面已经讲了如何绘制点、线、面,现在就来绘制一个立方体,OpenGL ES中任何一个立体图形都是由很多面组成的,这个面指的就是三角形,所以绘制立方体就是绘制多个三角形而组合起来。绘制立方体有6个面,左、右、...
  • Android 文字绘制到Bitmap上 OpenGL ES中似乎不能输出文本.将文本写到Bitmap上,再作为贴图,则可实现文字输出. 文字绘制到Bitmap上的方法为: String mstrTitle = "文字渲染到Bitmap!"; Bitmap bmp = Bitma
  • 使用OpenGL ES进行高效文字渲染

    千次阅读 2017-09-06 11:28:31
    至少在2010年以前,我刚开始写libhwui的时候(这是一个基于Android2.0的2D绘画库),我就意识到处理文字有时会比其他方面更复杂,特别是当你尝试用GPU在屏幕上进行绘制的时候。 文字Android Android上的文字...
  • OpenGL中的3D文字绘制

    千次阅读 2016-09-01 14:21:05
    //绘制字体的显示列表的开始位置 GLYPHMETRICSFLOAT gmf[256]; //保存256个轮廓字体显示列表中对应的每一个列表的位置和方向的信息 void BuildFont() { HFONT font, oldfont; //字体句柄, 旧的字体句柄 ...
  • 1.相关基础   1.1.贴纹理原理简单概述 ...public Model parseStlWithTexture...2.4.开始绘制   效果   代码下载:https://download.csdn.net/download/weixin_37730482/10449893
  • Android OpenGLES2.0(十五)——利用EGL后台处理图像

    万次阅读 热门讨论 2017-02-20 10:36:27
    Android OpenGLES2.0(十二)——FBO离屏渲染中,记录了采用FBO进行离屏渲染的方式来进行后台处理图像,但是在使用时,示例中还是用到了GLSurfaceView控件来提供GL环境。怎样完全抛开GLSurfaceView来进行图像处理...
  • 采集Camera的预览数据,然后通过OpenGL添加水印、贴纸、美颜滤镜等后渲染到GLSurfaceView,再用MediaCodec硬编码后通过MediaMuxer写入MP4文件。
  • 最近在使用ARToolKit开源代码,Android端检测到识别图形之后叠加显示虚拟的内容; 叠加的图像由OpenGL NDK方式开发;现在想在NDK下实现画出文字 glut下glutBitmapCharacter等方式不能实现了,代码目录下有个...
  • Android OpenGL添加纹理

    2018-08-09 06:30:00
    上一篇文章【Android OpenGL添加光照和材料属性 】我们已经学了如何为3D模型添加光照和材料属性,使得模型看起来更有立体感。今天我们学习如何为3D模型贴上纹理,使得模型看起来更真实!目前我在网上没有找到带有...
  • Android中使用opengl es2.0基础(3)-正方体绘制 包含了正方体的绘制,Vertex Shader(顶点着色器)和Fragment(片断着色器)的GLSL实现,纹理贴图的坐标系和实现方法,透视投影的设置
  • OpenGL.ES在Android上的简单实践:20-水印录制(预览 gl_blend) 1、继续画出预览帧 紧接着上篇文章,既然是要画出预览帧,按照之前其他项目的架构组成。我们是通过模型FrameRect.draw的方法画出预览帧,在定义...
  • Android使用Opengl录像时添加(动态)水印

    千次阅读 热门讨论 2019-09-12 11:08:12
    我使用的是OpenGL开发的,刚开始实现的是静态水印,后面才实现的动态水印。 1、静态水印 实现原理:录像时是通过OpenGL把图像渲染到GLSurfaceView上的,通俗的讲,就是把图片画到一块画布,然后展示出来。添加图片...
  • 除了汉字,一般情况下,128个ASCII码组成的对应关系足够满足我们绘制的文本需求。 因此可以在第一次调用绘制文本时,把这128个ASCII码字符加入到一个列表中,之后绘制时只需要调用即可。 #include <windows.h&...
  • 从这篇文章开始,接下来会连载一系列的OpenGL相关博文,好好探讨...对于Android开发者来说,OpenGL就是用来绘制三维图形的技术手段,当然OpenGL并不仅限于展示静止的三维图形,也能用来播放运动着的三维动画。不管是三
  • Android利用OpenGL实现高斯模糊

    千次阅读 2018-08-26 11:26:51
    其中处理大图的时候,opengl无疑是效率最好的,java是最差的,ndk和renderscript差不多。这里我决定用opengl来实现。 先看效果 原图 模糊后 1.高斯算法 如何实现模糊,先理解什么是模糊,模糊就可...
  • Android通过openGL实现视频贴纸功能

    千次阅读 2020-01-13 18:07:02
    Android通过openGL实现视频贴纸功能 GLSL代码 1.vertex代码,文件vertex_filter_stricker.glsl attribute vec2 inputTextureCoordinate; //纹理坐标 attribute vec4 position;// 顶点坐标 varying vec2 ...
  • OpenGL绘制三维图形的流程

    千次阅读 2018-01-22 09:56:00
    不过对于初次接触OpenGL的开发者来说,三维绘图的概念可能过于抽象,所以为了方便读者理解,下面就以Android上的二维图形绘制为参考,亦步亦趋地逐步消化OpenGL的相关知识点。 从前面的学习可以得知,每个Android...
  • 2.通过bitmap创建画布canvas绘制文字 3.将bitmap内容拷贝给Opengl 纹理 4.将纹理传递会Native //this static method must be called by opengl rendor thread //which opengles environment has been successfully ...
  • 本章主要讲解如何为绘制对象添加旋转的动作 旋转形状 我们只需创建一个变换矩阵(此处以旋转为例),然后将其与投影变换和相机视角变换矩阵结合在一起。 public class MyGLRenderer implements ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,392
精华内容 1,356
热门标签
关键字:

androidopengl绘制文字