Updated OpenGL test app

This commit is contained in:
pelya
2012-11-11 22:59:24 +02:00
parent 9e26993b2b
commit 0741c52be5
7 changed files with 256 additions and 159 deletions

View File

@@ -1,3 +0,0 @@
sdl_hello: *.cpp
g++ -o $@ $? `sdl-config --cflags` `sdl-config --libs` -lGL

View File

@@ -1,151 +0,0 @@
#include <SDL.h>
#include <SDL_image.h>
#include <GLES/gl.h>
GLuint texture;
// I've tweaked coordinates a bit to my taste
GLfloat textureCoordinates[] = { 0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f };
GLfloat vertices[] = {
100, 100,
100, 300,
300, 300,
300, 100 };
int loadImage() {
SDL_Surface *pic;
SDL_Surface *tmp;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
pic = IMG_Load("test.png");
// check power of 2
if (!pic || !pic->w || !pic->h || (pic->w & 1) || (pic->h & 1)) {
return -1;
}
tmp = SDL_CreateRGBSurface(0, pic->w, pic->h, 16, 0xF800, 0x7E0, 0x1F, 0); // Correct bits of RGB565 color format
SDL_BlitSurface(pic, NULL, tmp, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pic->w, pic->h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, tmp->pixels);
SDL_FreeSurface(pic);
SDL_FreeSurface(tmp);
return 0;
}
int width = 640;
int height = 480;
static void
initGL()
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0.0f, width, 0.0f, height, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
static void
draw()
{
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
// You have to this each frame, because SDL messes up with your GL context when drawing on-screen keyboard, however is taves/restores your matrices
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); // Just to be sure
glEnable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBindTexture(GL_TEXTURE_2D, texture);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, textureCoordinates);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); // You may just replace all your GL_QUADS with GL_TRIANGLE_FAN and it will draw absolutely identically with same coordinates, if you have just 4 coords.
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
int
main(int argc, char *argv[])
{
SDL_Surface *screen;
int done;
Uint8 *keys;
SDL_Init(SDL_INIT_VIDEO);
// Set native device screen resolution, if you want 640x480 select SdlVideoResize=y in AndroidAppSettings.cfg
width = SDL_ListModes(NULL, 0)[0]->w;
height = SDL_ListModes(NULL, 0)[0]->h;
screen = SDL_SetVideoMode(width, height, 16, SDL_OPENGL|SDL_DOUBLEBUF);
if ( ! screen ) {
fprintf(stderr, "Couldn't set GL video mode: %s\n", SDL_GetError());
SDL_Quit();
exit(2);
}
SDL_WM_SetCaption("test", "test");
initGL();
loadImage();
while ( ! SDL_GetKeyState(NULL)[SDLK_ESCAPE] ) // Exit by pressing Back button
{
draw();
SDL_GL_SwapBuffers();
SDL_Event event;
while( SDL_PollEvent(&event) ) ; // Do nothing, just process keyboard/mouse events internally
// Some kinda animation
//SDL_Delay(200);
static float diff = 1.0f;
vertices[0] += diff;
vertices[2] += diff;
vertices[4] += diff;
vertices[6] += diff;
if( vertices[4] > width )
diff = -1.0f;
if( vertices[0] < 0 )
diff = 1.0f;
}
SDL_Quit();
return 0;
}

View File

@@ -1,34 +1,53 @@
# The application settings for Android libSDL port
AppSettingVersion=16
AppSettingVersion=17
LibSdlVersion=1.2
AppName="OpenGL SDL test"
AppFullName=org.opengl.sdl.test
ScreenOrientation=h
InhibitSuspend=n
AppDataDownloadUrl="Gamedata|data2.zip"
VideoDepthBpp=24
NeedDepthBuffer=y
NeedStencilBuffer=n
NeedGles2=n
SwVideoMode=n
SdlVideoResize=n
SdlVideoResizeKeepAspect=n
NeedDepthBuffer=y
AppUsesMouse=n
CompatibilityHacks=n
CompatibilityHacksStaticInit=n
CompatibilityHacksTextInputEmulatesHwKeyboard=n
CompatibilityHacksPreventAudioChopping=n
AppUsesMouse=y
AppNeedsTwoButtonMouse=n
ShowMouseCursor=n
ForceRelativeMouseMode=n
AppNeedsArrowKeys=n
AppNeedsTextInput=n
AppUsesJoystick=n
AppHandlesJoystickSensitivity=n
AppUsesAccelerometer=n
AppUsesMultitouch=n
NonBlockingSwapBuffers=n
RedefinedKeys="RETURN"
AppTouchscreenKeyboardKeysAmount=0
AppTouchscreenKeyboardKeysAmountAutoFire=0
RedefinedKeysScreenKb="RETURN"
StartupMenuButtonTimeout=0
HiddenMenuOptions=''
FirstStartMenuOptions=''
MultiABI=n
AppMinimumRAM=0
AppVersionCode=1
AppVersionName="1"
ResetSdlConfigForThisVersion=n
DeleteFilesOnUpgrade="n"
CompiledLibraries="sdl_image"
CustomBuildScript=n
AppCflags='-finline-functions -O2'
AppLdflags=''
AppSubdirsBuild=''
AppUseCrystaXToolchain=n
AppCmdline=''
ReadmeText='^text'
MinimumScreenSize=s
AdmobPublisherId=n
AdmobTestDeviceId=
AdmobBannerSize=

View File

@@ -0,0 +1,4 @@
sdl_hello: *.cpp
g++ -g3 -O0 -o $@ $? `sdl-config --cflags` `sdl-config --libs` -lGL -lSDL_image
unzip -o AndroidData/*.zip

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,228 @@
#include <string>
#include <vector>
#include <SDL.h>
#include <SDL_image.h>
#ifdef ANDROID
#include <GLES/gl.h>
#define glOrtho glOrthof
#include <android/log.h>
#define fprintf(X, ...) __android_log_print(ANDROID_LOG_INFO, "Ballfield", __VA_ARGS__)
#define printf(...) __android_log_print(ANDROID_LOG_INFO, "Ballfield", __VA_ARGS__)
#else
#include <GL/gl.h>
#endif
int screenWidth = 0;
int screenHeight = 0;
struct Sprite {
Sprite(const char * path)
{
w = h = upload_w = upload_h = texture = 0;
imagePath = path;
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;
upload_w = powerOfTwo(w);
upload_h = powerOfTwo(h);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, glFormat, upload_w, upload_h, 0, glFormat, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, glFormat, GL_UNSIGNED_BYTE, pic->pixels);
SDL_FreeSurface(pic);
return 0;
}
int powerOfTwo(int i)
{
int r;
for (r = 1; r < i; r *= 2) {}
return r;
}
void draw(GLfloat x, GLfloat y, GLfloat width, GLfloat height, GLfloat r = 1.0f, GLfloat g = 1.0f, GLfloat b = 1.0f, GLfloat a = 1.0f)
{
if(texture == 0)
return;
// GL coordinates start at bottom-left corner, which is counter-intuitive for sprite graphics, so we have to flip Y coordinate
GLfloat textureCoordinates[] = { 0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f };
GLfloat vertices[] = { x, screenHeight - y,
x, screenHeight - (y + height),
x + width, screenHeight - (y + height),
x + width, screenHeight - y };
glColor4f(r, g, b, a);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, textureCoordinates);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); // You may just replace all your GL_QUADS with GL_TRIANGLE_FAN and it will draw absolutely identically with same coordinates, if you have just 4 coords.
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void draw(GLfloat x, GLfloat y)
{
draw(x, y, w, h);
}
GLuint texture;
int w, h, upload_w, upload_h;
std::string imagePath;
};
static void
initGL()
{
glViewport(0, 0, screenWidth, screenHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, screenWidth, 0.0f, screenHeight, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glDisable(GL_DEPTH_TEST);
}
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
// You have to do this each frame, because SDL messes up with your GL context when drawing on-screen keyboard, however is saves/restores your matrices
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
static void initSDL()
{
SDL_Init(SDL_INIT_VIDEO);
screenWidth = SDL_GetVideoInfo()->current_w;
screenHeight = SDL_GetVideoInfo()->current_h;
if ( ! SDL_SetVideoMode(screenWidth, screenHeight, 24, SDL_OPENGL|SDL_DOUBLEBUF|SDL_FULLSCREEN) )
{
fprintf(stderr, "Couldn't set GL video mode: %s\n", SDL_GetError());
SDL_Quit();
exit(2);
}
SDL_WM_SetCaption("test", "test");
}
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"));
int 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();
int mouseX = 0, mouseY = 0, buttons = 0;
buttons = SDL_GetMouseState(&mouseX, &mouseY);
sprites[0].draw(mouseX - sprites[0].w/2, mouseY - sprites[0].h/2, sprites[0].w, sprites[0].h, buttons ? 0 : 1, 1, 1, pulse);
sprites[1].draw(coords[0][0], coords[0][1]);
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);
SDL_GL_SwapBuffers();
SDL_Event event;
while( SDL_PollEvent(&event) )
{
if(event.type == SDL_VIDEORESIZE)
{
// Reload textures to OpenGL
initGL();
for(int i = 0; i < sprites.size(); i++)
sprites[i].loadTexture();
}
}
// 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;
}