aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Kropf <josh@slashdev.ca>2011-04-12 11:10:39 (GMT)
committerJosh Kropf <josh@slashdev.ca>2011-04-12 11:10:39 (GMT)
commit9e253635d41decaf1e294129332e03986efa68a3 (patch)
tree570f52bd95060f36b21151f4c416be346f6a1ead
parent97957f681666f29bef2bac81197daf3368f3944f (diff)
downloadballdemo-9e253635d41decaf1e294129332e03986efa68a3.zip
balldemo-9e253635d41decaf1e294129332e03986efa68a3.tar.gz
balldemo-9e253635d41decaf1e294129332e03986efa68a3.tar.bz2
asset loading api with initial implementation for android
-rw-r--r--android/jni/Android.mk2
-rw-r--r--android/jni/logging.cpp24
-rw-r--r--android/jni/main.cpp83
-rw-r--r--android/res/drawable-hdpi/icon.pngbin4147 -> 4474 bytes
-rw-r--r--android/res/values/strings.xml3
-rw-r--r--android/src/com/jiggak/balldemo/BallDemo.java344
-rw-r--r--common/assets.h22
-rwxr-xr-xcommon/mkheaders.sh8
-rw-r--r--common/sprite.cpp58
-rw-r--r--common/sprite.h28
-rw-r--r--common/stage.cpp9
-rw-r--r--common/tex.cpp2
-rw-r--r--common/tex.h2
-rw-r--r--desktop/Makefile4
-rw-r--r--desktop/logging.cpp21
-rw-r--r--desktop/main.cpp32
16 files changed, 400 insertions, 242 deletions
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
index 7826136..7523416 100644
--- a/android/jni/Android.mk
+++ b/android/jni/Android.mk
@@ -42,7 +42,7 @@ LOCAL_SRC_FILES += ../../common/Box2D/Collision/b2BroadPhase.cpp \
../../common/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp \
../../common/Box2D/Dynamics/Joints/b2WeldJoint.cpp
-LOCAL_SRC_FILES += logging.cpp \
+LOCAL_SRC_FILES += \
../../common/glutils.cpp \
../../common/matrix.cpp \
../../common/tex.cpp \
diff --git a/android/jni/logging.cpp b/android/jni/logging.cpp
deleted file mode 100644
index e602bae..0000000
--- a/android/jni/logging.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * logging.cpp
- *
- * Created on: Mar 31, 2011
- * Author: josh
- */
-#include "logging.h"
-#include <android/log.h>
-
-#define LOG_TAG "balldemo"
-
-void logError(const char *fmt, ...) {
- va_list argp;
- va_start(argp, fmt);
- __android_log_vprint(ANDROID_LOG_ERROR, LOG_TAG, fmt, argp);
- va_end(argp);
-}
-
-void logInfo(const char *fmt, ...) {
- va_list argp;
- va_start(argp, fmt);
- __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, fmt, argp);
- va_end(argp);
-}
diff --git a/android/jni/main.cpp b/android/jni/main.cpp
index 7a08ffb..cc5186d 100644
--- a/android/jni/main.cpp
+++ b/android/jni/main.cpp
@@ -1,21 +1,73 @@
#include <jni.h>
+#include <android/log.h>
+
#include "logging.h"
+#include "assets.h"
+
#include "stage.h"
#include "sprite.h"
+#define LOG_TAG "balldemo"
+
+JNIEnv *g_env;
+jobject g_activity;
+
stage *g_stage = NULL;
-void init(GLuint width, GLuint height) {
- if (g_stage) delete g_stage;
+void logError(const char *fmt, ...) {
+ va_list argp;
+ va_start(argp, fmt);
+ __android_log_vprint(ANDROID_LOG_ERROR, LOG_TAG, fmt, argp);
+ va_end(argp);
+}
+
+void logInfo(const char *fmt, ...) {
+ va_list argp;
+ va_start(argp, fmt);
+ __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, fmt, argp);
+ va_end(argp);
+}
+
+asset_t * loadAsset(const char * path) {
+ jstring file = g_env->NewStringUTF(path);
- logInfo("init(%d, %d)", width, height);
+ jclass cls = g_env->GetObjectClass(g_activity);
+ jmethodID mid = g_env->GetMethodID(cls, "loadResource", "(Ljava/lang/String;)[B");
+
+ jbyteArray data = (jbyteArray)g_env->CallObjectMethod(g_activity, mid, file);
+ g_env->DeleteLocalRef(file);
+
+ if (data) {
+ asset_t * asset = new asset_t;
+
+ asset->size = g_env->GetArrayLength(data);
+ asset->data = new uint8_t[asset->size];
+ g_env->GetByteArrayRegion(data, 0, asset->size, (jbyte*)asset->data);
+
+ return asset;
+ }
+
+ return NULL;
+}
+void freeAsset(asset_t * asset) {
+ delete asset->data;
+ delete asset;
+}
+
+void create(GLuint width, GLuint height) {
+ logInfo("create(%d, %d)", width, height);
+ g_stage = new stage(width, height);
+}
+
+void load() {
if (!stage::setupGL()) {
logError("sprite::setupGL failed");
- return;
}
+}
- g_stage = new stage(width, height);
+void destroy() {
+ delete g_stage;
}
void drawFrame() {
@@ -28,14 +80,29 @@ void touchUp(int x, int y) {
}
extern "C" {
-JNIEXPORT void JNICALL Java_com_jiggak_balldemo_BallDemo_init(JNIEnv* env, jobject obj, jint width, jint height);
+JNIEXPORT void JNICALL Java_com_jiggak_balldemo_BallDemo_nativeOnCreate(JNIEnv* env, jobject obj, jint width, jint height);
+JNIEXPORT void JNICALL Java_com_jiggak_balldemo_BallDemo_nativeOnDestroy(JNIEnv* env, jobject obj);
+JNIEXPORT void JNICALL Java_com_jiggak_balldemo_BallDemo_load(JNIEnv* env, jobject obj);
JNIEXPORT void JNICALL Java_com_jiggak_balldemo_BallDemo_drawFrame(JNIEnv* env, jobject obj);
JNIEXPORT void JNICALL Java_com_jiggak_balldemo_BallDemo_touchUp(JNIEnv* env, jobject obj, jint x, jint y);
};
JNIEXPORT void
-JNICALL Java_com_jiggak_balldemo_BallDemo_init(JNIEnv* env, jobject obj, jint width, jint height) {
- init(width, height);
+JNICALL Java_com_jiggak_balldemo_BallDemo_nativeOnCreate(JNIEnv* env, jobject obj, jint width, jint height) {
+ create(width, height);
+
+ g_env = env;
+ g_activity = obj;
+}
+
+JNIEXPORT void
+JNICALL Java_com_jiggak_balldemo_BallDemo_nativeOnDestroy(JNIEnv* env, jobject obj) {
+ destroy();
+}
+
+JNIEXPORT void
+JNICALL Java_com_jiggak_balldemo_BallDemo_load(JNIEnv* env, jobject obj) {
+ load();
}
JNIEXPORT void
diff --git a/android/res/drawable-hdpi/icon.png b/android/res/drawable-hdpi/icon.png
index 8074c4c..8eb4573 100644
--- a/android/res/drawable-hdpi/icon.png
+++ b/android/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml
index 9a86da4..00770ef 100644
--- a/android/res/values/strings.xml
+++ b/android/res/values/strings.xml
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string name="hello">Hello World, BallDemo!</string>
- <string name="app_name">BallDemo</string>
+ <string name="app_name">Ball Demo</string>
</resources>
diff --git a/android/src/com/jiggak/balldemo/BallDemo.java b/android/src/com/jiggak/balldemo/BallDemo.java
index 4aacaa5..4093ba6 100644
--- a/android/src/com/jiggak/balldemo/BallDemo.java
+++ b/android/src/com/jiggak/balldemo/BallDemo.java
@@ -1,5 +1,8 @@
package com.jiggak.balldemo;
+import java.io.IOException;
+import java.io.InputStream;
+
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
@@ -7,154 +10,217 @@ import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
+import android.content.Context;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
+import android.util.Log;
+import android.view.Display;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
public class BallDemo extends Activity {
- private static final String LOGTAG = "balldemo";
-
- static {
- System.loadLibrary("balldemo");
- }
-
- public static native void drawFrame();
- public static native void init(int width, int height);
- public static native void touchUp(int x, int y);
-
- private Renderer renderer;
- private GLSurfaceView view;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- requestWindowFeature(Window.FEATURE_NO_TITLE);
-
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
-
- view = new GLSurfaceView(getApplication()) {
- public boolean onTouchEvent(MotionEvent event) {
- final int x = (int)event.getX();
- final int y = (int)event.getY();
-
- // execute touch events on the rendering thread
- queueEvent(new Runnable() {
- public void run() {
- renderer.handleTouchUp(x, y);
- }
- });
-
- return false;
- }
- };
-
- // need translucent since textures have alpha channel
- view.getHolder().setFormat(PixelFormat.TRANSLUCENT);
-
- view.setEGLContextFactory(new GLSurfaceView.EGLContextFactory() {
- public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
- final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
-
- EGLContext context = egl.eglCreateContext(display,
- eglConfig,
- EGL10.EGL_NO_CONTEXT,
- new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE}
- );
-
- return context;
- }
-
- public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
- egl.eglDestroyContext(display, context);
- }
- });
-
- view.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
- public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
- final int EGL_OPENGL_ES2_BIT = 4;
-
- int[] configAttribs = {
- EGL10.EGL_RED_SIZE, 4,
- EGL10.EGL_GREEN_SIZE, 4,
- EGL10.EGL_BLUE_SIZE, 4,
- EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL10.EGL_NONE
- };
-
- int[] num_config = new int[1];
- egl.eglChooseConfig(display, configAttribs, null, 0, num_config);
-
- int numConfigs = num_config[0];
- if (numConfigs <= 0) {
- throw new IllegalArgumentException("No configs match configSpec");
- }
-
- EGLConfig[] configs = new EGLConfig[numConfigs];
- egl.eglChooseConfig(display, configAttribs, configs, numConfigs, num_config);
-
- return chooseConfig(egl, display, configs);
- }
-
- public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
- for(EGLConfig config : configs) {
- int r = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE, 0);
- int g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0);
- int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0);
- int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0);
-
- // only really care about 8bit rgba
- if (r == 8 && g == 8 && b == 8 && a == 8)
- return config;
- }
-
- return null;
- }
-
- private int findConfigAttrib(EGL10 egl, EGLDisplay display, EGLConfig config, int attribute, int defaultValue) {
- int [] value = new int[1];
- if (egl.eglGetConfigAttrib(display, config, attribute, value)) {
- return value[0];
- }
- return defaultValue;
- }
- });
-
- // create renderer that simply passes control into native code
- view.setRenderer(renderer = new Renderer());
-
- setContentView(view);
+ private static final String LOGTAG = "balldemo";
+
+ static {
+ System.loadLibrary("balldemo");
+ }
+
+ public native void nativeOnCreate(int width, int height);
+ public native void nativeOnDestroy();
+
+ public static native void load();
+ public static native void drawFrame();
+ public static native void touchUp(int x, int y);
+
+ private GLSurfaceView view;
+
+ static void logInfo(String fmt, Object... args) {
+ Log.i(LOGTAG, String.format(fmt, args));
+ }
+
+ static void logError(Exception e, String fmt, Object... args) {
+ Log.e(LOGTAG, String.format(fmt, args), e);
+ }
+
+ static void logError(String fmt, Object... args) {
+ Log.e(LOGTAG, String.format(fmt, args));
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+ getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+ WindowManager.LayoutParams.FLAG_FULLSCREEN);
+
+ Display display = getWindowManager().getDefaultDisplay();
+ int width = display.getWidth();
+ int height = display.getHeight();
+
+ // create engine in native code
+ nativeOnCreate(width, height);
+
+ setContentView(view = new SurfaceView(getApplication()));
+ }
+
+ public byte[] loadResource(String path) {
+ logInfo("loadResource(%s)", path);
+
+ InputStream in = null;
+
+ try {
+ in = getAssets().open(path);
+
+ int size = in.available();
+ byte[] buffer = new byte[size];
+
+ if (in.read(buffer) != size) {
+ logError("loadResource() short read %d != %d", buffer.length, size);
+ }
+
+ return buffer;
+ } catch (IOException e) {
+ logError(e, "loadResource() failed");
+ } finally {
+ try { in.close(); }
+ catch (IOException e) { }
+ }
+
+ return null;
}
-
- @Override
- protected void onPause() {
- super.onPause();
- view.onPause();
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ view.onPause();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ view.onResume();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ nativeOnDestroy();
+ }
+}
+
+class SurfaceView extends GLSurfaceView {
+ private SurfaceViewRenderer renderer;
+
+ public SurfaceView(Context context) {
+ super(context);
+
+ // need translucent since textures have alpha channel
+ getHolder().setFormat(PixelFormat.TRANSLUCENT);
+
+ setEGLContextFactory(new GLSurfaceView.EGLContextFactory() {
+ public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
+ final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+
+ EGLContext context = egl.eglCreateContext(
+ display,
+ eglConfig,
+ EGL10.EGL_NO_CONTEXT,
+ new int[] { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }
+ );
+
+ return context;
+ }
+
+ public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
+ egl.eglDestroyContext(display, context);
+ }
+ });
+
+ setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
+ public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
+ final int EGL_OPENGL_ES2_BIT = 4;
+
+ int[] configAttribs = {
+ EGL10.EGL_RED_SIZE, 4,
+ EGL10.EGL_GREEN_SIZE, 4,
+ EGL10.EGL_BLUE_SIZE, 4,
+ EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL10.EGL_NONE
+ };
+
+ int[] num_config = new int[1];
+ egl.eglChooseConfig(display, configAttribs, null, 0, num_config);
+
+ int numConfigs = num_config[0];
+ if (numConfigs <= 0) {
+ throw new IllegalArgumentException("No configs match configSpec");
+ }
+
+ EGLConfig[] configs = new EGLConfig[numConfigs];
+ egl.eglChooseConfig(display, configAttribs, configs, numConfigs, num_config);
+
+ return chooseConfig(egl, display, configs);
+ }
+
+ public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
+ for (EGLConfig config : configs) {
+ int r = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE, 0);
+ int g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0);
+ int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0);
+ int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0);
+
+ // only really care about 8bit rgba
+ if (r == 8 && g == 8 && b == 8 && a == 8)
+ return config;
+ }
+
+ return null;
+ }
+
+ private int findConfigAttrib(EGL10 egl, EGLDisplay display, EGLConfig config, int attribute, int defaultValue) {
+ int[] value = new int[1];
+ if (egl.eglGetConfigAttrib(display, config, attribute, value)) {
+ return value[0];
+ }
+ return defaultValue;
+ }
+ });
+
+ // create renderer that simply passes control into native code
+ setRenderer(renderer = new SurfaceViewRenderer());
+ }
+
+ public boolean onTouchEvent(MotionEvent event) {
+ final int x = (int) event.getX();
+ final int y = (int) event.getY();
+
+ // execute touch events on the rendering thread
+ queueEvent(new Runnable() {
+ public void run() {
+ renderer.handleTouchUp(x, y);
+ }
+ });
+
+ return false;
+ }
+}
+
+class SurfaceViewRenderer implements GLSurfaceView.Renderer {
+ public void onDrawFrame(GL10 gl) {
+ BallDemo.drawFrame();
}
-
- @Override
- protected void onResume() {
- super.onResume();
- view.onResume();
+
+ public void onSurfaceChanged(GL10 gl, int width, int height) { }
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ BallDemo.load();
}
-
- static class Renderer implements GLSurfaceView.Renderer {
- public void onDrawFrame(GL10 gl) {
- drawFrame();
- }
-
- public void onSurfaceChanged(GL10 gl, int width, int height) {
- init(width, height);
- }
-
- public void onSurfaceCreated(GL10 gl, EGLConfig config) { }
-
- public void handleTouchUp(int x, int y) {
- touchUp(x, y);
- }
+
+ public void handleTouchUp(int x, int y) {
+ BallDemo.touchUp(x, y);
}
-} \ No newline at end of file
+ } \ No newline at end of file
diff --git a/common/assets.h b/common/assets.h
new file mode 100644
index 0000000..42e8354
--- /dev/null
+++ b/common/assets.h
@@ -0,0 +1,22 @@
+/*
+ * assets.h
+ *
+ * Created on: April 11, 2011
+ * Author: josh
+ */
+
+#ifndef ASSETS_H_
+#define ASSETS_H_
+
+#include <stdint.h>
+
+typedef struct asset_t {
+ uint8_t *data;
+ int size;
+} asset_t;
+
+asset_t * loadAsset(const char * path);
+
+void freeAsset(asset_t * asset);
+
+#endif /* ASSETS_H_ */
diff --git a/common/mkheaders.sh b/common/mkheaders.sh
index 7f79224..5e142f2 100755
--- a/common/mkheaders.sh
+++ b/common/mkheaders.sh
@@ -19,11 +19,3 @@ for f in ${SRC}; do
./bin2c <${f} >>${HEADER}
echo -e '\t"\\x00";' >>${HEADER}
done
-
-SRC="../assets/ball.tga"
-HEADER="assets.h"
-
-rm -f ${HEADER}
-for f in ${SRC}; do
- ./bin2c $(path2cname $f) <${f} >>${HEADER}
-done
diff --git a/common/sprite.cpp b/common/sprite.cpp
index a1de579..f9eb52d 100644
--- a/common/sprite.cpp
+++ b/common/sprite.cpp
@@ -19,13 +19,9 @@ GLint sprite::s_u_translation = -1;
GLint sprite::s_u_rotation = -1;
GLint sprite::s_u_size = -1;
-sprite::sprite(const stage & s, const tex_t * texture, const b2BodyDef * def)
- : _stage(s), _width(texture->width), _height(texture->height)
+sprite::sprite(const stage & s, GLuint w, GLuint h)
+ : _stage(s), _width(w), _height(h)
{
- _texture = glutilLoadTexture(texture);
-
- _body = _stage.world()->CreateBody(def);
-
GLfloat hw = _width/2.0f; // half width
GLfloat hh = _height/2.0f; // half height
@@ -40,7 +36,6 @@ sprite::sprite(const stage & s, const tex_t * texture, const b2BodyDef * def)
sprite::~sprite()
{
- glDeleteTextures(1, &_texture);
_stage.world()->DestroyBody(_body);
}
@@ -91,10 +86,7 @@ bool sprite::setupGL()
void sprite::teardownGL()
{
- if (s_a_position) {
- glDeleteProgram(s_a_position);
- s_a_position = 0;
- }
+ glDeleteProgram(s_program);
}
b2Body* sprite::body() const { return _body; }
@@ -117,7 +109,7 @@ void sprite::render()
glEnableVertexAttribArray(s_a_position);
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, _texture);
+ glBindTexture(GL_TEXTURE_2D, this->texture());
glUniform1i(s_u_texture, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
@@ -125,30 +117,48 @@ void sprite::render()
glDisableVertexAttribArray(s_a_position);
}
-sprite * sprite::ballSprite(const stage & s, GLuint x, GLuint y)
-{
- tex_t *texture = texLoadTGA(ball_tga, ball_tga_size);
- if (!texture) {
- return NULL;
- }
+GLuint ball::s_texture = 0;
+ball::ball(const stage & s, GLuint x, GLuint y, GLuint w) : sprite(s, w, w)
+{
b2BodyDef ballBodyDef;
ballBodyDef.type = b2_dynamicBody;
ballBodyDef.position.Set(stage::s2w(x), stage::s2w(y));
- sprite *result = new sprite(s, texture, &ballBodyDef);
-
- texFree(texture);
+ _body = _stage.world()->CreateBody(&ballBodyDef);
b2CircleShape circle;
- circle.m_radius = stage::s2w(result->_width / 2);
+ circle.m_radius = stage::s2w(w / 2);
b2FixtureDef ballShapeDef;
ballShapeDef.shape = &circle;
ballShapeDef.density = 1.0f;
ballShapeDef.friction = 0.2f;
ballShapeDef.restitution = 0.8f;
- result->_body->CreateFixture(&ballShapeDef);
- return result;
+ _body->CreateFixture(&ballShapeDef);
+}
+
+bool ball::load()
+{
+ asset_t * asset = loadAsset("ball.tga");
+ if (!asset) {
+ return false;
+ }
+
+ tex_t *texture = texLoadTGA(asset->data, asset->size);
+ freeAsset(asset);
+
+ if (!texture) {
+ return false;
+ }
+
+ s_texture = glutilLoadTexture(texture);
+
+ return true;
+}
+
+void ball::unload()
+{
+ glDeleteTextures(1, &s_texture);
}
diff --git a/common/sprite.h b/common/sprite.h
index 8b32c07..82ba91b 100644
--- a/common/sprite.h
+++ b/common/sprite.h
@@ -10,11 +10,7 @@
#include "opengl.h"
class stage;
-
class b2Body;
-struct b2BodyDef;
-
-struct tex_t;
class sprite {
private:
@@ -31,26 +27,40 @@ private:
static GLint s_u_rotation;
static GLint s_u_size;
+ GLfloat _verts[8];
+
+protected:
const stage & _stage;
b2Body * _body;
GLuint _width, _height;
- GLfloat _verts[8];
- GLuint _texture;
+ virtual GLuint texture() const { return 0; };
public:
static bool setupGL();
static void teardownGL();
- sprite(const stage & s, const tex_t * texture, const b2BodyDef * def);
- ~sprite();
+ sprite(const stage & s, GLuint w, GLuint h);
+ virtual ~sprite();
b2Body* body() const;
void render();
+};
+
+class ball : public sprite {
+private:
+ static GLuint s_texture;
+
+protected:
+ GLuint texture() const { return s_texture; }
+
+public:
+ ball(const stage & s, GLuint x, GLuint y, GLuint w);
- static sprite * ballSprite(const stage & s, GLuint x, GLuint y);
+ static bool load();
+ static void unload();
};
#endif
diff --git a/common/stage.cpp b/common/stage.cpp
index 970342b..2d7111c 100644
--- a/common/stage.cpp
+++ b/common/stage.cpp
@@ -72,6 +72,7 @@ stage::stage(const GLuint w, const GLuint h, bool rotate)
stage::~stage()
{
sprite::teardownGL();
+ ball::unload();
list<sprite>::cursor c = _sprites.iterate();
while (c.more()) {
@@ -86,6 +87,10 @@ bool stage::setupGL()
if (!sprite::setupGL())
return false;
+ if (!ball::load()) {
+ return false;
+ }
+
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -94,7 +99,7 @@ bool stage::setupGL()
float stage::s2w(unsigned int i)
{
- return i/UNIT_RATIO;
+ return i / UNIT_RATIO;
}
unsigned int stage::w2s(float f)
@@ -147,5 +152,5 @@ void stage::touchUp(int x, int y)
y = _height - y;
}
- this->addSprite(sprite::ballSprite(*this, x, y));
+ this->addSprite(new ball(*this, x, y, 40));
}
diff --git a/common/tex.cpp b/common/tex.cpp
index dddcae8..31624d5 100644
--- a/common/tex.cpp
+++ b/common/tex.cpp
@@ -8,7 +8,7 @@
#include "logging.h"
#include <string.h>
-tex_t* texLoadTGA(const char * data, const int size)
+tex_t* texLoadTGA(const uint8_t * data, const int size)
{
int cursor = 0;
diff --git a/common/tex.h b/common/tex.h
index ced19f3..e66276e 100644
--- a/common/tex.h
+++ b/common/tex.h
@@ -30,7 +30,7 @@ typedef struct {
uint8_t image_descriptor;
} __attribute__((__packed__)) tga_header_t;
-tex_t* texLoadTGA(const char * data, const int size);
+tex_t* texLoadTGA(const uint8_t * data, const int size);
void texFree(tex_t *texture);
diff --git a/desktop/Makefile b/desktop/Makefile
index 75c2b1f..aa425d6 100644
--- a/desktop/Makefile
+++ b/desktop/Makefile
@@ -48,10 +48,10 @@ SRC+=../common/Box2D/Collision/b2BroadPhase.cpp \
../common/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp \
../common/Box2D/Dynamics/Joints/b2WeldJoint.cpp
-SRC+=logging.cpp \
- ../common/tex.cpp \
+SRC+= \
../common/glutils.cpp \
../common/matrix.cpp \
+ ../common/tex.cpp \
../common/sprite.cpp \
../common/stage.cpp \
main.cpp
diff --git a/desktop/logging.cpp b/desktop/logging.cpp
deleted file mode 100644
index 5f48ea9..0000000
--- a/desktop/logging.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "logging.h"
-#include <stdio.h>
-#include <stdarg.h>
-
-void logError(const char *fmt, ...) {
- va_list argp;
- va_start(argp, fmt);
- printf("ERROR: ");
- vprintf(fmt, argp);
- printf("\n");
- va_end(argp);
-}
-
-void logInfo(const char *fmt, ...) {
- va_list argp;
- va_start(argp, fmt);
- printf("INFO: ");
- vprintf(fmt, argp);
- printf("\n");
- va_end(argp);
-}
diff --git a/desktop/main.cpp b/desktop/main.cpp
index f8096a9..16de8a1 100644
--- a/desktop/main.cpp
+++ b/desktop/main.cpp
@@ -1,3 +1,6 @@
+#include <stdio.h>
+#include <stdarg.h>
+
#include <GL/glew.h>
#ifdef __APPLE__
@@ -7,6 +10,8 @@
#endif
#include "logging.h"
+#include "assets.h"
+
#include "stage.h"
#include "sprite.h"
@@ -15,6 +20,33 @@
stage *g_stage = NULL;
+void logError(const char *fmt, ...) {
+ va_list argp;
+ va_start(argp, fmt);
+ printf("ERROR: ");
+ vprintf(fmt, argp);
+ printf("\n");
+ va_end(argp);
+}
+
+void logInfo(const char *fmt, ...) {
+ va_list argp;
+ va_start(argp, fmt);
+ printf("INFO: ");
+ vprintf(fmt, argp);
+ printf("\n");
+ va_end(argp);
+}
+
+asset_t * loadAsset(const char * path) {
+
+}
+
+void freeAsset(asset_t * asset) {
+ delete asset->data;
+ delete asset;
+}
+
void render()
{
g_stage->render();