Android中编译和使用LuaJIT开发应用

$ git clone http://luajit.org/git/luajit-2.0.git
$ cd luajit-2.0
$ NDK=/opt/android/ndk
$ NDKABI=8
$ NDKVER=$NDK/toolchains/arm-linux-androideabi-4.6
$ NDKP=$NDKVER/prebuilt/darwin-x86/bin/arm-linux-androideabi-
$ NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm"
$ make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF" TARGET_SYS=Linux #在OS X下编译需要指明TARGET_SYS

参考:http://luajit.org/install.html

本例子中使用的是ndk中的hello-jni工程

$ cp src/{libluajit.a,lua.h,lauxlib.h,lua.hpp,luaconf.h,luajit.h,lualib.h} \
> ../android/jni  # android工程jni目录
$ vim ../android/jni/Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c
LOCAL_LDLIBS := $(LOCAL_PATH)/libluajit.a   #加上这句

include $(BUILD_SHARED_LIBRARY)
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"  // 引入头文件

lua_State* L;         // Lua指针

jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    L = lua_open();   // 打开Lua指针
    luaL_openlibs(L);
    luaL_dostring(L, "return 'Hello from Lua !'");  // 执行Lua语句
    const char * str = lua_tostring(L, -1);         // 获取Lua语句的返回值
    lua_close(L);

    return (*env)->NewStringUTF(env, str);
}

Cocos2d-x之使用tolua++生成lua对象

1.保留枚举类型 2.删除CC_DLL,改用多继承 3.删除inline内联关键字 4.删除public等访问限定词 5.删除成员变量 6.保留static关键字 7.删除非public的函数
class CCScale9Sprite : public CCNode
{
    void setPreferredSize(CCSize size);
    static CCScale9Sprite* create(const char *pszFileName);
};
$#include "LuaCocos2d.h"

$pfile "CCScale9Sprite.pkg"
执行 @./tolua++ -tCocos2d -o CCScale9Sprite.cpp Cocos2d.pkg@ 把生成的内容拷贝到LuaCocos2d.cpp,注意位置
// static void tolua_reg_types (lua_State* tolua_S)
tolua_usertype(tolua_S,"CCScale9Sprite");

/* method: setPreferredSize of class  CCScale9Sprite */
#ifndef TOLUA_DISABLE_tolua_Cocos2d_CCScale9Sprite_setPreferredSize00
static int tolua_Cocos2d_CCScale9Sprite_setPreferredSize00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     !tolua_isusertype(tolua_S,1,"CCScale9Sprite",0,&tolua_err) ||
     (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"CCSize",0,&tolua_err)) ||
     !tolua_isnoobj(tolua_S,3,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  CCScale9Sprite* self = (CCScale9Sprite*)  tolua_tousertype(tolua_S,1,0);
  CCSize size = *((CCSize*)  tolua_tousertype(tolua_S,2,0));
#ifndef TOLUA_RELEASE
  if (!self) tolua_error(tolua_S,"invalid 'self' in function 'setPreferredSize'", NULL);
#endif
  {
   self->setPreferredSize(size);
  }
 }
 return 0;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'setPreferredSize'.",&tolua_err);
 return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE

/* method: create of class  CCScale9Sprite */
#ifndef TOLUA_DISABLE_tolua_Cocos2d_CCScale9Sprite_create00
static int tolua_Cocos2d_CCScale9Sprite_create00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     !tolua_isusertable(tolua_S,1,"CCScale9Sprite",0,&tolua_err) ||
     !tolua_isstring(tolua_S,2,0,&tolua_err) ||
     !tolua_isnoobj(tolua_S,3,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  const char* pszFileName = ((const char*)  tolua_tostring(tolua_S,2,0));
  {
   CCScale9Sprite* tolua_ret = (CCScale9Sprite*)  CCScale9Sprite::create(pszFileName);
    tolua_pushusertype(tolua_S,(void*)tolua_ret,"CCScale9Sprite");
  }
 }
 return 1;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'create'.",&tolua_err);
 return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE

// TOLUA_API int tolua_Cocos2d_open (lua_State* tolua_S)
  tolua_cclass(tolua_S,"CCScale9Sprite","CCScale9Sprite","CCNode",NULL);
  tolua_beginmodule(tolua_S,"CCScale9Sprite");
   tolua_function(tolua_S,"setPreferredSize",tolua_Cocos2d_CCScale9Sprite_setPreferredSize00);
   tolua_function(tolua_S,"create",tolua_Cocos2d_CCScale9Sprite_create00);
  tolua_endmodule(tolua_S);
#include "cocos-ext.h"
using namespace cocos2d::extension;
local sprite = CCScale9Sprite:create("image.png")
sprite:setPreferredSize(CCSizeMake(100, 100))

每日日记

今天主要是学习Cocos2d-x平台下如何使用Lua做动态模块,因为工作需要开发一个插件式的应用,希望通过下载一个模块来增加新功能,了解到Lua是很不错的脚本语言,在查看Cocos2d-X官方2.0版本的时候无意看到spidermonkey,Google了一下才知道原来是javascript的C++解析器,能够在C++中直接调用javascript,也能够实现脚本的动态加载,不过仔细查看了一下,如果要在javascript中调用Cocos2d-x中的对象还需要绑定,目前官方实现的对象还没有Lua中的丰富,看来是刚刚弄起来的东西,不过相信以后会更加完善的,目前还是先使用Lua来实现这个动态加载的功能。

目前的想法是使用Lua实现一个新的场景,然后通过CCDirector都进行场景的切换,做了简单的测试这个可以实现,不过在进行测试的时候有用到CCScale9Sprite这个对象,不过官方的LuaCocos2d.cpp中并没有注册这个对象,所以无法在Lua中直接使用该对象,还需要自己添加,不过在想直接用C++实现好一个Layer的封装,再注册这个简单接口的,而不需要注册CCScale9Sprite这个很多接口的,用到的时候直接:create()进来,不过需要作一些事件的回调。

晚上的时候看了Ubuntu开发者网站的第一个做应用的视频,才发现原来Ubuntu可以这么容易开发,不过现在用着RMBP,分辨率太高了,跑Ubuntu字太小了,在考虑要不要增加一个外置显示器。

Cocos2d-x之CCRenderTexture fix htc

    CCTexture2D         *m_pTexture;
+   CCTexture2D         *m_pTextureCopy;
    CCImage             *m_pUITextureImage;
    , m_pTexture(0)
+   , m_pTextureCopy(0)
    , m_pUITextureImage(NULL)

    bool bRet = false;
+   void *data = NULL;
    do

    unsigned int powW = ccNextPOT(w);
    unsigned int powH = ccNextPOT(h);
+   data = malloc((int)(powW * powH * 4));
    CC_BREAK_IF(! data);


    m_pTexture->initWithData(data, (CCTexture2DPixelFormat)m_ePixelFormat, powW, powH, CCSizeMake((float)w, (float)h));
-   free( data );

+   if (CCConfiguration::sharedConfiguration()->checkForGLExtension("GL_QCOM"))
+   {
+       m_pTextureCopy = new CCTexture2D();
+       CC_BREAK_IF(! m_pTextureCopy);
+       m_pTextureCopy->initWithData(data, (CCTexture2DPixelFormat)m_ePixelFormat, powW, powH, CCSizeMake((float)w, (float)h));
+   }

    } while (0);

+   CC_SAFE_FREE(data);
    return bRet;

    glGetIntegerv(CC_GL_FRAMEBUFFER_BINDING, &m_nOldFBO);
    ccglBindFramebuffer(CC_GL_FRAMEBUFFER, m_uFBO);//Will direct drawing to the frame buffer created above
+   if (CCConfiguration::sharedConfiguration()->checkForGLExtension("GL_QCOM"))
+   {
+       // -- bind a temporary texture so we can clear the render buffer without losing our texture
+       ccglFramebufferTexture2D(CC_GL_FRAMEBUFFER, CC_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_pTextureCopy->getName(), 0);
+       //CHECK_GL_ERROR_DEBUG();
+       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+       ccglFramebufferTexture2D(CC_GL_FRAMEBUFFER, CC_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_pTexture->getName(), 0);
+   }

详细参考:https://github.com/cocos2d/cocos2d-x/commit/b71d67c766d30390101e39d08cffd98c5b2a6571

Cocos2d-x之CCRenderTexture

CCRenderTexture *pRender = CCRenderTexture::renderTextureWithWidthAndHeight(width, height);
pRender->begin();

// 这里可以调用,把相应的东西画在CCRendertexture上,可以画任何东西
CCNode::visit();

pRender->end(false);

主要是使用 @glBlendFunc()@ 函数,有两个参数,前者表示源因子,后者表示目标因子。

GL_ZERO                    // 表示使用0.0作为因子,实际上相当于不使用这种颜色参与混合运算。
GL_ONE                     // 表示使用1.0作为因子,实际上相当于完全的使用了这种颜色参与混合运算。
GL_SRC_ALPHA               // 表示使用源颜色的alpha值来作为因子。
GL_DST_ALPHA               // 表示使用目标颜色的alpha值来作为因子。
GL_ONE_MINUS_SRC_ALPHA     // 表示用1.0减去源颜色的alpha值来作为因子。
GL_ONE_MINUS_DST_ALPHA     // 表示用1.0减去目标颜色的alpha值来作为因子。

如果设置了 @glBlendFunc(GL_ONE, GL_ZERO);@,则表示完全使用源颜色,完全不使用目标颜色,因此画面效果和不使用混合的时候一致。

如果设置了 @glBlendFunc(GL_ONE, GL_ONE);@,则表示完全使用源颜色和目标颜色,最终的颜色实际上就是两种颜色的简单相加。

参考:http://blog.csdn.net/aurora_mylove/article/details/1700540