Added GLES2 sprite example
This commit is contained in:
295
project/jni/application/test-gles2/AndroidAppSettings.cfg
Normal file
295
project/jni/application/test-gles2/AndroidAppSettings.cfg
Normal file
@@ -0,0 +1,295 @@
|
||||
# The application settings for Android libSDL port
|
||||
|
||||
# Specify application name (e.x. My Application)
|
||||
AppName="GLES2 SDL test"
|
||||
|
||||
# Specify reversed site name of application (e.x. com.mysite.myapp)
|
||||
AppFullName=gles2.sdl.test
|
||||
|
||||
# Application version code (integer)
|
||||
AppVersionCode=1
|
||||
|
||||
# Application user-visible version name (string)
|
||||
AppVersionName="1"
|
||||
|
||||
# Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...'
|
||||
# If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu
|
||||
# If the URL in in the form ':dir/file.dat:http://URL/' it will be downloaded as binary BLOB to the application dir and not unzipped
|
||||
# If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir -
|
||||
# these files are put inside .apk package by build system
|
||||
# You can specify Google Play expansion files in the form 'obb:main.12345' or 'obb:patch.12345' where 12345 is the app version, first associated with the file
|
||||
AppDataDownloadUrl="!!Data|data.zip"
|
||||
|
||||
# Reset SDL config when updating application to the new version (y) / (n)
|
||||
ResetSdlConfigForThisVersion=n
|
||||
|
||||
# Delete application data files when upgrading (specify file/dir paths separated by spaces)
|
||||
DeleteFilesOnUpgrade="%"
|
||||
|
||||
# Here you may type readme text, which will be shown during startup. Format is:
|
||||
# Text in English, use \\\\n to separate lines (that's four backslashes)^de:Text in Deutsch^ru:Text in Russian^button:Button that will open some URL:http://url-to-open/
|
||||
ReadmeText='^text'
|
||||
|
||||
# libSDL version to use (1.2/1.3/2.0)
|
||||
LibSdlVersion=1.2
|
||||
|
||||
# Specify screen orientation: (v)ertical/(p)ortrait or (h)orizontal/(l)andscape
|
||||
ScreenOrientation=h
|
||||
|
||||
# Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only
|
||||
# with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32)
|
||||
VideoDepthBpp=24
|
||||
|
||||
# Enable OpenGL depth buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedDepthBuffer=n
|
||||
|
||||
# Enable OpenGL stencil buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedStencilBuffer=n
|
||||
|
||||
# Use GLES 2.x context
|
||||
# you need this option only if you're developing 3-d app (y) or (n)
|
||||
NeedGles2=y
|
||||
|
||||
# Use GLES 3.x context
|
||||
# you need this option only if you're developing 3-d app (y) or (n)
|
||||
NeedGles3=n
|
||||
|
||||
# Use glshim library for provide OpenGL 1.x functionality to OpenGL ES accelerated cards (y) or (n)
|
||||
UseGlshim=n
|
||||
|
||||
# Application uses software video buffer - you're calling SDL_SetVideoMode() without SDL_HWSURFACE and without SDL_OPENGL,
|
||||
# this will allow small speed optimization. Enable this even when you're using SDL_HWSURFACE. (y) or (n)
|
||||
SwVideoMode=n
|
||||
|
||||
# Application video output will be resized to fit into native device screen (y)/(n)
|
||||
SdlVideoResize=n
|
||||
|
||||
# Application resizing will keep 4:3 aspect ratio, with black bars at sides (y)/(n)
|
||||
SdlVideoResizeKeepAspect=n
|
||||
|
||||
# Do not allow device to sleep when the application is in foreground, set this for video players or apps which use accelerometer
|
||||
InhibitSuspend=y
|
||||
|
||||
# Create Android service, so the app is less likely to be killed while in background
|
||||
CreateService=n
|
||||
|
||||
# Application does not call SDL_Flip() or SDL_UpdateRects() appropriately, or draws from non-main thread -
|
||||
# enabling the compatibility mode will force screen update every 100 milliseconds, which is laggy and inefficient (y) or (n)
|
||||
CompatibilityHacksForceScreenUpdate=n
|
||||
|
||||
# Application does not call SDL_Flip() or SDL_UpdateRects() after mouse click (ScummVM and all Amiga emulators do that) -
|
||||
# force screen update by moving mouse cursor a little after each click (y) or (n)
|
||||
CompatibilityHacksForceScreenUpdateMouseClick=n
|
||||
|
||||
# Application initializes SDL audio/video inside static constructors (which is bad, you won't be able to run ndk-gdb) (y)/(n)
|
||||
CompatibilityHacksStaticInit=n
|
||||
|
||||
# On-screen Android soft text input emulates hardware keyboard, this will only work with Hackers Keyboard app (y)/(n)
|
||||
CompatibilityHacksTextInputEmulatesHwKeyboard=n
|
||||
|
||||
# Built-in text input keyboards with custom layouts for emulators, requires CompatibilityHacksTextInputEmulatesHwKeyboard=y
|
||||
# 0 or empty - standard Android keyboard
|
||||
# 1 - Simple QWERTY keyboard, no function keys, no arrow keys
|
||||
# 2 - Commodore 64 keyboard
|
||||
# 3 - Amiga keyboard
|
||||
# 4 - Atari800 keyboard
|
||||
TextInputKeyboard=0
|
||||
|
||||
# Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n)
|
||||
CompatibilityHacksPreventAudioChopping=n
|
||||
|
||||
# Hack for broken apps: application ignores audio buffer size returned by SDL (y)/(n)
|
||||
CompatibilityHacksAppIgnoresAudioBufferSize=n
|
||||
|
||||
# Hack for VCMI: preload additional shared libraries before aplication start
|
||||
CompatibilityHacksAdditionalPreloadedSharedLibraries=""
|
||||
|
||||
# Hack for Free Heroes 2, which redraws the screen inside SDL_PumpEvents(): slow and compatible SDL event queue -
|
||||
# do not use it with accelerometer/gyroscope, or your app may freeze at random (y)/(n)
|
||||
CompatibilityHacksSlowCompatibleEventQueue=n
|
||||
|
||||
# Save and restore OpenGL state when drawing on-screen keyboard for apps that use SDL_OPENGL
|
||||
CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=n
|
||||
|
||||
# Application uses SDL_UpdateRects() properly, and does not draw in any region outside those rects.
|
||||
# This improves drawing speed, but I know only one application that does that, and it's written by me (y)/(n)
|
||||
CompatibilityHacksProperUsageOfSDL_UpdateRects=
|
||||
|
||||
# Application uses mouse (y) or (n), this will show mouse emulation dialog to the user
|
||||
AppUsesMouse=y
|
||||
|
||||
# Application needs two-button mouse, will also enable advanced point-and-click features (y) or (n)
|
||||
AppNeedsTwoButtonMouse=n
|
||||
|
||||
# Right mouse button can do long-press/drag&drop action, necessary for some games (y) or (n)
|
||||
# If you disable it, swiping with two fingers will send mouse wheel events
|
||||
RightMouseButtonLongPress=
|
||||
|
||||
# Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n)
|
||||
ShowMouseCursor=n
|
||||
|
||||
# Screen follows mouse cursor, when it's covered by soft keyboard, this works only in software video mode (y) or (n)
|
||||
ScreenFollowsMouse=
|
||||
|
||||
# Generate more touch events, by default SDL generates one event per one video frame, this is useful for drawing apps (y) or (n)
|
||||
GenerateSubframeTouchEvents=
|
||||
|
||||
# Force relative (laptop) mouse movement mode, useful when both on-screen keyboard and mouse are needed (y) or (n)
|
||||
ForceRelativeMouseMode=n
|
||||
|
||||
# Show on-screen dpad/joystick, that will act as arrow keys (y) or (n)
|
||||
AppNeedsArrowKeys=n
|
||||
|
||||
# On-screen dpad/joystick will appear under finger when it touches the screen (y) or (n)
|
||||
# Joystick always follows finger, so moving mouse requires touching the screen with other finger
|
||||
FloatingScreenJoystick=
|
||||
|
||||
# Application needs text input (y) or (n), enables button for text input on screen
|
||||
AppNeedsTextInput=y
|
||||
|
||||
# Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1
|
||||
# This will disable AppNeedsArrowKeys option
|
||||
AppUsesJoystick=n
|
||||
|
||||
# Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n)
|
||||
AppUsesSecondJoystick=n
|
||||
|
||||
# Application uses third on-screen joystick, as SDL joystick 0 axes 20-21 (y)/(n)
|
||||
AppUsesThirdJoystick=
|
||||
|
||||
# Application uses accelerometer (y) or (n), the accelerometer will be used as joystick 1 axes 0-1 and 5-7
|
||||
AppUsesAccelerometer=n
|
||||
|
||||
# Application uses gyroscope (y) or (n), the gyroscope will be used as joystick 1 axes 2-4
|
||||
AppUsesGyroscope=n
|
||||
|
||||
# Application uses orientation sensor (y) or (n), reported as joystick 1 axes 8-10
|
||||
AppUsesOrientationSensor=
|
||||
|
||||
# Use gyroscope to move mouse cursor (y) or (n), it eats battery, and can be disabled in settings, do not use with AppUsesGyroscope setting
|
||||
MoveMouseWithGyroscope=
|
||||
|
||||
# Application uses multitouch (y) or (n), multitouch events are passed as SDL_JOYBALLMOTION events for the joystick 0
|
||||
AppUsesMultitouch=n
|
||||
|
||||
# Application records audio (it will use any available source, such a s microphone)
|
||||
# API is defined in file SDL_android.h: int SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec); void SDL_ANDROID_CloseAudioRecording(void);
|
||||
# This option will add additional permission to Android manifest (y)/(n)
|
||||
AppRecordsAudio=n
|
||||
|
||||
# Application needs to access SD card. Always disable it, unless you want to access user photos and downloads. (y) / (n)
|
||||
AccessSdCard=
|
||||
|
||||
# Application needs Internet access. If you disable it, you'll have to bundle all your data files inside .apk (y) / (n)
|
||||
AccessInternet=
|
||||
|
||||
# Immersive mode - Android will hide on-screen Home/Back keys. Looks bad if you invoke Android keyboard. (y) / (n)
|
||||
ImmersiveMode=
|
||||
|
||||
# Application implements Android-specific routines to put to background, and will not draw anything to screen
|
||||
# between SDL_ACTIVEEVENT lost / gained notifications - you should check for them
|
||||
# rigth after SDL_Flip(), if (n) then SDL_Flip() will block till app in background (y) or (n)
|
||||
# This option is reported to be buggy, sometimes failing to restore video state
|
||||
NonBlockingSwapBuffers=n
|
||||
|
||||
# Redefine common hardware keys to SDL keysyms
|
||||
# BACK hardware key is available on all devices, MENU is available on pre-ICS devices, other keys may be absent
|
||||
# SEARCH and CALL by default return same keycode as DPAD_CENTER - one of those keys is available on most devices
|
||||
# Use word NO_REMAP if you want to preserve native functionality for certain key (volume keys are 3-rd and 4-th)
|
||||
# Keys: TOUCHSCREEN (works only when AppUsesMouse=n), DPAD_CENTER/SEARCH, VOLUMEUP, VOLUMEDOWN, MENU, BACK, CAMERA
|
||||
RedefinedKeys="RETURN"
|
||||
|
||||
# Number of virtual keyboard keys (currently 6 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmount=0
|
||||
|
||||
# Redefine on-screen keyboard keys to SDL keysyms - 6 keyboard keys + 4 multitouch gestures (zoom in/out and rotate left/right)
|
||||
RedefinedKeysScreenKb="RETURN"
|
||||
|
||||
# Names for on-screen keyboard keys, such as Fire, Jump, Run etc, separated by spaces, they are used in SDL config menu
|
||||
RedefinedKeysScreenKbNames="RETURN"
|
||||
|
||||
# On-screen keys theme
|
||||
# 0 = Ultimate Droid by Sean Stieber (green, with cross joystick)
|
||||
# 1 = Simple Theme by Beholder (white, with cross joystick)
|
||||
# 2 = Sun by Sirea (yellow, with round joystick)
|
||||
# 3 = Keen by Gerstrong (multicolor, with round joystick)
|
||||
# 4 = Retro by Santiago Radeff (red/white, with cross joystick)
|
||||
# 5 = GameBoy from RetroArch
|
||||
# 6 = PlayStation from RetroArch
|
||||
# 7 = SuperNintendo from RetroArch
|
||||
# 8 = DualShock from RetroArch
|
||||
# 9 = Nintendo64 from RetroArch
|
||||
TouchscreenKeysTheme=2
|
||||
|
||||
# Redefine gamepad keys to SDL keysyms, button order is:
|
||||
# A B X Y L1 R1 L2 R2 LThumb RThumb
|
||||
RedefinedKeysGamepad="RETURN"
|
||||
|
||||
# How long to show startup menu button, in msec, 0 to disable startup menu
|
||||
StartupMenuButtonTimeout=0
|
||||
|
||||
# Menu items to hide from startup menu, available menu items:
|
||||
# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.CommandlineConfig SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout SettingsMenuKeyboard.ScreenKeyboardAdvanced
|
||||
HiddenMenuOptions=''
|
||||
|
||||
# Menu items to show at startup - this is Java code snippet, leave empty for default
|
||||
# new SettingsMenuMisc.ShowReadme(), (AppUsesMouse \&\& \! ForceRelativeMouseMode \? new SettingsMenuMouse.DisplaySizeConfig(true) : new SettingsMenu.DummyMenu()), new SettingsMenuMisc.OptionalDownloadConfig(true), new SettingsMenuMisc.GyroscopeCalibration()
|
||||
# Available menu items:
|
||||
# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.CommandlineConfig SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout SettingsMenuKeyboard.ScreenKeyboardAdvanced
|
||||
FirstStartMenuOptions=''
|
||||
|
||||
# Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower
|
||||
AppMinimumRAM=0
|
||||
|
||||
# GCC version, or 'clang' for CLANG
|
||||
NDK_TOOLCHAIN_VERSION=
|
||||
|
||||
# Specify architectures to compile, 'all' or 'y' to compile for all architectures.
|
||||
# Available architectures: armeabi armeabi-v7a x86 mips arm64-v8a
|
||||
MultiABI='armeabi-v7a'
|
||||
|
||||
# Optional shared libraries to compile - removing some of them will save space
|
||||
# MP3 support by libMAD is encumbered by patents and libMAD is GPL-ed
|
||||
# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu avcodec avdevice avfilter avformat avresample avutil swscale swresample bzip2
|
||||
CompiledLibraries="sdl_image"
|
||||
|
||||
# Application uses custom build script AndroidBuild.sh instead of Android.mk (y) or (n)
|
||||
CustomBuildScript=n
|
||||
|
||||
# Aditional CFLAGS for application
|
||||
AppCflags='-O2'
|
||||
|
||||
# Aditional C++-specific compiler flags for application, added after AppCflags
|
||||
AppCppflags=''
|
||||
|
||||
# Additional LDFLAGS for application
|
||||
AppLdflags=''
|
||||
|
||||
# If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable
|
||||
AppOverlapsSystemHeaders=
|
||||
|
||||
# Build only following subdirs (empty will build all dirs, ignored with custom script)
|
||||
AppSubdirsBuild=''
|
||||
|
||||
# Exclude these files from build
|
||||
AppBuildExclude=''
|
||||
|
||||
# Application command line parameters, including app name as 0-th param
|
||||
AppCmdline=''
|
||||
|
||||
# Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens
|
||||
# Minimum screen size that application supports: (s)mall / (m)edium / (l)arge
|
||||
MinimumScreenSize=s
|
||||
|
||||
# Your AdMob Publisher ID, (n) if you don't want advertisements
|
||||
AdmobPublisherId=n
|
||||
|
||||
# Your AdMob test device ID, to receive a test ad
|
||||
AdmobTestDeviceId=
|
||||
|
||||
# Your AdMob banner size (BANNER/FULL_BANNER/LEADERBOARD/MEDIUM_RECTANGLE/SMART_BANNER/WIDE_SKYSCRAPER/FULL_WIDTH:Height/Width:AUTO_HEIGHT/Width:Height)
|
||||
AdmobBannerSize=
|
||||
|
||||
# Google Play Game Services application ID, required for cloud saves to work
|
||||
GooglePlayGameServicesId=
|
||||
|
||||
BIN
project/jni/application/test-gles2/AndroidData/data.zip
Normal file
BIN
project/jni/application/test-gles2/AndroidData/data.zip
Normal file
Binary file not shown.
4
project/jni/application/test-gles2/Makefile
Normal file
4
project/jni/application/test-gles2/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
sdl_hello: *.cpp
|
||||
g++ -g3 -O0 -o $@ $? `sdl-config --cflags` `sdl-config --libs` -lGLESv2 -lSDL_image
|
||||
unzip -o AndroidData/*.zip
|
||||
BIN
project/jni/application/test-gles2/icon.png
Normal file
BIN
project/jni/application/test-gles2/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
418
project/jni/application/test-gles2/main.cpp
Normal file
418
project/jni/application/test-gles2/main.cpp
Normal file
@@ -0,0 +1,418 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_image.h>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#define printf(...) __android_log_print(ANDROID_LOG_INFO, "Test-GLES3", __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
int screenWidth = 0;
|
||||
int screenHeight = 0;
|
||||
|
||||
GLuint drawTextureProgram = 0;
|
||||
GLint drawTextureSamplerLocation = 0;
|
||||
|
||||
static void initSDL()
|
||||
{
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
|
||||
SDL_EnableUNICODE(1);
|
||||
|
||||
screenWidth = SDL_GetVideoInfo()->current_w;
|
||||
screenHeight = SDL_GetVideoInfo()->current_h;
|
||||
|
||||
if ( ! SDL_SetVideoMode(screenWidth, screenHeight, 24, SDL_OPENGL|SDL_DOUBLEBUF|SDL_FULLSCREEN) )
|
||||
{
|
||||
printf("Couldn't set GL video mode: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint loadShader ( GLenum type, const char *shaderSrc )
|
||||
{
|
||||
GLuint shader;
|
||||
GLint compiled;
|
||||
|
||||
// Create the shader object
|
||||
shader = glCreateShader ( type );
|
||||
|
||||
if ( shader == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Load the shader source
|
||||
glShaderSource ( shader, 1, &shaderSrc, NULL );
|
||||
|
||||
// Compile the shader
|
||||
glCompileShader ( shader );
|
||||
|
||||
// Check the compile status
|
||||
glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled );
|
||||
|
||||
if ( !compiled )
|
||||
{
|
||||
GLint infoLen = 0;
|
||||
|
||||
glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen );
|
||||
|
||||
if ( infoLen > 1 )
|
||||
{
|
||||
char *infoLog = (char *) malloc ( sizeof ( char ) * infoLen );
|
||||
|
||||
glGetShaderInfoLog ( shader, infoLen, NULL, infoLog );
|
||||
printf ( "===========> Error compiling shader:\n");
|
||||
printf ( "===========> %s\n", infoLog );
|
||||
printf ( "===========> %s\n", shaderSrc );
|
||||
|
||||
free ( infoLog );
|
||||
}
|
||||
|
||||
glDeleteShader ( shader );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
|
||||
}
|
||||
|
||||
static GLuint loadProgram ( const char *vertShaderSrc, const char *fragShaderSrc )
|
||||
{
|
||||
GLuint vertexShader;
|
||||
GLuint fragmentShader;
|
||||
GLuint programObject;
|
||||
GLint linked;
|
||||
|
||||
// Load the vertex/fragment shaders
|
||||
vertexShader = loadShader ( GL_VERTEX_SHADER, vertShaderSrc );
|
||||
|
||||
if ( vertexShader == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
fragmentShader = loadShader ( GL_FRAGMENT_SHADER, fragShaderSrc );
|
||||
|
||||
if ( fragmentShader == 0 )
|
||||
{
|
||||
glDeleteShader ( vertexShader );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create the program object
|
||||
programObject = glCreateProgram ( );
|
||||
|
||||
if ( programObject == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
glAttachShader ( programObject, vertexShader );
|
||||
glAttachShader ( programObject, fragmentShader );
|
||||
|
||||
// Link the program
|
||||
glLinkProgram ( programObject );
|
||||
|
||||
// Check the link status
|
||||
glGetProgramiv ( programObject, GL_LINK_STATUS, &linked );
|
||||
|
||||
if ( !linked )
|
||||
{
|
||||
GLint infoLen = 0;
|
||||
|
||||
glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen );
|
||||
|
||||
if ( infoLen > 1 )
|
||||
{
|
||||
char *infoLog = (char *) malloc ( sizeof ( char ) * infoLen );
|
||||
|
||||
glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog );
|
||||
printf ( "===========> Error linking program:\n" );
|
||||
printf ( "===========> %s\n", infoLog );
|
||||
|
||||
free ( infoLog );
|
||||
}
|
||||
|
||||
glDeleteProgram ( programObject );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Free up no longer needed shader resources
|
||||
glDeleteShader ( vertexShader );
|
||||
glDeleteShader ( fragmentShader );
|
||||
|
||||
return programObject;
|
||||
}
|
||||
|
||||
static void initShaders()
|
||||
{
|
||||
char *vertexShaderStr = NULL;
|
||||
asprintf( &vertexShaderStr,
|
||||
"#version 100 \n"
|
||||
"const highp float screenWidthDiv = 2.0 / %d.0; \n"
|
||||
"const highp float screenHeightDiv = 2.0 / %d.0; \n"
|
||||
"attribute highp vec2 a_position; \n"
|
||||
"attribute highp vec2 a_texCoord; \n"
|
||||
"attribute lowp vec4 a_color; \n"
|
||||
"varying highp vec2 v_texCoord; \n"
|
||||
"varying lowp vec4 v_color; \n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
" gl_Position = vec4( \n"
|
||||
" a_position.x * screenWidthDiv - 1.0, \n"
|
||||
" 1.0 - a_position.y * screenHeightDiv, \n"
|
||||
" 0, 1); \n"
|
||||
" v_texCoord = a_texCoord; \n"
|
||||
" v_color = a_color; \n"
|
||||
"} \n"
|
||||
, screenWidth, screenHeight );
|
||||
|
||||
const char *fragmentShaderStr =
|
||||
"#version 100 \n"
|
||||
"varying highp vec2 v_texCoord; \n"
|
||||
"varying lowp vec4 v_color; \n"
|
||||
"uniform sampler2D s_texture; \n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
" gl_FragColor = texture2D( s_texture, v_texCoord ) * v_color; \n"
|
||||
"} \n";
|
||||
|
||||
//printf("initShaders(): vertex shader:\n%s\n", vertexShaderStr);
|
||||
//printf("initShaders(): fragment shader:\n%s\n", fragmentShaderStr);
|
||||
|
||||
// Load the shaders and get a linked program object
|
||||
drawTextureProgram = loadProgram ( vertexShaderStr, fragmentShaderStr );
|
||||
if (drawTextureProgram == 0)
|
||||
{
|
||||
printf("Could not init shaders\n");
|
||||
SDL_Quit();
|
||||
exit(2);
|
||||
}
|
||||
|
||||
free(vertexShaderStr);
|
||||
|
||||
// Get the sampler location
|
||||
drawTextureSamplerLocation = glGetUniformLocation ( drawTextureProgram, "s_texture" );
|
||||
}
|
||||
|
||||
static void initGL()
|
||||
{
|
||||
glViewport(0, 0, screenWidth, screenHeight);
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glActiveTexture ( GL_TEXTURE0 );
|
||||
|
||||
initShaders();
|
||||
}
|
||||
|
||||
static void clearScreen()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Always clear your scene before rendering, unless you're sure that you'll fill whole screen with textures/models etc
|
||||
}
|
||||
|
||||
struct Sprite {
|
||||
|
||||
|
||||
Sprite(const char * path, GLint wrap = GL_CLAMP_TO_EDGE)
|
||||
{
|
||||
w = h = texture = 0;
|
||||
imagePath = path;
|
||||
textureWrap = wrap;
|
||||
loadTexture();
|
||||
}
|
||||
|
||||
bool loadTexture()
|
||||
{
|
||||
SDL_Surface *pic;
|
||||
|
||||
pic = IMG_Load(imagePath.c_str());
|
||||
|
||||
if (!pic)
|
||||
{
|
||||
printf("Error: image %s cannot be loaded\n", imagePath.c_str());
|
||||
return false;
|
||||
}
|
||||
if (pic->format->BitsPerPixel != 32 && pic->format->BitsPerPixel != 24)
|
||||
{
|
||||
printf("Error: image %s is %dbpp - it should be either 24bpp or 32bpp, images with palette are not supported\n", imagePath.c_str(), pic->format->BitsPerPixel);
|
||||
SDL_FreeSurface(pic);
|
||||
return false;
|
||||
}
|
||||
|
||||
GLenum glFormat = (pic->format->BitsPerPixel == 32 ? GL_RGBA : GL_RGB);
|
||||
w = pic->w;
|
||||
h = pic->h;
|
||||
// GLES3 always supports non-power-of-two textures, no need to recalculate texture dimensions
|
||||
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, glFormat, w, h, 0, glFormat, GL_UNSIGNED_BYTE, pic->pixels);
|
||||
SDL_FreeSurface(pic);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, textureWrap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, textureWrap);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void draw(GLfloat x, GLfloat y, GLfloat width, GLfloat height,
|
||||
GLfloat tex_x1 = 0.0f, GLfloat tex_y1 = 0.0f, GLfloat tex_x2 = 1.0f, GLfloat tex_y2 = 1.0f,
|
||||
GLfloat r = 1.0f, GLfloat g = 1.0f, GLfloat b = 1.0f, GLfloat a = 1.0f)
|
||||
{
|
||||
if (texture == 0)
|
||||
return;
|
||||
|
||||
glUseProgram( drawTextureProgram );
|
||||
|
||||
GLfloat coords[] = {
|
||||
x, y, // Position 0
|
||||
tex_x1, tex_y1, // TexCoord 0
|
||||
x, y + height, // Position 1
|
||||
tex_x1, tex_y2, // TexCoord 1
|
||||
x + width, y + height, // Position 2
|
||||
tex_x2, tex_y2, // TexCoord 2
|
||||
x + width, y, // Position 3
|
||||
tex_x2, tex_y1 // TexCoord 3
|
||||
};
|
||||
GLfloat color[] = { r, g, b, a, r, g, b, a, r, g, b, a, r, g, b, a };
|
||||
|
||||
// Load the vertex position
|
||||
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof ( GLfloat ), coords );
|
||||
// Load the texture coordinate
|
||||
glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof ( GLfloat ), &coords[2] );
|
||||
glVertexAttribPointer( 2, 4, GL_FLOAT, GL_FALSE, 0, color );
|
||||
|
||||
glEnableVertexAttribArray( 0 );
|
||||
glEnableVertexAttribArray( 1 );
|
||||
glEnableVertexAttribArray( 2 );
|
||||
|
||||
glActiveTexture( GL_TEXTURE0 );
|
||||
glBindTexture( GL_TEXTURE_2D, texture );
|
||||
|
||||
glUniform1i ( drawTextureSamplerLocation, 0 );
|
||||
|
||||
glDrawArrays ( GL_TRIANGLE_FAN, 0, 4 );
|
||||
}
|
||||
|
||||
void draw(GLfloat x, GLfloat y)
|
||||
{
|
||||
draw(x, y, w, h);
|
||||
}
|
||||
|
||||
void drawColor(GLfloat x, GLfloat y, GLfloat width, GLfloat height, GLfloat r, GLfloat g, GLfloat b, GLfloat a)
|
||||
{
|
||||
draw(x, y, width, height, 0.0f, 0.0f, 1.0f, 1.0f, r, g, b, a);
|
||||
}
|
||||
|
||||
void drawColor(GLfloat x, GLfloat y, GLfloat r, GLfloat g, GLfloat b, GLfloat a)
|
||||
{
|
||||
drawColor(x, y, w, h, r, g, b, a);
|
||||
}
|
||||
|
||||
GLuint texture;
|
||||
int w, h;
|
||||
std::string imagePath;
|
||||
GLint textureWrap;
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
initSDL();
|
||||
initGL();
|
||||
|
||||
std::vector<Sprite> sprites;
|
||||
sprites.push_back(Sprite("test.png"));
|
||||
sprites.push_back(Sprite("element0.png"));
|
||||
sprites.push_back(Sprite("element1.png"));
|
||||
sprites.push_back(Sprite("element2.png"));
|
||||
sprites.push_back(Sprite("element3.png"));
|
||||
//sprites.push_back(Sprite("stars.jpg", GL_REPEAT)); // Repeating tiles
|
||||
sprites.push_back(Sprite("stars.jpg", GL_MIRRORED_REPEAT)); // Looks nice
|
||||
|
||||
float coords[][2] = { {0, 0},
|
||||
{200, 0},
|
||||
{300, 200},
|
||||
{400, 300} };
|
||||
|
||||
float pulse = 1.0f, pulseChange = 0.01f;
|
||||
int anim = 1;
|
||||
|
||||
while ( ! SDL_GetKeyState(NULL)[SDLK_ESCAPE] ) // Exit by pressing Back button
|
||||
{
|
||||
// clearScreen(); // Do not clear screen, we will fill the screens with tiled background image instead
|
||||
sprites[5].draw(0, 0, screenWidth, screenHeight,
|
||||
coords[0][0] / sprites[5].w * 3,
|
||||
coords[0][0] / sprites[5].h * 2,
|
||||
coords[0][0] / sprites[5].w * 3 + (float) screenWidth / sprites[5].w,
|
||||
coords[0][0] / sprites[5].h * 2 + (float) screenHeight / sprites[5].h);
|
||||
|
||||
sprites[1].drawColor(coords[0][0], coords[0][1], pulse, pulse, 1.0f - pulse, 1.0f);
|
||||
sprites[2].draw(coords[1][0], coords[1][1], sprites[2].w * pulse * 4, sprites[2].h * pulse * 4);
|
||||
sprites[3].draw(coords[2][0], coords[2][1], sprites[3].w * pulse * 4, sprites[3].h * 2);
|
||||
sprites[4].draw(coords[3][0], coords[3][1], sprites[4].w, sprites[4].h * pulse * 2);
|
||||
|
||||
sprites[1].draw(screenWidth / 2.0f - sprites[1].w / 2.0f, screenHeight / 2.0f - sprites[1].h / 2.0f);
|
||||
sprites[1].draw(0 - sprites[1].w / 2.0f, 0 - sprites[1].h / 2.0f);
|
||||
sprites[1].draw(screenWidth - sprites[1].w / 2.0f, screenHeight - sprites[1].h / 2.0f);
|
||||
sprites[1].draw(0 - sprites[1].w / 2.0f, screenHeight - sprites[1].h / 2.0f);
|
||||
sprites[1].draw(screenWidth - sprites[1].w / 2.0f, 0 - sprites[1].h / 2.0f);
|
||||
|
||||
int mouseX = 0, mouseY = 0, buttons = 0;
|
||||
buttons = SDL_GetMouseState(&mouseX, &mouseY);
|
||||
sprites[0].drawColor(mouseX - sprites[0].w/2, mouseY - sprites[0].h/2, 1.0f, 1.0f, 1.0f, pulse);
|
||||
|
||||
SDL_GL_SwapBuffers();
|
||||
SDL_Event event;
|
||||
while( SDL_PollEvent(&event) )
|
||||
{
|
||||
if(event.type == SDL_VIDEORESIZE)
|
||||
{
|
||||
// GL context was destroyed - reload all textures
|
||||
initGL();
|
||||
for(int i = 0; i < sprites.size(); i++)
|
||||
sprites[i].loadTexture();
|
||||
}
|
||||
|
||||
if(event.type == SDL_KEYUP || event.type == SDL_KEYDOWN)
|
||||
{
|
||||
printf("SDL key event: evt %s state %s key %4d %12s scancode %4d mod %2d unicode %d", event.type == SDL_KEYUP ? "UP " : "DOWN" , event.key.state == SDL_PRESSED ? "PRESSED " : "RELEASED", (int)event.key.keysym.sym, SDL_GetKeyName(event.key.keysym.sym), (int)event.key.keysym.scancode, (int)event.key.keysym.mod, (int)event.key.keysym.unicode);
|
||||
if(event.key.keysym.sym == SDLK_ESCAPE)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Some kinda animation
|
||||
|
||||
pulse += pulseChange;
|
||||
if(pulse >= 1.0f)
|
||||
pulseChange = -0.01f;
|
||||
if(pulse <= 0)
|
||||
pulseChange = 0.01f;
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
coords[i][0] += anim;
|
||||
coords[i][1] += anim;
|
||||
}
|
||||
if( coords[0][0] < 0 )
|
||||
anim = 1;
|
||||
if( coords[3][1] > screenHeight )
|
||||
anim = -1;
|
||||
}
|
||||
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user