zoukankan      html  css  js  c++  java
  • [原]零基础学习SDL开发之在Android使用SDL2.0加载字体

    在上一篇文章我们知道了如何在android使用SDL2.0来渲染显示一张png图,而且在上上一篇我们知道如何使用sdl来渲染输出bmp图,那么sdl是否可以渲染输出自己喜爱的字体库的字体呢?答案是当然可以。

    我们需要移植SDL_ttf字体库来支持相应的字体的渲染输出。

    一、移植SDL_ttf库:

    使用如下命令,从SDL Mercurial获取SDL_image的源码:

    hg clone https://hg.libsdl.org/SDL_ttf/

    SDL_ttf拷贝到在上一篇文章中的android-projectjni下,将平台相关的代码去掉以及自动自动化相关的文件去掉,保留android相关的代码与文件。

    二、在android中添加相关的引用:

    修改android-projectjnisrcAndroid.mk,添加相关的引用:

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := main
    
    SDL_PATH := ../SDL
    SDL_IMAGE_PATH := ../SDL2_image
    SDL_TTF_PATH := ../SDL_ttf
    
    LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include 
    LOCAL_C_INCLUDES +=    $(LOCAL_PATH)/$(SDL_IMAGE_PATH)
    LOCAL_C_INCLUDES +=    $(LOCAL_PATH)/$(SDL_TTF_PATH)
    
    # Add your application source files here...
    LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c 
        SDL_lesson.c
    
    LOCAL_SHARED_LIBRARIES := SDL2
    LOCAL_SHARED_LIBRARIES += SDL2_image
    LOCAL_SHARED_LIBRARIES += SDL2_ttf
    
    LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog
    
    include $(BUILD_SHARED_LIBRARY)

    三、代码中引用相关的头文件:

    /*
     * SDL_lesson.c
     * Clipping Sprite Sheets
     *  Created on: Aug 12, 2014
     *      Author: clarck
     */
    #include <jni.h>
    #include "SDL.h"
    #include "SDL_image.h"
    #include "SDL_ttf.h"
    #include "SDL_logger.h"
    #include "SDL_main.h"
    #include "SDL_cleanup.h"
    
    //The attributes of the screen
    const int SCREEN_WIDTH = 640;
    const int SCREEN_HEIGHT = 480;
    
    struct SDL_Window *window = NULL;
    struct SDL_Renderer *render = NULL;
    
    struct SDL_Texture *background = NULL;
    struct SDL_Texture *image = NULL;
    
    struct SDL_Surface *surface = NULL;
    struct SDL_Texture *texture = NULL;

    四、加载图片的部分修改为IMG_LoadTexture:

    * SDL_lesson.c
     * Clipping Sprite Sheets
     *  Created on: Aug 12, 2014
     *      Author: clarck
     */
    #include <jni.h>
    #include "SDL.h"
    #include "SDL_image.h"
    #include "SDL_ttf.h"
    #include "SDL_logger.h"
    #include "SDL_main.h"
    #include "SDL_cleanup.h"
    
    //The attributes of the screen
    const int SCREEN_WIDTH = 640;
    const int SCREEN_HEIGHT = 480;
    
    struct SDL_Window *window = NULL;
    struct SDL_Renderer *render = NULL;
    
    struct SDL_Texture *background = NULL;
    struct SDL_Texture *image = NULL;
    
    struct SDL_Surface *surface = NULL;
    struct SDL_Texture *texture = NULL;
    
    /*
     * Loads a image into a texture on the rendering device
     * @param file The image file to load
     * @param ren The renderer to load the texture onto
     * @return the loaded texture, or NULL if something went wrong.
     */
    SDL_Texture* loadTexture(const char *file, SDL_Renderer *render) {
        struct SDL_Texture *texture = NULL;
    
        texture = IMG_LoadTexture(render, file);
    
        if (texture == NULL) {
            LOGE("SDL_CreateTextureFromSurface failed %s", SDL_GetError());
        } else {
            LOGI("SDL_CreateTextureFromSurface successful.");
        }
    
        return texture;
    }
    
    /*
     * Draw an SDL_Texture to an SDL_Renderer at position x, y, preserving
     * the texture's width and height
     * @param tex The source texture we want to draw
     * @param ren The renderer we want to draw too
     * @param x The x coordinate to draw too
     * @param y The y coordinate to draw too
     * @param w The width of the texture to draw
     * @param h The height of the texture to draw
     */
    void renderTexture(SDL_Texture *tex, SDL_Renderer *ren, SDL_Rect dst,
            SDL_Rect *clip) {
        SDL_RenderCopy(ren, tex, clip, &dst);
    }
    
    /*
     * Draw an SDL_Texture to an SDL_Renderer at position x, y, preserving
     * the texture's width and height and taking a clip of the texture if desired
     * If a clip is passed, the clip's width and height will be used instead of the texture's
     * @param tex The source texture we want to draw
     * @param rend The renderer we want to draw too
     * @param x The x coordinate to draw too
     * @param y The y coordinate to draw too
     * @param clip The sub-section of the texture to draw (clipping rect)
     *        default of nullptr draws the entire texture
     */
    void renderTexture2(SDL_Texture *tex, SDL_Renderer *ren, int x, int y,
            SDL_Rect *clip) {
        SDL_Rect dst;
        dst.x = x;
        dst.y = y;
        if (clip != NULL) {
            dst.w = clip->w;
            dst.h = clip->h;
        } else {
            SDL_QueryTexture(tex, NULL, NULL, &dst.w, &dst.h);
        }
        renderTexture(tex, ren, dst, clip);
    }

    五、添加字体渲染功能函数:

    /*
     * SDL_lesson.c
     * Clipping Sprite Sheets
     *  Created on: Aug 12, 2014
     *      Author: clarck
     */
    #include <jni.h>
    #include "SDL.h"
    #include "SDL_image.h"
    #include "SDL_ttf.h"
    #include "SDL_logger.h"
    #include "SDL_main.h"
    #include "SDL_cleanup.h"
    
    //The attributes of the screen
    const int SCREEN_WIDTH = 640;
    const int SCREEN_HEIGHT = 480;
    
    struct SDL_Window *window = NULL;
    struct SDL_Renderer *render = NULL;
    
    struct SDL_Texture *background = NULL;
    struct SDL_Texture *image = NULL;
    
    struct SDL_Surface *surface = NULL;
    struct SDL_Texture *texture = NULL;
    
    /*
     * Loads a image into a texture on the rendering device
     * @param file The image file to load
     * @param ren The renderer to load the texture onto
     * @return the loaded texture, or NULL if something went wrong.
     */
    SDL_Texture* loadTexture(const char *file, SDL_Renderer *render) {
        struct SDL_Texture *texture = NULL;
    
        texture = IMG_LoadTexture(render, file);
    
        if (texture == NULL) {
            LOGE("SDL_CreateTextureFromSurface failed %s", SDL_GetError());
        } else {
            LOGI("SDL_CreateTextureFromSurface successful.");
        }
    
        return texture;
    }
    
    /*
     * Draw an SDL_Texture to an SDL_Renderer at position x, y, preserving
     * the texture's width and height
     * @param tex The source texture we want to draw
     * @param ren The renderer we want to draw too
     * @param x The x coordinate to draw too
     * @param y The y coordinate to draw too
     * @param w The width of the texture to draw
     * @param h The height of the texture to draw
     */
    void renderTexture(SDL_Texture *tex, SDL_Renderer *ren, SDL_Rect dst,
            SDL_Rect *clip) {
        SDL_RenderCopy(ren, tex, clip, &dst);
    }
    
    /*
     * Draw an SDL_Texture to an SDL_Renderer at position x, y, preserving
     * the texture's width and height and taking a clip of the texture if desired
     * If a clip is passed, the clip's width and height will be used instead of the texture's
     * @param tex The source texture we want to draw
     * @param rend The renderer we want to draw too
     * @param x The x coordinate to draw too
     * @param y The y coordinate to draw too
     * @param clip The sub-section of the texture to draw (clipping rect)
     *        default of nullptr draws the entire texture
     */
    void renderTexture2(SDL_Texture *tex, SDL_Renderer *ren, int x, int y,
            SDL_Rect *clip) {
        SDL_Rect dst;
        dst.x = x;
        dst.y = y;
        if (clip != NULL) {
            dst.w = clip->w;
            dst.h = clip->h;
        } else {
            SDL_QueryTexture(tex, NULL, NULL, &dst.w, &dst.h);
        }
        renderTexture(tex, ren, dst, clip);
    }
    
    SDL_Texture* renderText(char *message, char *fontFile, SDL_Color color,
            int fontSize, SDL_Renderer *renderer) {
        //Open the font
        TTF_Font *font = TTF_OpenFont(fontFile, fontSize);
    
        if (font == NULL) {
            LOGE("renderText error: %s", SDL_GetError());
            return NULL;
        }
    
        surface = TTF_RenderText_Blended(font, message, color);
        if (surface == NULL) {
            TTF_CloseFont(font);
            LOGE("TTF_RenderText_Blended error: %s", SDL_GetError());
            return NULL;
        }
    
        texture = SDL_CreateTextureFromSurface(renderer, surface);
        if (texture == NULL) {
            LOGE("SDL_CreateTextureFromSurface error: %s", SDL_GetError());
        }
    
        //Clean up the surface and font
        SDL_FreeSurface(surface);
        TTF_CloseFont(font);
        return texture;
    }

    六、编写主函数功能:

    /*
     * SDL_lesson.c
     * Clipping Sprite Sheets
     *  Created on: Aug 12, 2014
     *      Author: clarck
     */
    #include <jni.h>
    #include "SDL.h"
    #include "SDL_image.h"
    #include "SDL_ttf.h"
    #include "SDL_logger.h"
    #include "SDL_main.h"
    #include "SDL_cleanup.h"
    
    //The attributes of the screen
    const int SCREEN_WIDTH = 640;
    const int SCREEN_HEIGHT = 480;
    
    struct SDL_Window *window = NULL;
    struct SDL_Renderer *render = NULL;
    
    struct SDL_Texture *background = NULL;
    struct SDL_Texture *image = NULL;
    
    struct SDL_Surface *surface = NULL;
    struct SDL_Texture *texture = NULL;
    
    /*
     * Loads a image into a texture on the rendering device
     * @param file The image file to load
     * @param ren The renderer to load the texture onto
     * @return the loaded texture, or NULL if something went wrong.
     */
    SDL_Texture* loadTexture(const char *file, SDL_Renderer *render) {
        struct SDL_Texture *texture = NULL;
    
        texture = IMG_LoadTexture(render, file);
    
        if (texture == NULL) {
            LOGE("SDL_CreateTextureFromSurface failed %s", SDL_GetError());
        } else {
            LOGI("SDL_CreateTextureFromSurface successful.");
        }
    
        return texture;
    }
    
    /*
     * Draw an SDL_Texture to an SDL_Renderer at position x, y, preserving
     * the texture's width and height
     * @param tex The source texture we want to draw
     * @param ren The renderer we want to draw too
     * @param x The x coordinate to draw too
     * @param y The y coordinate to draw too
     * @param w The width of the texture to draw
     * @param h The height of the texture to draw
     */
    void renderTexture(SDL_Texture *tex, SDL_Renderer *ren, SDL_Rect dst,
            SDL_Rect *clip) {
        SDL_RenderCopy(ren, tex, clip, &dst);
    }
    
    /*
     * Draw an SDL_Texture to an SDL_Renderer at position x, y, preserving
     * the texture's width and height and taking a clip of the texture if desired
     * If a clip is passed, the clip's width and height will be used instead of the texture's
     * @param tex The source texture we want to draw
     * @param rend The renderer we want to draw too
     * @param x The x coordinate to draw too
     * @param y The y coordinate to draw too
     * @param clip The sub-section of the texture to draw (clipping rect)
     *        default of nullptr draws the entire texture
     */
    void renderTexture2(SDL_Texture *tex, SDL_Renderer *ren, int x, int y,
            SDL_Rect *clip) {
        SDL_Rect dst;
        dst.x = x;
        dst.y = y;
        if (clip != NULL) {
            dst.w = clip->w;
            dst.h = clip->h;
        } else {
            SDL_QueryTexture(tex, NULL, NULL, &dst.w, &dst.h);
        }
        renderTexture(tex, ren, dst, clip);
    }
    
    SDL_Texture* renderText(char *message, char *fontFile, SDL_Color color,
            int fontSize, SDL_Renderer *renderer) {
        //Open the font
        TTF_Font *font = TTF_OpenFont(fontFile, fontSize);
    
        if (font == NULL) {
            LOGE("renderText error: %s", SDL_GetError());
            return NULL;
        }
    
        surface = TTF_RenderText_Blended(font, message, color);
        if (surface == NULL) {
            TTF_CloseFont(font);
            LOGE("TTF_RenderText_Blended error: %s", SDL_GetError());
            return NULL;
        }
    
        texture = SDL_CreateTextureFromSurface(renderer, surface);
        if (texture == NULL) {
            LOGE("SDL_CreateTextureFromSurface error: %s", SDL_GetError());
        }
    
        //Clean up the surface and font
        SDL_FreeSurface(surface);
        TTF_CloseFont(font);
        return texture;
    }
    
    int main(int argc, char *argv[]) {
        //char *filefolder = "/storage/sdcard0/";
        char *filefolder = argv[1];
    
        char *font_temp = "sample.ttf";
        char *image_temp = "image.png";
        char *background_temp = "background.png";
        LOGI("natvie_SDL %s", filefolder);
    
        char *background_file = (char*) malloc(
                strlen(filefolder) + strlen(background_temp) + 1);
        strcpy(background_file, filefolder);
        strcat(background_file, background_temp);
        LOGI("natvie_SDL background_file : %s", background_file);
    
        char *image_file = (char*) malloc(
                strlen(filefolder) + strlen(image_temp) + 1);
        strcpy(image_file, filefolder);
        strcat(image_file, image_temp);
        LOGI("natvie_SDL image_file : %s", image_file);
    
        char *font_file = (char*) malloc(
                strlen(filefolder) + strlen(font_temp) + 1);
        strcpy(font_file, filefolder);
        strcat(font_file, font_temp);
        LOGI("natvie_SDL font_file : %s", font_file);
    
        if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
            LOGE("SDL_Init failed %s", SDL_GetError());
            return 1;
        }
    
        if (TTF_Init() != 0) {
            LOGE("TTF_Init failed %s", SDL_GetError());
            SDL_Quit();
            return 1;
        }
    
        window = SDL_CreateWindow("lesson5", 100, 100, SCREEN_WIDTH, SCREEN_HEIGHT,
                SDL_WINDOW_SHOWN);
        if (window == NULL) {
            LOGE("SDL_CreateWindow failed %s", SDL_GetError());
            TTF_Quit();
            SDL_Quit();
            return 1;
        }
    
        render = SDL_CreateRenderer(window, -1,
                SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
        if (render == NULL) {
            LOGE("SDL_CreateRenderer failed %s", SDL_GetError());
            cleanup_window(window);
            TTF_Quit();
            SDL_Quit();
            return 1;
        }
    
        SDL_Color color = { 255, 255, 255, 255 };
    
        image = renderText("TTF fonts are cool !", font_file, color, 64, render);
    
        if (image == NULL) {
            cleanup_texture(image);
            cleanup_render(render);
            cleanup_window(window);
            TTF_Quit();
            SDL_Quit();
            return 1;
        }
    
        //Clear the window
        SDL_RenderClear(render);
    
        //Draw our image in the center of the window
        //We need the foreground image's width to properly compute the position
        //of it's top left corner so that the image will be centered
        int iW, iH;
        int x = SCREEN_WIDTH / 2 - iW / 2;
        int y = SCREEN_HEIGHT / 2 - iH / 2;
    
        SDL_Event e;
        int quit = 1;
        while (quit != 0) {
            //Read any events that occured, for now we'll just quit if any event occurs
            while (SDL_PollEvent(&e)) {
                //If user closes the window
                if (e.type == SDL_QUIT) {
                    quit = 0;
                }
                if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE) {
                    quit = 0;
                }
            }
    
            //Rendering
            SDL_RenderClear(render);
    
            //Draw the image
            renderTexture2(image, render, x, y, NULL);
            SDL_RenderPresent(render);
        }
        //Destroy the various items
        cleanup_texture(image);
        cleanup_render(render);
        cleanup_window(window);
        IMG_Quit();
        SDL_Quit();
    
        return 0;
    }

    七、修改SDLActivity,添加SDL_ttf动态库的load:

    // Load the .so
        static {
            System.loadLibrary("SDL2");
            System.loadLibrary("SDL2_image");
            //System.loadLibrary("SDL2_mixer");
            //System.loadLibrary("SDL2_net");
            System.loadLibrary("SDL2_ttf");
            System.loadLibrary("main");
        }

    运行截图:

  • 相关阅读:
    【秋招必备】Redis面试题(2021最新版)
    【秋招必备】Spring Boot面试题(2021最新版)
    【秋招必备】Java基础知识面试题(2021最新版)
    用友二面:如何设计一个高可用、高并发秒杀系统
    万字长文,带你深入理解Java虚拟机!
    小米面试官:说说Spring源码里面的Bean的生命周期!
    苏宁易购三面:写一个脚本获取Linux系统CPU的详细信息,并说出原理!
    易错点。
    APP间传递消息
    KVC, KVO
  • 原文地址:https://www.cnblogs.com/tanlon/p/3928384.html
Copyright © 2011-2022 走看看