문제

나는 현재 개발 작은 OpenGL 안드로이드 플랫폼을위한 게임하고 있는지 궁금하는 쉬운 방법을 렌더링하는 텍스트로의 상단에 렌더링된 프레임(HUD 처럼과 함께 선수의 점수를 etc.).텍스트가 필요 사용자 지정 글꼴을 사용하도.

봤어요 예를 들어 사용하기로 오버레이,하지만 내가 알지 못하는 경우 내가 하고 싶기 때문에 나는 할 수 있습트 게임을 다른 플랫폼에다.

어떤 아이디어가?

도움이 되었습니까?

해결책

Android SDK에는 OpenGL보기에 텍스트를 그리는 쉬운 방법이 없습니다. 다음 옵션을 남겨주세요.

  1. SurfaceView 위에 TextView를 배치하십시오. 이것은 느리고 나쁘지만 가장 직접적인 접근 방식입니다.
  2. 일반적인 문자열을 텍스처에 렌더링하고 단순히 텍스처를 그립니다. 이것은 지금까지 가장 단순하고 빠르지 만 가장 유연하지 않습니다.
  3. 스프라이트를 기반으로 한 롤 텍스트 텍스트 렌더링 코드. 2가 옵션이 아닌 경우 두 번째 최상의 선택 일 것입니다. 발을 젖게하는 좋은 방법이지만 단순 해 보이지만 기본 기능이있는 것처럼 보이지만 더 많은 기능 (텍스처 정렬, 라인 브레이크, 가변 폭 글꼴 등을 다루는 기능을 추가 할 때 더 어려워지고 도전적입니다. ) -이 경로를 취하면 도망 갈 수있는만큼 간단하게 만드십시오!
  4. 상용/오픈 소스 라이브러리를 사용하십시오. Google에서 사냥하면 주변에 몇 가지가 있습니다. 까다로운 비트는 통합 및 실행을 얻는 것입니다. 그러나 적어도, 당신이 그렇게하면, 당신은 그들이 제공하는 모든 유연성과 성숙도를 가질 것입니다.

다른 팁

텍스트를 텍스처로 렌더링하는 것보다 스프라이트 텍스트 데모가 보이는 것보다 간단합니다. 기본 아이디어는 캔버스 클래스를 사용하여 비트 맵으로 렌더링 한 다음 비트 맵을 OpenGL 텍스처로 전달하는 것입니다.

// Create an empty, mutable bitmap
Bitmap bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.ARGB_4444);
// get a canvas to paint over the bitmap
Canvas canvas = new Canvas(bitmap);
bitmap.eraseColor(0);

// get a background image from resources
// note the image format must match the bitmap format
Drawable background = context.getResources().getDrawable(R.drawable.background);
background.setBounds(0, 0, 256, 256);
background.draw(canvas); // draw the background to our bitmap

// Draw the text
Paint textPaint = new Paint();
textPaint.setTextSize(32);
textPaint.setAntiAlias(true);
textPaint.setARGB(0xff, 0x00, 0x00, 0x00);
// draw the text centered
canvas.drawText("Hello World", 16,112, textPaint);

//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 the 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();

나는 a 지도 시간 게시 된 답변이 확장됩니다 JVITELA. 기본적으로 동일한 아이디어를 사용하지만 각 문자열을 텍스처로 렌더링하는 대신 글꼴 파일의 모든 문자를 텍스처로 렌더링하고 더 이상 속도가 저하되지 않고 전체 동적 텍스트 렌더링을 허용하도록합니다 (초기화가 완료되면). .

내 방법의 주요 장점은 다양한 글꼴 Atlas 생성기와 비교할 때 모든 글꼴 변형 및 크기에 대해 큰 비트 맵을 배송하지 않고 프로젝트와 함께 작은 글꼴 파일 (.ttf .otf)을 배송 할 수 있다는 것입니다. 글꼴 파일 만 사용하여 모든 해상도에서 완벽한 품질 글꼴을 생성 할 수 있습니다 :)

그만큼 지도 시간 모든 프로젝트에서 사용할 수있는 전체 코드가 포함되어 있습니다 :)

이 링크에 따르면 :

http://code.neenbedankt.com/how-to-render-an-droid-view-to-a----- bitmap

당신은 렌더링 할 수 있습니다 모든 견해 비트 맵에. 필요에 따라보기 (텍스트, 이미지 등 포함)를 레이아웃하고 비트 맵으로 렌더링 할 수 있다고 가정 할 가치가 있습니다.

JVITELA 코드 사용 ~ 위에 해당 비트 맵을 OpenGL 텍스처로 사용할 수 있어야합니다.

로드/렌더링 코드의 CBFG와 Android 포트를 살펴보십시오. 코드를 프로젝트에 삭제하고 바로 사용할 수 있어야합니다.

CBFG- http://www.codehead.co.uk/cbfg

안드로이드 로더 - http://www.codehead.co.uk/cbfg/texfont.java

나는 스프라이트 텍스트 예제를 보았고 그러한 작업에 끔찍하게 복잡해 보인다. 나는 질감을 렌더링하는 것을 고려했지만, 성능이 발생할 수있는 걱정이 걱정된다. 대신보기와 함께 가야하고 그 다리를 건너야 할 때 포팅에 대해 걱정해야 할 수도 있습니다. :)

"스프라이트 텍스트"샘플을보십시오. glsurfaceview 샘플.

IMHO 게임에서 OpenGl es를 사용해야하는 세 가지 이유가 있습니다.

  1. 개방형 표준을 사용하여 모바일 플랫폼 간의 차이를 피하십시오.
  2. 렌더 프로세스를 더 많이 제어하기 위해;
  3. GPU 병렬 처리로부터 이익을 얻기 위해;

텍스트 그리기는 게임 디자인에서 항상 문제가되므로 물건을 그리기 때문에 위젯 등으로 일반적인 활동의 모양과 느낌을 가질 수 없습니다.

프레임 워크를 사용하여 Truetype 글꼴에서 비트 맵 글꼴을 생성하여 렌더링 할 수 있습니다. 내가 본 모든 프레임 워크는 동일한 방식으로 작동합니다. 텍스트의 정점 및 텍스처 좌표 생성 텍스트는 드로우 시간입니다. 이것은 OpenGL을 가장 효율적으로 사용하는 것이 아닙니다.

가장 좋은 방법은 코드 초기에 정점 및 텍스처에 원격 버퍼 (Vertex Buffer Objects -VBO)를 할당하여 드로우 시간에 게으른 메모리 전송 작업을 피하는 것입니다.

게임 플레이어는 텍스트를 읽는 것을 좋아하지 않으므로 오랫동안 동적으로 생성 된 텍스트를 작성하지 않습니다. 레이블의 경우 정적 텍스처를 사용하여 동적 텍스트를 시간과 점수로 남겨두고 둘 다 길이가 길어질 수 있습니다.

그래서 내 솔루션은 간단합니다.

  1. 일반적인 레이블과 경고에 대한 질감을 만듭니다.
  2. 숫자 0-9, ":", "+"및 "-"에 대한 텍스처를 만듭니다. 각 캐릭터에 대한 하나의 질감;
  3. 화면의 모든 위치에 대한 원격 VBO를 생성합니다. 해당 위치에서 정적 또는 동적 텍스트를 렌더링 할 수 있지만 VBO는 정적입니다.
  4. 텍스트가 항상 한 가지 방법으로 렌더링되므로 하나의 텍스처 vbo 만 생성합니다.
  5. 드로우 시간에는 정적 텍스트를 렌더링합니다.
  6. 다이나믹 텍스트의 경우, 위치 vbo를 엿볼 수 있고, 캐릭터 텍스처를 가져 와서 한 번에 캐릭터를 그릴 수 있습니다.

원격 정적 버퍼를 사용하는 경우 드로우 작업이 빠릅니다.

화면 위치 (화면의 대각선 백분율 기반)와 텍스처 (정적 및 문자)가있는 XML 파일을 만듭니다. 그런 다음 렌더링하기 전에이 XML을로드합니다.

높은 FPS 속도를 얻으려면 드로우 시간에 VBO를 생성하지 않아야합니다.

GL 사용을 고집하면 텍스트를 텍스처로 렌더링 할 수 있습니다. 대부분의 HUD가 비교적 정적이라고 가정하면 텍스처를 텍스처 메모리에 너무 자주로드 할 필요가 없습니다.

살펴보 CBFG 고의 안드로이드 포트/로더 코드입니다.당신이해야 할 수 있는 코드로 당신의 프로젝트 사용 습니다.

  1. CBFG

  2. 안드로이드 로더

문제가 있으로 이를 구현합니다.그것만 표시 하나의 캐릭터에도 할 변화의 글꼴 크기의 bitmap(필요한 특별한 문자)전체 그리 실패합니다.(

나는 이것을 몇 시간 동안 찾고 있었는데, 이것은 내가 accross에 온 첫 번째 기사였으며, 그것이 가장 좋은 답을 가지고 있지만 가장 인기있는 답변은 마크에서 벗어 났다고 생각합니다. 확실히 내가 필요한 것에 대해. Weichsel과 Shakazed의 답변은 버튼에 바로 있었지만 기사에는 약간 가려졌습니다. 당신을 프로젝트에 바로 잡기 위해. 여기 : 기존 샘플을 기반으로 새로운 Android 프로젝트를 작성하십시오. 아파 데모 선택 :

소스 폴더 아래를보십시오

ApiDemos/src/com/example/android/apis/graphics/spritetext

그리고 당신은 당신이 필요한 모든 것을 찾을 것입니다.

을 위한 정적 텍스트:

  • PC에 사용 된 모든 단어가있는 이미지를 생성합니다 (예 : 김프).
  • 이것을 질감으로로드하고 비행기의 재료로 사용하십시오.

을 위한 긴 텍스트 한 번에 한 번 업데이트해야합니다.

  • Android가 비트 맵 캔버스 (Jvitela의 솔루션)를 그려 보도록하십시오.
  • 이것을 비행기의 재료로로드하십시오.
  • 각 단어마다 다른 텍스처 좌표를 사용하십시오.

을 위한 숫자 (서식 00.0) :

  • 모든 숫자와 점으로 이미지를 생성합니다.
  • 이것을 비행기의 재료로로드하십시오.
  • 아래 셰이더를 사용하십시오.
  • ONDRAW 이벤트에서 셰이더로 전송 된 값 변수 만 업데이트하십시오.

    precision highp float;
    precision highp sampler2D;
    
    uniform float uTime;
    uniform float uValue;
    uniform vec3 iResolution;
    
    varying vec4 v_Color;
    varying vec2 vTextureCoord;
    uniform sampler2D s_texture;
    
    void main() {
    
    vec4 fragColor = vec4(1.0, 0.5, 0.2, 0.5);
    vec2 uv = vTextureCoord;
    
    float devisor = 10.75;
    float digit;
    float i;
    float uCol;
    float uRow;
    
    if (uv.y < 0.45) {
        if (uv.x > 0.75) {
            digit = floor(uValue*10.0);
            digit = digit - floor(digit/10.0)*10.0;
            i = 48.0 - 32.0 + digit;
            uRow = floor(i / 10.0);
            uCol = i - 10.0 * uRow;
            fragColor = texture2D( s_texture, uv / devisor * 2.0 + vec2((uCol-1.5) / devisor, uRow / devisor) );
        } else if (uv.x > 0.5) {
            uCol = 4.0;
            uRow = 1.0;
            fragColor = texture2D( s_texture, uv / devisor * 2.0 + vec2((uCol-1.0) / devisor, uRow / devisor) );
        } else if (uv.x > 0.25) {
            digit = floor(uValue);
            digit = digit - floor(digit/10.0)*10.0;
            i = 48.0 - 32.0 + digit;
            uRow = floor(i / 10.0);
            uCol = i - 10.0 * uRow;
            fragColor = texture2D( s_texture, uv / devisor * 2.0 + vec2((uCol-0.5) / devisor, uRow / devisor) );
        } else if (uValue >= 10.0) {
            digit = floor(uValue/10.0);
            digit = digit - floor(digit/10.0)*10.0;
            i = 48.0 - 32.0 + digit;
            uRow = floor(i / 10.0);
            uCol = i - 10.0 * uRow;
            fragColor = texture2D( s_texture, uv / devisor * 2.0 + vec2((uCol-0.0) / devisor, uRow / devisor) );
        } else {
            fragColor = vec4(0.0, 0.0, 0.0, 0.0);
        }
    } else {
        fragColor = vec4(0.0, 0.0, 0.0, 0.0);
    }
    gl_FragColor = fragColor;
    
    }
    

위의 코드는 텍스처 아틀라스 (텍스처)의 두 번째 열의 7 번째 열에서 0부터 시작되는 텍스처 아틀라스에 대해 작동합니다.

인용하다 https://www.shadertoy.com/view/xl23dw 데모를 위해 (잘못된 질감으로)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top