[原]零基础学习SDL开发之在Android使用SDL2.0渲染PNG图片

摘要:
在上一篇文章我们知道了如何在android使用SDL2.0来渲染显示一张bmp图,但是如果是一张png或者一张jpg的图,那么还能显示成功么?答案是否定的我们需要移植SDL_image库来支持除bmp之外的图片格式。

在上一篇文章我们知道了如何在android使用SDL2.0来渲染显示一张bmp图,但是如果是一张png或者一张jpg的图,那么还能显示成功么?答案是否定的

我们需要移植SDL_image库来支持除bmp之外的图片格式。

一、移植SDL_image库:

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

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

将SDL_image拷贝到在上一篇文章中的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

LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include 
                    $(LOCAL_PATH)/$(SDL_IMAGE_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_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_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;

四、加载图片的部分修改为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_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;

/** 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.");
    }

    returntexture;
}

五、编写主函数:

/** 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_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;

/** 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.");
    }

    returntexture;
}

/** 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, inty,
        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);
}

int main(int argc, char *argv[]) {
    //char *filefolder = "/storage/sdcard0/";
    char *filefolder = argv[1];
    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);

    char *image_file = (char*) malloc(
            strlen(filefolder) + strlen(image_temp) + 1);
    strcpy(image_file, filefolder);
    strcat(image_file, image_temp);
    LOGI("natvie_SDL %s", image_file);

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

    window = SDL_CreateWindow("lesson5", 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
    intbW, bH;
    SDL_QueryTexture(background, NULL, NULL, &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 = 100, iH = 100;
    int x = SCREEN_WIDTH / 2 - iW / 2;
    int y = SCREEN_HEIGHT / 2 - iH / 2;

    //Setup the clips for our image
    SDL_Rect clips[4];

    inti;
    for (i = 0; i < 4; i++) {
        clips[i].x = i / 2 *iW;
        clips[i].y = i % 2 *iH;
        clips[i].w =iW;
        clips[i].h =iH;
    }

    //Specify a default clip to start with
    int useClip = 0;

    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 user presses any key
            if (e.type ==SDL_KEYDOWN) {
                switch(e.key.keysym.sym) {
                caseSDLK_1:
                    useClip = 0;
                    break;

                caseSDLK_2:
                    useClip = 1;
                    break;

                caseSDLK_3:
                    useClip = 2;
                    break;

                caseSDLK_4:
                    useClip = 3;
                    break;

                caseSDLK_ESCAPE:
                    quit = 0;
                    break;

                default:
                    break;
                }
            }
            //If user clicks the mouse
            if (e.type ==SDL_MOUSEBUTTONDOWN) {
                quit = 0;
            }
        }

        //Rendering
SDL_RenderClear(render);

        //We want to tile our background so draw it 4 times
        renderTexture2(background, render, 0, 0, NULL);
        renderTexture2(background, render, bW, 0, NULL);
        renderTexture2(background, render, 0, bH, NULL);
        renderTexture2(background, render, bW, bH, NULL);

        //Draw the image
        renderTexture2(image, render, x, y,  &clips[useClip]);
        SDL_RenderPresent(render);
    }
    //Destroy the various items
cleanup_texture(image);
    cleanup_render(render);
    cleanup_window(window);
    IMG_Quit();
    SDL_Quit();

    return 0;
}

六、修改SDLActivity,加载SDL2_image库:

  //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");
    }

运行截图:

[原]零基础学习SDL开发之在Android使用SDL2.0渲染PNG图片第1张

免责声明:文章转载自《[原]零基础学习SDL开发之在Android使用SDL2.0渲染PNG图片》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇使用jQuery实现tag便签去重效果httpClient带一个或多个参数实现下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

抓取Android应用的log

今天测试软件时,遇到一个bug,因为开发说那边不复现,所以为了更好追踪这个问题,需要抓取复现步骤地log. 在网上查了相关资料,同时结合自己遇到的问题,总结如下。 1. 抓取Android 应用log的方法 2. adb server is out of date.killing的解决办法 3. 在Eclipse中怎样成功连接Android手机 1. 抓取...

5+ App开发入门指南

HTML5 Plus应用概述 HTML5 Plus移动App,简称5+App,是一种基于HTML、JS、CSS编写的运行于手机端的App,这种App可以通过扩展的JS API任意调用手机的原生能力,实现与原生App同样强大的功能和性能。 HTML5 Plus规范 通过HTML5开发移动App时,会发现HTML5很多能力不具备。为弥补HTML5能力的不足,在...

简单实用SQL脚本

行列互转 createtabletest(idint,namevarchar(20),quarterint,profileint)insertintotestvalues(1,'a',1,1000)insertintotestvalues(1,'a',2,2000)insertintotestvalues(1,'a',3,4000)insertintot...

Android开发笔记(十六)——Activity的4种启动模式

AndroidManifest 中比较重要的一个属性是 launchMode 启动模式: Acyivity的 android:launchMode 四个属性: standard:标准模式,默认 singleTop:Task栈顶复用模式(栈是先进后出,当我们启动一个Activity,如果这个目标Activity位于栈顶,不会创建一个新的实例,而是会直接...

Android研究Android系统初始化程序init和初始化配置文件init.rc分析[zz]

上篇中讲到linux内核启动与android启动的衔接是linux内核根据约定,在启动的最后执行android的init进程。init进程主要工作是首先是解析init.rc等配置文件,之后充当property service。本文收集两篇文章,能够很好的理解init的逻辑和init.rc配置文件的语法和使用方法。 1. init程序逻辑 文章引用地址:一篇...

通过案例理解position:relative和position:absolute

w3school过了HTML的知识之后,觉得要自己单纯地去啃知识点有点枯燥,然后自己也很容易忘记,所以便找具体的网站练手便补上不懂的知识点。position:relative和postion:absolute困扰了我快一个星期之久,网上找到的资料鱼龙混杂,刚确定“这样”的理解之后,看另一份资料,发现“这样”理解是错了,就这样不断更正,并记录下来,最终整理出...