代码改变世界

[原]零基础学习SDL开发之在Android使用SDL2.0显示BMP叠加图

2014-08-21 23:38  雪夜&流星  阅读(1636)  评论(3编辑  收藏  举报

关于如何移植在android上使用SDL,可以参考[原]零基础学习SDL开发之移植SDL2.0到Android 和 [原]零基础学习SDL开发之在Android使用SDL2.0显示BMP图 。

在一篇文章我们主要使用SDL2.0来加载一张BMP图来渲染显示,同时叠加一张图作为背景图。

博主的开发环境:Ubuntu 14.04 64位,Eclipse + CDT + ADT+NDK

在前面两篇文章我们知道了如何移植SDL2.0到android上面来,并且可以在Android上面来显示一张图片,这篇文章就是在前两篇文章的基础上来进行继续开发。

一、将功能模块化,将加载BMP的功能封装到一个函数中:

/*
 * SDL_Lesson.c
 *
 *  Created on: Aug 12, 2014
 *      Author: clarck
 */
#include <jni.h>
#include "SDL.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 *bmp = NULL;

/*
 * Loads a BMP image into a texture on the rendering device
 * @param file The BMP 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;
    //Load the image
    bmp = SDL_LoadBMP(file);

    if (bmp == NULL) {
        LOGE("SDL_LoadBMP failed %s", SDL_GetError());
    }
    //If the loading went ok, convert to texture and return the texture
    texture = SDL_CreateTextureFromSurface(render, bmp);
    SDL_FreeSurface(bmp);

    if (texture == NULL) {
        LOGE("SDL_CreateTextureFromSurface failed %s", SDL_GetError());
    }

    return texture;
}

二、将渲染功能封装到renderTexture函数中:

/*
 * SDL_Lesson.c
 *
 *  Created on: Aug 12, 2014
 *      Author: clarck
 */
#include <jni.h>
#include "SDL.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 *bmp = NULL;

/*
 * Loads a BMP image into a texture on the rendering device
 * @param file The BMP 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;
    //Load the image
    bmp = SDL_LoadBMP(file);

    if (bmp == NULL) {
        LOGE("SDL_LoadBMP failed %s", SDL_GetError());
    }
    //If the loading went ok, convert to texture and return the texture
    texture = SDL_CreateTextureFromSurface(render, bmp);
    SDL_FreeSurface(bmp);

    if (texture == NULL) {
        LOGE("SDL_CreateTextureFromSurface failed %s", SDL_GetError());
    }

    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
 */
void renderTexture(SDL_Texture *tex, SDL_Renderer *ren, int x, int y) {
    //Setup the destination rectangle to be at the position we want
    SDL_Rect dst;
    dst.x = x;
    dst.y = y;
    //Query the texture to get its width and height to use
    SDL_QueryTexture(tex, NULL, NULL, &dst.w, &dst.h);
    SDL_RenderCopy(ren, tex, NULL, &dst);
}

三、编写主函数功能:

/*
 * SDL_Lesson.c
 *
 *  Created on: Aug 12, 2014
 *      Author: clarck
 */
#include <jni.h>
#include "SDL.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 *bmp = NULL;

/*
 * Loads a BMP image into a texture on the rendering device
 * @param file The BMP 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;
    //Load the image
    bmp = SDL_LoadBMP(file);

    if (bmp == NULL) {
        LOGE("SDL_LoadBMP failed %s", SDL_GetError());
    }
    //If the loading went ok, convert to texture and return the texture
    texture = SDL_CreateTextureFromSurface(render, bmp);
    SDL_FreeSurface(bmp);

    if (texture == NULL) {
        LOGE("SDL_CreateTextureFromSurface failed %s", SDL_GetError());
    }

    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
 */
void renderTexture(SDL_Texture *tex, SDL_Renderer *ren, int x, int y) {
    //Setup the destination rectangle to be at the position we want
    SDL_Rect dst;
    dst.x = x;
    dst.y = y;
    //Query the texture to get its width and height to use
    SDL_QueryTexture(tex, NULL, NULL, &dst.w, &dst.h);
    SDL_RenderCopy(ren, tex, NULL, &dst);
}

int main(int argc, char *argv[]) {
    char *filefolder = argv[1];

    char *background_temp = "background.bmp";
    char *image_temp = "image.bmp";
    LOGI("natvie_SDL %s", filefolder);

    //char *background_file = "/storage/sdcard0/background.bmp";
    char *background_file = (char*) malloc(
            strlen(filefolder) + strlen(background_temp) + 1);
    strcpy(background_file, filefolder);
    strcat(background_file, background_temp);

    //char *image_file = "/storage/sdcard0/image.bmp";
    char *image_file = (char*) malloc(
            strlen(filefolder) + strlen(image_temp) + 1);
    strcpy(image_file, filefolder);
    strcat(image_file, image_temp);

    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
        LOGE("SDL_Init failed %s", SDL_GetError());
    }

    window = SDL_CreateWindow("lesson2", 100, 100, SCREEN_WIDTH, SCREEN_HEIGHT,
            SDL_WINDOW_SHOWN);
    if (window == NULL) {
        LOGE("SDL_CreateWindow failed %s", SDL_GetError());
    }

    render = SDL_CreateRenderer(window, -1,
            SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (render == NULL) {
        LOGE("SDL_CreateRenderer failed %s", SDL_GetError());
    }

    background = loadTexture(background_file, render);
    image = loadTexture(image_file, render);

    //Clear the window
    SDL_RenderClear(render);

    //Get the width and height from the texture so we know how much to move x,y by
    //to tile it correctly
    int bW, bH;
    SDL_QueryTexture(background, NULL, NULL, &bW, &bH);
    //We want to tile our background so draw it 4 times
    renderTexture(background, render, 0, 0);
    renderTexture(background, render, bW, 0);
    renderTexture(background, render, 0, bH);
    renderTexture(background, render, bW, bH);

    //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;
    SDL_QueryTexture(image, NULL, NULL, &iW, &iH);
    int x = SCREEN_WIDTH / 2 - iW / 2;
    int y = SCREEN_HEIGHT / 2 - iH / 2;
    renderTexture(image, render, x, y);

    //Update the screen
    SDL_RenderPresent(render);
    SDL_Delay(2000);

    cleanup_texture(background);
    cleanup_texture(image);
    cleanup_render(render);
    cleanup_window(window);
    SDL_Quit();

    return 0;
}

四、修改SDLActivity中的 SDLMain类,传入参数为sdcard的路径,其余修改参考上一篇文章,修改内容如下:

/**
    Simple nativeInit() runnable
*/
class SDLMain implements Runnable {
    @Override
    public void run() {
        // Runs SDL_main()
        String sdcard = Environment.getExternalStorageDirectory().getAbsolutePath();
        SDLActivity.nativeInit(sdcard);

        //Log.v("SDL", "SDL thread terminated");
    }
}

 

五、运行效果截图