diff --git a/ChangeAppSettings.sh b/ChangeAppSettings.sh index d1f900335..96077e0c0 100755 --- a/ChangeAppSettings.sh +++ b/ChangeAppSettings.sh @@ -126,8 +126,8 @@ fi if [ -z "$VideoDepthBpp" -o -z "$AUTO" ]; then echo -echo "Video color depth - 16 BPP is the fastest, other modes are not supported" -echo -n "if you're using SDL_HWSURFACE (16)/(24)/(32) ($VideoDepthBpp): " +echo "Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only for" +echo -n "software video mode, SDL_OPENGL mode supports everything (16)/(24)/(32) ($VideoDepthBpp): " read var if [ -n "$var" ] ; then VideoDepthBpp="$var" diff --git a/bugs.txt b/bugs.txt index 235bca8ea..4f29cfbcb 100644 --- a/bugs.txt +++ b/bugs.txt @@ -9,6 +9,8 @@ Known bugs - SDL_FillRect() does not work in SDL 1.2 HW mode. +- 32-bpp color mode does not work with SW video surface, 24-bpp and 32-bpp mode does not work with SDL_HWSURFACE. + Requested features ================== diff --git a/project/java/GLSurfaceView_SDL.java b/project/java/GLSurfaceView_SDL.java index a767dbe11..5dc766f50 100644 --- a/project/java/GLSurfaceView_SDL.java +++ b/project/java/GLSurfaceView_SDL.java @@ -681,6 +681,7 @@ public class GLSurfaceView_SDL extends SurfaceView implements SurfaceHolder.Call EGLConfig[] configs) { EGLConfig closestConfig = null; int closestDistance = 1000; + String cfglog = ""; for(EGLConfig config : configs) { int r = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE, 0); @@ -699,13 +700,17 @@ public class GLSurfaceView_SDL extends SurfaceView implements SurfaceHolder.Call int distance = Math.abs(r - mRedSize) + Math.abs(g - mGreenSize) + Math.abs(b - mBlueSize) + Math.abs(a - mAlphaSize) - + Math.abs(d - mDepthSize) + Math.abs(s - mStencilSize) - + (gles2 == isGles2 ? 0 : 17); + + Math.abs( ((d > 0) == (mDepthSize > 0)) ? 0 : 16 ) + + Math.abs( ((s > 0) == (mStencilSize > 0)) ? 0 : 16 ) + + (gles2 == isGles2 ? 0 : 16); if (distance < closestDistance) { closestDistance = distance; closestConfig = config; + cfglog = "R" + r + "G" + g + "B" + b + "A" + a + " depth " + d + " stencil " + s + " GLES2 " + gles2 + + " renderable type " + findConfigAttrib(egl, display, config, EGL10.EGL_RENDERABLE_TYPE, 0); } } + Log.v("SDL", "GLSurfaceView_SDL::EGLConfigChooser::chooseConfig(): selected " + cfglog ); return closestConfig; } @@ -820,6 +825,8 @@ public class GLSurfaceView_SDL extends SurfaceView implements SurfaceHolder.Call final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; final int[] gles2_attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; + Log.v("SDL", "GLSurfaceView_SDL::EglHelper::start(): Gles2 " + mEGLConfigChooser.isGles2Required()); + mEglContext = mEgl.eglCreateContext(mEglDisplay, mEglConfig, EGL10.EGL_NO_CONTEXT, mEGLConfigChooser.isGles2Required() ? gles2_attrib_list : null ); diff --git a/project/java/MainActivity.java b/project/java/MainActivity.java index 1fb8fffed..ceb4eddbf 100644 --- a/project/java/MainActivity.java +++ b/project/java/MainActivity.java @@ -450,6 +450,7 @@ public class MainActivity extends Activity { { if(Globals.NeedGles2) System.loadLibrary("GLESv2"); + System.out.println("libSDL: loaded GLESv2 lib"); } catch ( UnsatisfiedLinkError e ) { diff --git a/project/jni/application/ballfield/AndroidAppSettings.cfg b/project/jni/application/ballfield/AndroidAppSettings.cfg index d00a4f934..6ef0d3d98 100644 --- a/project/jni/application/ballfield/AndroidAppSettings.cfg +++ b/project/jni/application/ballfield/AndroidAppSettings.cfg @@ -6,10 +6,14 @@ AppFullName=net.olofson.ballfield ScreenOrientation=h InhibitSuspend=n AppDataDownloadUrl="Game data is 1 Mb|ballfield.zip" +VideoDepthBpp=24 +NeedDepthBuffer=n +NeedStencilBuffer=n +NeedGles2=n +SwVideoMode=y SdlVideoResize=y SdlVideoResizeKeepAspect=n -NeedDepthBuffer=n -SwVideoMode=y +CompatibilityHacks=n AppUsesMouse=y AppNeedsTwoButtonMouse=y AppNeedsArrowKeys=n @@ -24,6 +28,7 @@ AppTouchscreenKeyboardKeysAmountAutoFire=0 RedefinedKeysScreenKb="1 2 3 4 5 6 1 2 3 4" StartupMenuButtonTimeout=3000 HiddenMenuOptions='' +FirstStartMenuOptions='' MultiABI=y AppVersionCode=101 AppVersionName="1.01" diff --git a/project/jni/application/ballfield/ballfield.cpp b/project/jni/application/ballfield/ballfield.cpp index d832e32f4..52cf382eb 100644 --- a/project/jni/application/ballfield/ballfield.cpp +++ b/project/jni/application/ballfield/ballfield.cpp @@ -346,8 +346,8 @@ int main(int argc, char* argv[]) SDL_Surface *temp_image; SDL_Surface *back, *logo, *font; SDL_Event event; - int bpp = 16, - flags = SDL_DOUBLEBUF | SDL_HWSURFACE, + int bpp = 24, + flags = SDL_DOUBLEBUF | SDL_SWSURFACE, alpha = 1; int x_offs = 0, y_offs = 0; long tick, @@ -461,6 +461,9 @@ int main(int argc, char* argv[]) tick = SDL_GetTicks(); dt = (tick - last_tick) * 0.001f; last_tick = tick; + + if( bpp == 32 ) + SDL_FillRect(screen, NULL, 0); // Clear alpha channel /* Background image */ tiled_back(back, screen, x_offs>>11, y_offs>>11); diff --git a/project/jni/application/hello-gl2/AndroidAppSettings.cfg b/project/jni/application/hello-gl2/AndroidAppSettings.cfg new file mode 100644 index 000000000..176cc8d88 --- /dev/null +++ b/project/jni/application/hello-gl2/AndroidAppSettings.cfg @@ -0,0 +1,41 @@ +# The application settings for Android libSDL port +AppSettingVersion=17 +LibSdlVersion=1.2 +AppName="SDL GL2 test" +AppFullName=net.libsdl.gl2test +ScreenOrientation=h +InhibitSuspend=n +AppDataDownloadUrl="Game data is 1 Mb|ballfield.zip" +VideoDepthBpp=24 +NeedDepthBuffer=y +NeedStencilBuffer=n +NeedGles2=y +SwVideoMode=n +SdlVideoResize=y +SdlVideoResizeKeepAspect=n +CompatibilityHacks=n +AppUsesMouse=y +AppNeedsTwoButtonMouse=y +AppNeedsArrowKeys=n +AppNeedsTextInput=y +AppUsesJoystick=n +AppHandlesJoystickSensitivity=n +AppUsesMultitouch=n +NonBlockingSwapBuffers=y +RedefinedKeys="SPACE" +AppTouchscreenKeyboardKeysAmount=0 +AppTouchscreenKeyboardKeysAmountAutoFire=0 +RedefinedKeysScreenKb="1 2 3 4 5 6 1 2 3 4" +StartupMenuButtonTimeout=3000 +HiddenMenuOptions='' +FirstStartMenuOptions='' +MultiABI=y +AppVersionCode=101 +AppVersionName="1.01" +CompiledLibraries="sdl_mixer sdl_image" +CustomBuildScript=n +AppCflags='' +AppLdflags='' +AppSubdirsBuild='' +AppCmdline='' +ReadmeText='^Readme text' diff --git a/project/jni/application/hello-gl2/AndroidData/ballfield.zip b/project/jni/application/hello-gl2/AndroidData/ballfield.zip new file mode 100644 index 000000000..3d65c19da Binary files /dev/null and b/project/jni/application/hello-gl2/AndroidData/ballfield.zip differ diff --git a/project/jni/application/hello-gl2/gl_code.cpp b/project/jni/application/hello-gl2/gl_code.cpp new file mode 100644 index 000000000..03af30942 --- /dev/null +++ b/project/jni/application/hello-gl2/gl_code.cpp @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// OpenGL ES 2.0 code + +#include +#include + +#include +#include + +#include +#include +#include + +#define LOG_TAG "libgl2jni" +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) + +static void printGLString(const char *name, GLenum s) { + const char *v = (const char *) glGetString(s); + LOGI("GL %s = %s\n", name, v); +} + +static void checkGlError(const char* op) { + for (GLint error = glGetError(); error; error + = glGetError()) { + LOGI("after %s() glError (0x%x)\n", op, error); + } +} + +static const char gVertexShader[] = + "attribute vec4 vPosition;\n" + "void main() {\n" + " gl_Position = vPosition;\n" + "}\n"; + +static const char gFragmentShader[] = + "precision mediump float;\n" + "void main() {\n" + " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n" + "}\n"; + +typedef GLuint (*tglCreateShader) (GLenum type); +tglCreateShader xglCreateShader; +typedef void (*tglDeleteShader) (GLuint shader); +tglDeleteShader xglDeleteShader; +typedef void (*tglShaderSource) (GLuint shader, GLsizei count, const char** string, const GLint* length); +tglShaderSource xglShaderSource; +typedef void (*tglCompileShader) (GLuint shader); +tglCompileShader xglCompileShader; +typedef void (*tglGetShaderiv) (GLuint shader, GLenum pname, GLint* params); +tglGetShaderiv xglGetShaderiv; +typedef void (*tglGetShaderInfoLog) (GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog); +tglGetShaderInfoLog xglGetShaderInfoLog; +typedef GLuint (*tglCreateProgram) (void); +tglCreateProgram xglCreateProgram; +typedef void (*tglDeleteProgram) (GLuint program); +tglDeleteProgram xglDeleteProgram; +typedef void (*tglAttachShader) (GLuint program, GLuint shader); +tglAttachShader xglAttachShader; +typedef void (*tglLinkProgram) (GLuint program); +tglLinkProgram xglLinkProgram; +typedef void (*tglGetProgramiv) (GLuint program, GLenum pname, GLint* params); +tglGetProgramiv xglGetProgramiv; +typedef void (*tglGetProgramInfoLog) (GLuint program, GLsizei bufsize, GLsizei* length, char* infolog); +tglGetProgramInfoLog xglGetProgramInfoLog; +typedef int (*tglGetAttribLocation) (GLuint program, const char* name); +tglGetAttribLocation xglGetAttribLocation; +typedef void (*tglUseProgram) (GLuint program); +tglUseProgram xglUseProgram; +typedef void (*tglVertexAttribPointer) (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr); +tglVertexAttribPointer xglVertexAttribPointer; +typedef void (*tglEnableVertexAttribArray) (GLuint index); +tglEnableVertexAttribArray xglEnableVertexAttribArray; +typedef void (*tglClearColor) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +tglClearColor xglClearColor; + +void loadFunctions(void) +{ + SDL_GL_LoadLibrary(NULL); + #define GL_LOAD_PROC(name) GL_LOAD_PROC1(name) + #define GL_LOAD_PROC1(name) \ + x ## name = (t ## name) SDL_GL_GetProcAddress( # name ); \ + if( x ## name == NULL ) \ + LOGE("Error loading GL function: %s", # name ); + + GL_LOAD_PROC(glCreateShader); + GL_LOAD_PROC(glDeleteShader); + GL_LOAD_PROC(glShaderSource); + GL_LOAD_PROC(glCompileShader); + GL_LOAD_PROC(glGetShaderiv); + GL_LOAD_PROC(glGetShaderInfoLog); + GL_LOAD_PROC(glCreateProgram); + GL_LOAD_PROC(glDeleteProgram); + GL_LOAD_PROC(glAttachShader); + GL_LOAD_PROC(glLinkProgram); + GL_LOAD_PROC(glGetProgramiv); + GL_LOAD_PROC(glGetProgramInfoLog); + GL_LOAD_PROC(glGetAttribLocation); + GL_LOAD_PROC(glUseProgram); + GL_LOAD_PROC(glVertexAttribPointer); + GL_LOAD_PROC(glEnableVertexAttribArray); + GL_LOAD_PROC(glClearColor); +} + +GLuint loadShader(GLenum shaderType, const char* pSource) { + GLuint shader = xglCreateShader(shaderType); + checkGlError("glCreateShader"); + if (shader) { + xglShaderSource(shader, 1, &pSource, NULL); + xglCompileShader(shader); + GLint compiled = 0; + xglGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLint infoLen = 0; + xglGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen) { + char* buf = (char*) malloc(infoLen); + if (buf) { + xglGetShaderInfoLog(shader, infoLen, NULL, buf); + LOGE("Could not compile shader %d:\n%s\n", + shaderType, buf); + free(buf); + } + xglDeleteShader(shader); + shader = 0; + } + } + } + return shader; +} + +GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { + GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); + if (!vertexShader) { + return 0; + } + + GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); + if (!pixelShader) { + return 0; + } + + GLuint program = xglCreateProgram(); + checkGlError("glCreateProgram"); + if (program) { + xglAttachShader(program, vertexShader); + checkGlError("glAttachShader"); + xglAttachShader(program, pixelShader); + checkGlError("glAttachShader"); + xglLinkProgram(program); + GLint linkStatus = GL_FALSE; + xglGetProgramiv(program, GL_LINK_STATUS, &linkStatus); + if (linkStatus != GL_TRUE) { + GLint bufLength = 0; + xglGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) { + char* buf = (char*) malloc(bufLength); + if (buf) { + xglGetProgramInfoLog(program, bufLength, NULL, buf); + LOGE("Could not link program:\n%s\n", buf); + free(buf); + } + } + xglDeleteProgram(program); + program = 0; + } + } + return program; +} + +GLuint gProgram; +GLuint gvPositionHandle; + +bool setupGraphics(int w, int h) { + printGLString("Version", GL_VERSION); + printGLString("Vendor", GL_VENDOR); + printGLString("Renderer", GL_RENDERER); + printGLString("Extensions", GL_EXTENSIONS); + loadFunctions(); + + LOGI("setupGraphics(%d, %d)", w, h); + gProgram = createProgram(gVertexShader, gFragmentShader); + if (!gProgram) { + LOGE("Could not create program."); + return false; + } + gvPositionHandle = xglGetAttribLocation(gProgram, "vPosition"); + checkGlError("glGetAttribLocation"); + LOGI("glGetAttribLocation(\"vPosition\") = %d\n", + gvPositionHandle); + + glViewport(0, 0, w, h); + checkGlError("glViewport"); + return true; +} + +const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f }; + +void renderFrame() { + static float grey; + grey += 0.01f; + if (grey > 1.0f) { + grey = 0.0f; + } + xglClearColor(grey, grey, grey, 1.0f); + checkGlError("glClearColor"); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + checkGlError("glClear"); + + xglUseProgram(gProgram); + checkGlError("glUseProgram"); + + xglVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices); + checkGlError("glVertexAttribPointer"); + xglEnableVertexAttribArray(gvPositionHandle); + checkGlError("glEnableVertexAttribArray"); + glDrawArrays(GL_TRIANGLES, 0, 3); + checkGlError("glDrawArrays"); +} + +int SDL_main(int argc, char ** argv) +{ + int SCREEN_W = 640; + int SCREEN_H = 480; + SDL_Init(SDL_INIT_VIDEO); + SDL_SetVideoMode(SCREEN_W, SCREEN_H, 24, SDL_OPENGL | SDL_DOUBLEBUF); + setupGraphics(SCREEN_W, SCREEN_H); + while( ! SDL_GetKeyState(NULL)[SDLK_ESCAPE] ) + { + SDL_Event evt; + renderFrame(); + SDL_GL_SwapBuffers(); + while( SDL_PollEvent(&evt) ) + { + } + } +} diff --git a/project/jni/application/hello-gl2/icon.png b/project/jni/application/hello-gl2/icon.png new file mode 100644 index 000000000..b3614e149 Binary files /dev/null and b/project/jni/application/hello-gl2/icon.png differ diff --git a/project/jni/application/src b/project/jni/application/src index c5a9d291d..98ce0a94c 120000 --- a/project/jni/application/src +++ b/project/jni/application/src @@ -1 +1 @@ -commandergenius \ No newline at end of file +hello-gl2 \ No newline at end of file diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo-1.2.c b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo-1.2.c index 9600b8d41..3144b060a 100644 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo-1.2.c +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo-1.2.c @@ -201,9 +201,12 @@ static SDL_VideoDevice *ANDROID_CreateDevice(int devindex) device->ShowWMCursor = ANDROID_ShowWMCursor; device->ToggleFullScreen = ANDROID_ToggleFullScreen; - glLibraryHandle = dlopen("libGLESv1_CM.so", RTLD_NOW); + glLibraryHandle = dlopen("libGLESv1_CM.so", RTLD_NOW | RTLD_GLOBAL); if(SDL_ANDROID_UseGles2) - gl2LibraryHandle = dlopen("libGLESv2.so", RTLD_NOW); + { + gl2LibraryHandle = dlopen("libGLESv2.so", RTLD_NOW | RTLD_GLOBAL); + __android_log_print(ANDROID_LOG_INFO, "libSDL", "Loading libGLESv2.so: %p", gl2LibraryHandle); + } return device; } @@ -1001,7 +1004,7 @@ static void* ANDROID_GL_GetProcAddress(_THIS, const char *proc) void * func = dlsym(glLibraryHandle, proc); if(!func && gl2LibraryHandle) func = dlsym(gl2LibraryHandle, proc); - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROID_GL_GetProcAddress(\"%s\"): %p", proc, func); + __android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROID_GL_GetProcAddress(\"%s\"): %p", proc, func); return func; }; diff --git a/project/jni/sdl-1.3/src/video/SDL_renderer_gles.c b/project/jni/sdl-1.3/src/video/SDL_renderer_gles.c index e176eee37..62d88ecf9 100644 --- a/project/jni/sdl-1.3/src/video/SDL_renderer_gles.c +++ b/project/jni/sdl-1.3/src/video/SDL_renderer_gles.c @@ -126,7 +126,7 @@ SDL_RenderDriver GL_ES_RenderDriver = { SDL_TEXTUREMODULATE_ALPHA), (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD), - (SDL_SCALEMODE_NONE | SDL_SCALEMODE_FAST | SDL_SCALEMODE_SLOW), 6, + (SDL_SCALEMODE_NONE | SDL_SCALEMODE_FAST | SDL_SCALEMODE_SLOW), 5, { /* OpenGL ES 1.x supported formats list */ SDL_PIXELFORMAT_RGBA4444, @@ -424,6 +424,7 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) break; case SDL_PIXELFORMAT_BGR888: case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_RGBA8888: internalFormat = GL_RGBA; format = GL_RGBA; type = GL_UNSIGNED_BYTE;