因为使用到SDL与opengl的结合
本来以为window,linux下添加3D成功后,android平台也会很顺利。
结果遇到了一个讨厌的错误:
unimplemented OpenGL ES API error
经过google,baidu,发现此错误原因五花八门,解决方法也是千奇百怪。最终也没有找到适合我的。
好吧,这个问题还是解决了。方法有两种:
1.使用 opengl es2. 编译连接的库,头文件,都改成 opengl es2 的内容。这样我的手机测试没有问题。
方法一有什么问题呢?opengl es2 与 opengl es1 差别很大。 而我的非手机端需要使用opengl跟opengl es比较接近。
于是需要只使用opengl es。
最终解决方法是,修改SDL_config_android.h
将
#define SDL_VIDEO_RENDER_OGL_ES2 0
这样重新编译出了适合手机的 sdl.so
结果发现,我电脑上的模拟器也能运行我的测试程序了,意外收获。
背景上绘制一个旋转的矩形:
主函数:
#include "../sk_game/sk_inc.h"
#include "../sk_src/SkGame.h"
#ifdef __ANDROID__
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include "SkyparkJni.hpp"
skypark::SkyparkJni g_SkyparkJni;
#ifdef __cplusplus
extern "C" {
#endif
//jni接口 --begin
void Java_cn_skypark_shouhulongzhu_SkyparkGame_mySetAsset(JNIEnv* env, jclass tis,
jobject assetManager) {
AAssetManager * pAAssetManager = AAssetManager_fromJava(env, assetManager);
g_SkyparkJni.setAAssetManager(env, pAAssetManager);
}
//jni接口 --end
#ifdef __cplusplus
}
#endif
#endif
#ifdef HAVE_OPENGL
static void Render() {
//绘制2D的游戏场景
glPushMatrix();
glLoadIdentity();
glOrtho(-g_iScreenWidthHalf, g_iScreenWidthHalf, g_iScreenHeightHalf,
-g_iScreenHeightHalf, -1000, 1000);
g_SkGame.show(&g_SkShow);
glPopMatrix();
//绘制3D图形
{
#ifndef __ANDROID__
glBegin(GL_QUADS);
glVertex2f(-50,-50);
glVertex2f(50,-50);
glVertex2f(50,50);
glVertex2f(-50,50);
glEnd();
#else
GLfloat q3[] = {
-50,-50,
50,-50,
50,50,
-50,50
};
//glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, q3);
glDrawArrays(GL_TRIANGLE_FAN,0,4);
//glDisableClientState(GL_VERTEX_ARRAY);
#endif
}
//绘制3D的立方体
//draw3D();
glRotatef(5.0, 1.0, 1.0, 1.0);
}
#endif
int main(int argc, char *argv[]) {
//游戏引擎初始化
int iRet = g_SkComm.init();
if (iRet != 0) {
g_SkComm.log("[%s][%d]g_SkComm.init!=0 %d,%s\n", __FILE__, __LINE__,
iRet, g_SkComm.getErrMsg());
exit(0);
}
//显示模块初始化
g_SkShow.init(g_SkComm.getRenderer());
Sint64 siGameBegin = g_SkGameTimer.getGameMTime();
g_SkGameTimer.m_siGameLastTime = siGameBegin;
g_SkGameThread.run(g_SkGameTimer.m_siGameLastTime);
Sint64 siShowBegin = siGameBegin;
//游戏初始化
g_SkGame.init();
//g_SkComm.msleep(3000);
//g_SkComm.myexit();
#ifdef HAVE_OPENGL
{
#ifdef __ANDROID__
glMatrixMode(GL_PROJECTION | GL_MODELVIEW);
glLoadIdentity();
//坐标统一,设置大小为窗口一半
glOrtho(-g_iScreenWidthHalf, g_iScreenWidthHalf, g_iScreenHeightHalf,
-g_iScreenHeightHalf, -1000, 1000);
sk_gl_setOrtho(-g_iScreenWidthHalf, g_iScreenWidthHalf,
g_iScreenHeightHalf, -g_iScreenHeightHalf, 0, 1);
#else
//g_SkComm.log("[%s][%d]context=%d", __FILE__, __LINE__, context);
glMatrixMode(GL_PROJECTION | GL_MODELVIEW);
glLoadIdentity();
//坐标统一,设置大小为窗口一半
glOrtho(-g_iScreenWidthHalf, g_iScreenWidthHalf, g_iScreenHeightHalf,
-g_iScreenHeightHalf, -1000, 1000);
sk_gl_setOrtho(-g_iScreenWidthHalf, g_iScreenWidthHalf,
g_iScreenHeightHalf, -g_iScreenHeightHalf, 0, 1);
#endif
}
#endif
while (true) {
SkEvent event;
while (g_SkComm.poll_event(&event)) {
g_SkGame.doEvent(&event);
}
Sint64 iCurTime = g_SkGameTimer.getGameMTime();
while (g_SkGameTimer.m_siGameLastTime + g_SkGameTimer.siGameLoopMsec
< iCurTime) {
g_SkGameTimer.m_siGameLastTime += g_SkGameTimer.siGameLoopMsec;
g_SkGameThread.run(g_SkGameTimer.m_siGameLastTime);
}
bool bShow = true;
while (siShowBegin + g_SkGameTimer.siShowLoopMsec < iCurTime) {
siShowBegin += g_SkGameTimer.siShowLoopMsec;
if (bShow) {
#ifdef HAVE_OPENGL
Render();
#else
g_SkGame.show(&g_SkShow);
#endif
g_SkShow.flush();
bShow = false;
}
}
//g_SkComm.log("[%s][%d]\n", __FILE__, __LINE__);
//g_SkComm.msleep(3000);
g_SkComm.msleep(SkGameTimer::siGameManLoopMsec);
}
g_SkComm.myexit();
return 0;
}
效果如下: