First cut at GL Touch Joystick

This commit is contained in:
Aaron Culliney 2015-04-01 19:59:38 -07:00
parent d63bd7b412
commit 30236cb400
12 changed files with 1026 additions and 45 deletions

View File

@ -37,6 +37,7 @@ public class Apple2Activity extends Activity {
private final static int BUF_SZ = 4096;
private final static String PREFS_CONFIGURED = "prefs_configured";
private final static int SOFTKEYBOARD_THRESHOLD = 50;
private final static int MAX_FINGERS = 32;// HACK ...
private Apple2View mView = null;
private AlertDialog mQuitDialog = null;
@ -48,6 +49,9 @@ public class Apple2Activity extends Activity {
private int mHeight = 0;
private boolean mSoftKeyboardShowing = false;
private float[] mXCoords = new float[MAX_FINGERS];
private float[] mYCoords = new float[MAX_FINGERS];
static {
System.loadLibrary("apple2ix");
}
@ -63,7 +67,8 @@ public class Apple2Activity extends Activity {
public native void nativeOnResume();
public native void nativeOnPause();
public native void nativeOnQuit();
public native boolean nativeOnTouch(int action, float x, float y);
public native boolean nativeOnTouch(int action, int pointerCount, int pointerIndex, float[] xCoords, float[] yCoords);
public native void nativeReboot();
public native void nativeRender();
@ -238,6 +243,45 @@ public class Apple2Activity extends Activity {
}
}
private String actionToString(int action) {
switch (action) {
case MotionEvent.ACTION_CANCEL:
return "CANCEL:"+action;
case MotionEvent.ACTION_DOWN:
return "DOWN:"+action;
case MotionEvent.ACTION_MOVE:
return "MOVE:"+action;
case MotionEvent.ACTION_UP:
return "UP:"+action;
case MotionEvent.ACTION_POINTER_DOWN:
return "PDOWN:"+action;
case MotionEvent.ACTION_POINTER_UP:
return "PUP:"+action;
default:
return "UNK:"+action;
}
}
private void printSamples(MotionEvent ev) {
final int historySize = ev.getHistorySize();
final int pointerCount = ev.getPointerCount();
/*
for (int h = 0; h < historySize; h++) {
Log.d(TAG, "Event "+ev.getAction().toString()+" at historical time "+ev.getHistoricalEventTime(h)+" :");
for (int p = 0; p < pointerCount; p++) {
Log.d(TAG, " pointer "+ev.getPointerId(p)+": ("+ev.getHistoricalX(p, h)+","+ev.getHistoricalY(p, h)+")");
}
}
*/
int pointerIndex = ev.getActionIndex();
Log.d(TAG, "Event "+actionToString(ev.getActionMasked())+" for "+pointerIndex+" at time "+ev.getEventTime()+" :");
for (int p=0; p<pointerCount; p++) {
Log.d(TAG, " pointer "+ev.getPointerId(p)+": ("+ev.getX(p)+","+ev.getY(p)+")");
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
do {
@ -251,16 +295,21 @@ public class Apple2Activity extends Activity {
break;
}
printSamples(event);
int action = event.getActionMasked();
float x = event.getX();
float y = event.getY();
int pointerIndex = event.getActionIndex();
int pointerCount = event.getPointerCount();
for (int i=0; i<pointerCount/* && i < MAX_FINGERS */; i++) {
mXCoords[i] = event.getX(i);
mYCoords[i] = event.getY(i);
}
boolean nativeHandled = nativeOnTouch(action, x, y);
boolean nativeHandled = nativeOnTouch(action, pointerCount, pointerIndex, mXCoords, mYCoords);
if (nativeHandled) {
break;
}
this.mDetector.onTouchEvent(event);
//this.mDetector.onTouchEvent(event);
} while (false);
return super.onTouchEvent(event);

View File

@ -15,6 +15,15 @@
#include <jni.h>
#include <math.h>
enum {
ANDROID_ACTION_DOWN = 0x0,
ANDROID_ACTION_UP = 0x1,
ANDROID_ACTION_MOVE = 0x2,
ANDROID_ACTION_CANCEL = 0x3,
ANDROID_ACTION_POINTER_DOWN = 0x5,
ANDROID_ACTION_POINTER_UP = 0x6,
};
static bool nativePaused = false;
#if TESTING
@ -45,6 +54,26 @@ static bool _run_tests(void) {
}
#endif
static inline int _androidTouchEvent2JoystickEvent(jint action) {
switch (action) {
case ANDROID_ACTION_DOWN:
return TOUCH_DOWN;
case ANDROID_ACTION_MOVE:
return TOUCH_MOVE;
case ANDROID_ACTION_UP:
return TOUCH_UP;
case ANDROID_ACTION_POINTER_DOWN:
return TOUCH_POINTER_DOWN;
case ANDROID_ACTION_POINTER_UP:
return TOUCH_POINTER_UP;
case ANDROID_ACTION_CANCEL:
return TOUCH_CANCEL;
default:
LOG("Unknown Android event : %d", action);
return TOUCH_CANCEL;
}
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnCreate(JNIEnv *env, jobject obj, jstring j_dataDir) {
const char *dataDir = (*env)->GetStringUTFChars(env, j_dataDir, 0);
data_dir = strdup(dataDir);
@ -154,8 +183,23 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnKeyUp(JNIEnv *env, jobjec
#endif
}
jboolean Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnTouch(JNIEnv *env, jobject obj, jint action, jfloat keyCode, jfloat metaState) {
return false;
jboolean Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnTouch(JNIEnv *env, jobject obj, jint action, jint pointerCount, jint pointerIndex, jfloatArray xCoords, jfloatArray yCoords) {
//LOG("nativeOnTouch : %d/%d/%d :", action, pointerCount, pointerIndex);
jfloat *x_coords = (*env)->GetFloatArrayElements(env, xCoords, 0);
jfloat *y_coords = (*env)->GetFloatArrayElements(env, yCoords, 0);
int joyaction = _androidTouchEvent2JoystickEvent(action);
//for (unsigned int i=0; i<pointerCount; i++) {
// LOG("\t[%f,%f]", x_coords[i], y_coords[i]);
//}
bool consumed = joydriver_onTouchEvent(joyaction, pointerCount, pointerIndex, x_coords, y_coords);
(*env)->ReleaseFloatArrayElements(env, xCoords, x_coords, 0);
(*env)->ReleaseFloatArrayElements(env, yCoords, y_coords, 0);
return consumed;
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeIncreaseCPUSpeed(JNIEnv *env, jobject obj) {

View File

@ -33,5 +33,5 @@ APPLE2_MAIN_SRC = \
$(APPLE2_SRC_PATH)/timing.c $(APPLE2_SRC_PATH)/zlib-helpers.c $(APPLE2_SRC_PATH)/joystick.c $(APPLE2_SRC_PATH)/keys.c \
$(APPLE2_SRC_PATH)/disk.c $(APPLE2_SRC_PATH)/cpu-supp.c
APPLE2_BASE_CFLAGS := -DAPPLE2IX=1 -DMOBILE_DEVICE=1 -DVIDEO_OPENGL=1 -DDEBUGGER=1 -std=gnu11 -I$(APPLE2_SRC_PATH)
APPLE2_BASE_CFLAGS := -DAPPLE2IX=1 -DTOUCH_JOYSTICK=1 -DMOBILE_DEVICE=1 -DVIDEO_OPENGL=1 -DDEBUGGER=1 -std=gnu11 -I$(APPLE2_SRC_PATH)

View File

@ -219,15 +219,7 @@ static void c_calibrate_keypad_joystick()
}
}
#endif // KEYPAD_JOYSTICK
#endif // INTERFACE_CLASSIC
#ifdef TOUCH_JOYSTICK
// TBD ...
#endif
/* ---------------------------------------------------------------------- */
#ifdef INTERFACE_CLASSIC
void c_calibrate_joystick()
{
if (joy_mode == JOY_PCJOY)
@ -245,7 +237,7 @@ void c_calibrate_joystick()
#endif // INTERFACE_CLASSIC
extern void gldriver_joystick_reset(void);
void c_joystick_reset()
void c_joystick_reset(void)
{
#if VIDEO_OPENGL && !TESTING
if (!is_headless) {
@ -264,3 +256,23 @@ void c_joystick_reset()
#endif
}
#if TOUCH_JOYSTICK
bool (*joydriver_onTouchEvent)(joystick_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords) = NULL;
// is the touch joystick available
bool (*joydriver_isTouchJoystickAvailable)(void) = NULL;
// enable/disable touch joystick
void (*joydriver_setTouchJoyEnabled)(bool enabled) = NULL;
// set the joystick button parameters (7bit ASCII characters or MOUSETEXT values)
void (*joydriver_setTouchButtonValues)(char button0Val, char button1Val) = NULL;
// set the axis type
void (*joydriver_setTouchAxisType)(touchjoy_axis_type_t axisType) = NULL;
// set the axis button parameters (7bit ASCII characters or MOUSETEXT values)
void (*joydriver_setTouchAxisValues)(char up, char left, char right, char down) = NULL;
#endif

View File

@ -9,13 +9,6 @@
*
*/
/*
* 65c02 CPU Timing Support.
*
* Copyleft 2013 Aaron Culliney
*
*/
#ifndef _JOYSTICK_H_
#define _JOYSTICK_H_
@ -39,4 +32,40 @@ void c_joystick_reset(void);
void c_calibrate_joystick(void);
#endif
#if TOUCH_JOYSTICK
typedef enum joystick_touch_event_t {
TOUCH_CANCEL = 0,
TOUCH_DOWN,
TOUCH_MOVE,
TOUCH_UP,
TOUCH_POINTER_DOWN,
TOUCH_POINTER_UP,
} joystick_touch_event_t;
typedef enum touchjoy_axis_type_t {
AXIS_EMULATED_DEVICE = 0, // touch joystick axes emulate a physical joystick device
AXIS_EMULATED_KEYBOARD, // touch joystick axes send single key events
} touchjoy_axis_type_t;
// handle touch event
extern bool (*joydriver_onTouchEvent)(joystick_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords);
// is the touch joystick available
extern bool (*joydriver_isTouchJoystickAvailable)(void);
// enable/disable touch joystick
extern void (*joydriver_setTouchJoyEnabled)(bool enabled);
// set the joystick button parameters (7bit ASCII characters or MOUSETEXT values)
extern void (*joydriver_setTouchButtonValues)(char button0Val, char button1Val);
// set the axis type
extern void (*joydriver_setTouchAxisType)(touchjoy_axis_type_t axisType);
// set the axis button parameters (7bit ASCII characters or MOUSETEXT values)
extern void (*joydriver_setTouchAxisValues)(char up, char left, char right, char down);
#endif // TOUCH_JOYSTICK
#endif // whole file

View File

@ -30,21 +30,37 @@ uniform sampler2D framebufferTexture;
// Floating message
uniform sampler2D messageTexture;
// Joystick axis
uniform sampler2D axisTexture;
// Joystick buttons
uniform sampler2D buttonTexture;
#if __VERSION__ >= 140
#define OUTPUT_TEXTURE(TEX) \
vec4 tex = texture(TEX, varTexcoord.st, 0.0); \
fragColor = vec4(tex.r, tex.g, tex.b, 1.0*aValue)
fragColor = vec4(tex.r, tex.g, tex.b, tex.a*aValue)
#define OUTPUT_RED() \
fragColor = vec4(1.0, 0.0, 0.0, 1.0)
#else
#define OUTPUT_TEXTURE(TEX) \
vec4 tex = texture2D(TEX, varTexcoord.st, 0.0); \
gl_FragColor = vec4(tex.r, tex.g, tex.b, 1.0*aValue)
gl_FragColor = vec4(tex.r, tex.g, tex.b, tex.a*aValue)
#define OUTPUT_RED() \
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0)
#endif
void main(void)
{
if (tex2Use == 1) {
OUTPUT_TEXTURE(messageTexture);
} else {
if (tex2Use == 0) {
OUTPUT_TEXTURE(framebufferTexture);
} else if (tex2Use == 1) {
OUTPUT_TEXTURE(messageTexture);
} else if (tex2Use == 2) {
OUTPUT_TEXTURE(axisTexture);
} else if (tex2Use == 3) {
OUTPUT_TEXTURE(buttonTexture);
} else {
//OUTPUT_RED(); -- WTF is this failing?
}
}

View File

@ -74,3 +74,11 @@ void gldriver_animation_render(void) {
}
}
void gldriver_animation_reshape(int w, int h) {
glanim_array_node_t *p = animations;
while (p) {
p->anim->reshape(w, h);
p = p->next;
}
}

View File

@ -14,14 +14,11 @@
#ifndef _GLANIMATION_H_
#define _GLANIMATION_H_
typedef void (*glanim_ctor_fn)(void);
typedef void (*glanim_dtor_fn)(void);
typedef void (*glanim_render_fn)(void);
typedef struct glanim_t {
glanim_ctor_fn ctor;
glanim_dtor_fn dtor;
glanim_render_fn render;
void (*ctor)(void);
void (*dtor)(void);
void (*render)(void);
void (*reshape)(int w, int h);
} glanim_t;
// register an animation
@ -36,5 +33,8 @@ void gldriver_animation_destroy(void);
// renders the animation
void gldriver_animation_render(void);
// renders the animation
void gldriver_animation_reshape(int w, int h);
#endif

View File

@ -48,10 +48,10 @@ static glanim_t cpuMessageAnimation = { 0 };
static void _create_message_model(void) {
const GLfloat messageObj_positions[] = {
-0.3, -0.3, -0.1, 1.0,
0.3, -0.3, -0.1, 1.0,
-0.3, 0.3, -0.1, 1.0,
0.3, 0.3, -0.1, 1.0,
-0.3, -0.3, -0.0625, 1.0,
0.3, -0.3, -0.0625, 1.0,
-0.3, 0.3, -0.0625, 1.0,
0.3, 0.3, -0.0625, 1.0,
};
const GLfloat messageObj_texcoords[] = {
0.0, 1.0,
@ -349,6 +349,10 @@ static void cpuanim_render(void) {
_render_message_object(alpha, cpuMessageObjVAOName, cpuMessageObjPosBufferName, cpuMessageObjTexcoordBufferName, cpuMessageObjElementBufferName);
}
static void cpuanim_reshape(int w, int h) {
// no-op
}
static void cpuanim_show(void) {
if (!animation_subsystem_functional) {
return;
@ -403,6 +407,7 @@ static void _init_glcpuanim(void) {
cpuMessageAnimation.ctor = &cpuanim_init;
cpuMessageAnimation.dtor = &cpuanim_destroy;
cpuMessageAnimation.render = &cpuanim_render;
cpuMessageAnimation.reshape = &cpuanim_reshape;
gldriver_register_animation(&cpuMessageAnimation);
}

View File

@ -9,11 +9,802 @@
*
*/
// GL touch joystick -- Created by Aaron Culliney
#include "common.h"
#include "video/glvideo.h"
void gldriver_joystick_reset(void) {
#define MAX_FINGERS 32
#define TOUCHJOY_TEMPLATE_COLS 5
#define TOUCHJOY_TEMPLATE_ROWS 5
// HACK NOTE FIXME TODO : interpolated pixel adjustment still necessary ...
#define TOUCHJOY_FB_WIDTH ((TOUCHJOY_TEMPLATE_COLS * FONT80_WIDTH_PIXELS) + INTERPOLATED_PIXEL_ADJUSTMENT)
#define TOUCHJOY_FB_HEIGHT (TOUCHJOY_TEMPLATE_ROWS * FONT_HEIGHT_PIXELS)
enum {
TOUCHED_NONE = -1,
TOUCHED_BUTTON0 = 0,
TOUCHED_BUTTON1,
TOUCHED_BOTH,
};
static bool isAvailable = false;
static bool isEnabled = true;
static bool isVisible = true;
static char axisTemplate[TOUCHJOY_TEMPLATE_ROWS][TOUCHJOY_TEMPLATE_COLS+1] = {
"|||||",
"| @ |",
"|@+@|",
"| @ |",
"|||||",
};
static char buttonTemplate[TOUCHJOY_TEMPLATE_ROWS][TOUCHJOY_TEMPLATE_COLS+1] = {
" |||",
" |@|",
"|||||",
"|@|+ ",
"||| ",
};
static const GLfloat model_width = 0.5;
static const GLfloat model_height = 0.5;
static glanim_t touchjoyAnimation = { 0 };
static int viewportWidth = 0;
static int viewportHeight = 0;
// touch axis variables
static demoModel *touchAxisObjModel = NULL;
static GLuint touchAxisObjVAOName = UNINITIALIZED_GL;
static GLuint touchAxisObjTextureName = UNINITIALIZED_GL;
static GLuint touchAxisObjPosBufferName = UNINITIALIZED_GL;
static GLuint touchAxisObjTexcoordBufferName = UNINITIALIZED_GL;
static GLuint touchAxisObjElementBufferName = UNINITIALIZED_GL;
static int touchAxisObjModelScreenX = 0;
static int touchAxisObjModelScreenY = 0;
static int touchAxisObjModelScreenXMax = 0;
static int touchAxisObjModelScreenYMax = 0;
static uint8_t touchAxisObjFB[TOUCHJOY_FB_WIDTH * TOUCHJOY_FB_HEIGHT] = { 0 };
static uint8_t touchAxisObjPixels[TOUCHJOY_FB_WIDTH * TOUCHJOY_FB_HEIGHT * 4] = { 0 };// RGBA8888
static bool axisTextureDirty = true;
static int trackingAxisIndex = TOUCHED_NONE;
// button object variables
static demoModel *buttonObjModel = NULL;
static GLuint buttonObjVAOName = UNINITIALIZED_GL;
static GLuint buttonObjTextureName = UNINITIALIZED_GL;
static GLuint buttonObjPosBufferName = UNINITIALIZED_GL;
static GLuint buttonObjTexcoordBufferName = UNINITIALIZED_GL;
static GLuint buttonObjElementBufferName = UNINITIALIZED_GL;
static int buttonObj0ScreenX = 0;
static int buttonObj0ScreenY = 0;
static int buttonObj0ScreenXMax = 0;
static int buttonObj0ScreenYMax = 0;
static int buttonObj1ScreenX = 0;
static int buttonObj1ScreenY = 0;
static int buttonObj1ScreenXMax = 0;
static int buttonObj1ScreenYMax = 0;
static uint8_t buttonObjFB[TOUCHJOY_FB_WIDTH * TOUCHJOY_FB_HEIGHT] = { 0 };
static uint8_t buttonObjPixels[TOUCHJOY_FB_WIDTH * TOUCHJOY_FB_HEIGHT * 4] = { 0 };// RGBA8888
static bool buttonTextureDirty = true;
static int trackingButton0Index = TOUCHED_NONE;
static int trackingButton1Index = TOUCHED_NONE;
static int trackingButtonBothIndex = TOUCHED_NONE;
// configurables for current touchjoy
static uint8_t button0Char = MOUSETEXT_OPENAPPLE;
static uint8_t button1Char = MOUSETEXT_CLOSEDAPPLE;
static touchjoy_axis_type_t touchjoy_axisType = AXIS_EMULATED_DEVICE;
static uint8_t upChar = MOUSETEXT_UP;
static uint8_t leftChar = MOUSETEXT_LEFT;
static uint8_t rightChar = MOUSETEXT_RIGHT;
static uint8_t downChar = MOUSETEXT_DOWN;
// ----------------------------------------------------------------------------
static demoModel *_create_model(GLfloat skew_x, GLfloat skew_y) {
/* 2...3
* .
* .
* .
* 0...1
*/
const GLfloat obj_positions[] = {
skew_x, skew_y, -0.03125, 1.0,
skew_x+model_width, skew_y, -0.03125, 1.0,
skew_x, skew_y+model_height, -0.03125, 1.0,
skew_x+model_width, skew_y+model_height, -0.03125, 1.0,
};
const GLfloat obj_texcoords[] = {
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0,
};
const GLushort indices[] = {
0, 1, 2, 2, 1, 3
};
demoModel *obj = calloc(1, sizeof(demoModel));
obj->numVertices = 4;
obj->numElements = 6;
obj->positions = malloc(sizeof(obj_positions));
memcpy(obj->positions, &obj_positions[0], sizeof(obj_positions));
obj->positionType = GL_FLOAT;
obj->positionSize = 4; // x,y,z coordinates
obj->positionArraySize = sizeof(obj_positions);
obj->texcoords = malloc(sizeof(obj_texcoords));
memcpy(obj->texcoords, &obj_texcoords[0], sizeof(obj_texcoords));
obj->texcoordType = GL_FLOAT;
obj->texcoordSize = 2; // s,t coordinates
obj->texcoordArraySize = sizeof(obj_texcoords);
obj->normals = NULL;
obj->normalType = GL_NONE;
obj->normalSize = GL_NONE;
obj->normalArraySize = 0;
obj->elements = malloc(sizeof(indices));
memcpy(obj->elements, &indices[0], sizeof(indices));
obj->elementType = GL_UNSIGNED_SHORT;
obj->elementArraySize = sizeof(indices);
return obj;
}
static void _create_VAO_VBOs(const demoModel *model, GLuint *vaoName, GLuint *posBufferName, GLuint *texcoordBufferName, GLuint *elementBufferName) {
// Create a vertex array object (VAO) to cache model parameters
#if USE_VAO
glGenVertexArrays(1, vaoName);
glBindVertexArray(*vaoName);
#endif
// Create a vertex buffer object (VBO) to store positions and load data
glGenBuffers(1, posBufferName);
glBindBuffer(GL_ARRAY_BUFFER, *posBufferName);
glBufferData(GL_ARRAY_BUFFER, model->positionArraySize, model->positions, GL_STATIC_DRAW);
#if USE_VAO
// Enable the position attribute for this VAO
glEnableVertexAttribArray(POS_ATTRIB_IDX);
// Get the size of the position type so we can set the stride properly
GLsizei posTypeSize = _get_gl_type_size(model->positionType);
// Set up parmeters for position attribute in the VAO including,
// size, type, stride, and offset in the currenly bound VAO
// This also attaches the position VBO to the VAO
glVertexAttribPointer(POS_ATTRIB_IDX, // What attibute index will this array feed in the vertex shader (see buildProgram)
model->positionSize, // How many elements are there per position?
model->positionType, // What is the type of this data?
GL_FALSE, // Do we want to normalize this data (0-1 range for fixed-pont types)
model->positionSize*posTypeSize, // What is the stride (i.e. bytes between positions)?
0); // What is the offset in the VBO to the position data?
#endif
if (model->texcoords) {
// Create a VBO to store texcoords
glGenBuffers(1, texcoordBufferName);
glBindBuffer(GL_ARRAY_BUFFER, *texcoordBufferName);
// Allocate and load texcoord data into the VBO
glBufferData(GL_ARRAY_BUFFER, model->texcoordArraySize, model->texcoords, GL_STATIC_DRAW);
#if USE_VAO
// Enable the texcoord attribute for this VAO
glEnableVertexAttribArray(TEXCOORD_ATTRIB_IDX);
// Get the size of the texcoord type so we can set the stride properly
GLsizei texcoordTypeSize = _get_gl_type_size(model->texcoordType);
// Set up parmeters for texcoord attribute in the VAO including,
// size, type, stride, and offset in the currenly bound VAO
// This also attaches the texcoord VBO to VAO
glVertexAttribPointer(TEXCOORD_ATTRIB_IDX, // What attibute index will this array feed in the vertex shader (see buildProgram)
model->texcoordSize, // How many elements are there per texture coord?
model->texcoordType, // What is the type of this data in the array?
GL_TRUE, // Do we want to normalize this data (0-1 range for fixed-point types)
model->texcoordSize*texcoordTypeSize, // What is the stride (i.e. bytes between texcoords)?
0); // What is the offset in the VBO to the texcoord data?
#endif
}
// Create a VBO to vertex array elements
// This also attaches the element array buffer to the VAO
glGenBuffers(1, elementBufferName);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *elementBufferName);
// Allocate and load vertex array element data into VBO
glBufferData(GL_ELEMENT_ARRAY_BUFFER, model->elementArraySize, model->elements, GL_STATIC_DRAW);
GL_ERRLOG("gltouchjoy finished creating VAO/VBOs");
}
static void _destroy_VAO_VBOs(GLuint vaoName, GLuint posBufferName, GLuint texcoordBufferName, GLuint elementBufferName) {
// Bind the VAO so we can get data from it
#if USE_VAO
glBindVertexArray(vaoName);
// For every possible attribute set in the VAO
for (GLuint index = 0; index < 16; index++) {
// Get the VBO set for that attibute
GLuint bufName = 0;
glGetVertexAttribiv(index , GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, (GLint*)&bufName);
// If there was a VBO set...
if (bufName) {
//...delete the VBO
glDeleteBuffers(1, &bufName);
}
}
// Get any element array VBO set in the VAO
{
GLuint bufName = 0;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint*)&bufName);
// If there was a element array VBO set in the VAO
if (bufName) {
//...delete the VBO
glDeleteBuffers(1, &bufName);
}
}
// Finally, delete the VAO
glDeleteVertexArrays(1, &vaoName);
#else
glDeleteBuffers(1, &posBufferName);
glDeleteBuffers(1, &texcoordBufferName);
glDeleteBuffers(1, &elementBufferName);
#endif
GL_ERRLOG("gltouchjoy destroying VAO/VBOs");
}
static GLuint _create_texture(GLvoid *pixels) {
GLuint texName = UNINITIALIZED_GL;
// Create a texture object to apply to model
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
// Set up filter and wrap modes for this texture object
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_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Indicate that pixel rows are tightly packed
// (defaults to stride of 4 which is kind of only good for
// RGBA or FLOAT data types)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// register texture with OpenGL
glTexImage2D(GL_TEXTURE_2D, /*level*/0, /*internal format*/GL_RGBA, TOUCHJOY_FB_WIDTH, TOUCHJOY_FB_HEIGHT, /*border*/0, /*format*/GL_RGBA, GL_UNSIGNED_BYTE, pixels);
GL_ERRLOG("gltouchjoy texture");
return texName;
}
static void _setup_object(char *submenu, uint8_t *fb, uint8_t *pixels) {
// render template into indexed fb
unsigned int submenu_width = TOUCHJOY_TEMPLATE_COLS;
unsigned int submenu_height = TOUCHJOY_TEMPLATE_ROWS;
video_interface_print_submenu_centered_fb(fb, submenu_width, submenu_height, submenu, submenu_width, submenu_height);
// generate RGBA_8888 from indexed color
unsigned int count = TOUCHJOY_FB_WIDTH * TOUCHJOY_FB_HEIGHT;
for (unsigned int i=0, j=0; i<count; i++, j+=4) {
uint8_t index = *(fb + i);
uint32_t rgb = (((uint32_t)(colormap[index].red) << 0 ) |
((uint32_t)(colormap[index].green) << 8 ) |
((uint32_t)(colormap[index].blue) << 16));
if (rgb == 0) {
// make black transparent for joystick
} else {
rgb |= ((uint32_t)0xff << 24);
}
*( (uint32_t*)(pixels + j) ) = rgb;
}
}
static void _setup_axis_object(void) {
axisTemplate[1][2] = upChar;
axisTemplate[2][1] = leftChar;
axisTemplate[2][3] = rightChar;
axisTemplate[3][2] = downChar;
_setup_object(axisTemplate[0], touchAxisObjFB, touchAxisObjPixels);
axisTextureDirty = true;
}
static void _setup_button_object(void) {
buttonTemplate[1][3] = button1Char;
buttonTemplate[3][1] = button0Char;
_setup_object(buttonTemplate[0], buttonObjFB, buttonObjPixels);
buttonTextureDirty = true;
}
static void _model_to_screen(float screenCoords[4], demoModel *model) {
float x0 = 1.0;
float y0 = 1.0;
float x1 = -1.0;
float y1 = -1.0;
#if PERSPECTIVE
#error TODO FIXME we really should do it this way regardless of whether we are using PERSPECTIVE ...
// project models to screen space for touch handling
GLfloat mvp[16];
#else
#warning TODO FIXME ... should really use matrix calculations (assuming identity/orthographic for now)
GLfloat *positions = (GLfloat *)(model->positions);
unsigned int stride = model->positionSize;
unsigned int len = model->positionArraySize/_get_gl_type_size(model->positionType);
for (unsigned int i=0; i < len; i += stride) {
float x = (positions[i] + 1.f) / 2.f;
if (x < x0) {
x0 = x;
}
if (x > x1) {
x1 = x;
}
float y = (positions[i+1] + 1.f) / 2.f;
LOG("\tmodel x:%f, y:%f", x, y);
if (y < y0) {
y0 = y;
}
if (y > y1) {
y1 = y;
}
}
#endif
// OpenGL screen origin is bottom-left (Android is top-left)
float yFlip0 = viewportHeight - (y1 * viewportHeight);
float yFlip1 = viewportHeight - (y0 * viewportHeight);
screenCoords[0] = x0 * viewportWidth;
screenCoords[1] = yFlip0;
screenCoords[2] = x1 * viewportWidth;
screenCoords[3] = yFlip1;
}
static void gltouchjoy_init(void) {
LOG("gltouchjoy_init ...");
mdlDestroyModel(touchAxisObjModel);
mdlDestroyModel(buttonObjModel);
touchAxisObjModel = _create_model(-1.05, -1.0);
touchAxisObjVAOName = UNINITIALIZED_GL;
touchAxisObjPosBufferName = UNINITIALIZED_GL;
touchAxisObjTexcoordBufferName = UNINITIALIZED_GL;
touchAxisObjElementBufferName = UNINITIALIZED_GL;
_create_VAO_VBOs(touchAxisObjModel, &touchAxisObjVAOName, &touchAxisObjPosBufferName, &touchAxisObjTexcoordBufferName, &touchAxisObjElementBufferName);
if (touchAxisObjPosBufferName == UNINITIALIZED_GL || touchAxisObjTexcoordBufferName == UNINITIALIZED_GL || touchAxisObjElementBufferName == UNINITIALIZED_GL)
{
LOG("gltouchjoy not initializing axis");
return;
}
touchAxisObjTextureName = _create_texture(touchAxisObjPixels);
if (touchAxisObjTextureName == UNINITIALIZED_GL) {
LOG("gltouchjoy not initializing axis: texture error");
return;
}
_setup_axis_object();
float screenCoords[4] = { 0 };
_model_to_screen(screenCoords, touchAxisObjModel);
touchAxisObjModelScreenX = (int)screenCoords[0];
touchAxisObjModelScreenY = (int)screenCoords[1];
touchAxisObjModelScreenXMax = (int)screenCoords[2];
touchAxisObjModelScreenYMax = (int)screenCoords[3];
LOG("axis screen coords: [%d,%d] -> [%d,%d]", touchAxisObjModelScreenX, touchAxisObjModelScreenY, touchAxisObjModelScreenXMax, touchAxisObjModelScreenYMax);
// button object
buttonObjModel = _create_model(1.05-model_width, -1.0);
buttonObjVAOName = UNINITIALIZED_GL;
buttonObjPosBufferName = UNINITIALIZED_GL;
buttonObjTexcoordBufferName = UNINITIALIZED_GL;
buttonObjElementBufferName = UNINITIALIZED_GL;
_create_VAO_VBOs(buttonObjModel, &buttonObjVAOName, &buttonObjPosBufferName, &buttonObjTexcoordBufferName, &buttonObjElementBufferName);
if (buttonObjPosBufferName == UNINITIALIZED_GL || buttonObjTexcoordBufferName == UNINITIALIZED_GL || buttonObjElementBufferName == UNINITIALIZED_GL)
{
LOG("gltouchjoy not initializing buttons");
return;
}
buttonObjTextureName = _create_texture(buttonObjPixels);
if (buttonObjTextureName == UNINITIALIZED_GL) {
LOG("not initializing buttons: texture error");
return;
}
_setup_button_object();
// NOTE : button model is a composite of both button 0 and button 1 (with ability to press both with one touch)
_model_to_screen(screenCoords, buttonObjModel);
int button0W = ((int)screenCoords[2] - (int)screenCoords[0]) >>1;
buttonObj0ScreenX = (int)screenCoords[0]+button0W;
buttonObj0ScreenY = (int)screenCoords[1];
buttonObj0ScreenXMax = (int)screenCoords[2];
buttonObj0ScreenYMax = (int)screenCoords[3];
LOG("button 0 screen coords: [%d,%d] -> [%d,%d]", buttonObj0ScreenX, buttonObj0ScreenY, buttonObj0ScreenXMax, buttonObj0ScreenYMax);
int button1H = ((int)screenCoords[3] - (int)screenCoords[1]) >>1;
buttonObj1ScreenX = (int)screenCoords[0];
buttonObj1ScreenY = (int)screenCoords[1]+button1H;
buttonObj1ScreenXMax = (int)screenCoords[2];
buttonObj1ScreenYMax = (int)screenCoords[3];
LOG("button 1 screen coords: [%d,%d] -> [%d,%d]", buttonObj1ScreenX, buttonObj1ScreenY, buttonObj1ScreenXMax, buttonObj1ScreenYMax);
isAvailable = true;
}
static void gltouchjoy_destroy(void) {
LOG("gltouchjoy_destroy ...");
if (!isAvailable) {
return;
}
isAvailable = false;
glDeleteTextures(1, &touchAxisObjTextureName);
touchAxisObjTextureName = UNINITIALIZED_GL;
_destroy_VAO_VBOs(touchAxisObjVAOName, touchAxisObjPosBufferName, touchAxisObjTexcoordBufferName, touchAxisObjElementBufferName);
touchAxisObjVAOName = UNINITIALIZED_GL;
touchAxisObjPosBufferName = UNINITIALIZED_GL;
touchAxisObjTexcoordBufferName = UNINITIALIZED_GL;
touchAxisObjElementBufferName = UNINITIALIZED_GL;
mdlDestroyModel(touchAxisObjModel);
touchAxisObjModel = NULL;
glDeleteTextures(1, &buttonObjTextureName);
buttonObjTextureName = UNINITIALIZED_GL;
_destroy_VAO_VBOs(buttonObjVAOName, buttonObjPosBufferName, buttonObjTexcoordBufferName, buttonObjElementBufferName);
buttonObjVAOName = UNINITIALIZED_GL;
buttonObjPosBufferName = UNINITIALIZED_GL;
buttonObjTexcoordBufferName = UNINITIALIZED_GL;
buttonObjElementBufferName = UNINITIALIZED_GL;
mdlDestroyModel(buttonObjModel);
buttonObjModel = NULL;
}
static void _render_object(demoModel *model, GLuint vaoName, GLuint posBufferName, GLuint texcoordBufferName, GLuint elementBufferName) {
// Bind our vertex array object
#if USE_VAO
glBindVertexArray(vaoName);
#else
glBindBuffer(GL_ARRAY_BUFFER, posBufferName);
GLsizei posTypeSize = _get_gl_type_size(model->positionType);
GLsizei texcoordTypeSize = _get_gl_type_size(model->texcoordType);
// Set up parmeters for position attribute in the VAO including, size, type, stride, and offset in the currenly
// bound VAO This also attaches the position VBO to the VAO
glVertexAttribPointer(POS_ATTRIB_IDX, // What attibute index will this array feed in the vertex shader (see buildProgram)
model->positionSize, // How many elements are there per position?
model->positionType, // What is the type of this data?
GL_FALSE, // Do we want to normalize this data (0-1 range for fixed-pont types)
model->positionSize*posTypeSize, // What is the stride (i.e. bytes between positions)?
0); // What is the offset in the VBO to the position data?
glEnableVertexAttribArray(POS_ATTRIB_IDX);
// Set up parmeters for texcoord attribute in the VAO including, size, type, stride, and offset in the currenly
// bound VAO This also attaches the texcoord VBO to VAO
glBindBuffer(GL_ARRAY_BUFFER, texcoordBufferName);
glVertexAttribPointer(TEXCOORD_ATTRIB_IDX, // What attibute index will this array feed in the vertex shader (see buildProgram)
model->texcoordSize, // How many elements are there per texture coord?
model->texcoordType, // What is the type of this data in the array?
GL_TRUE, // Do we want to normalize this data (0-1 range for fixed-point types)
model->texcoordSize*texcoordTypeSize,// What is the stride (i.e. bytes between texcoords)?
0); // What is the offset in the VBO to the texcoord data?
glEnableVertexAttribArray(TEXCOORD_ATTRIB_IDX);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferName);
#endif
glUniform1f(alphaValue, 1.0);
// Draw the object
glDrawElements(GL_TRIANGLES, model->numElements, model->elementType, 0);
GL_ERRLOG("gltouchjoy render");
}
static void gltouchjoy_render(void) {
if (!isAvailable) {
return;
}
if (!isEnabled) {
return;
}
if (!isVisible) {
return;
}
glViewport(0, 0, viewportWidth, viewportHeight);
glActiveTexture(TEXTURE_ACTIVE_TOUCHJOY_AXIS);
glBindTexture(GL_TEXTURE_2D, touchAxisObjTextureName);
if (axisTextureDirty) {
axisTextureDirty = false;
glTexImage2D(GL_TEXTURE_2D, /*level*/0, /*internal format*/GL_RGBA, TOUCHJOY_FB_WIDTH, TOUCHJOY_FB_HEIGHT, /*border*/0, /*format*/GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)touchAxisObjPixels);
}
glUniform1i(uniformTex2Use, TEXTURE_ID_TOUCHJOY_AXIS);
_render_object(touchAxisObjModel, touchAxisObjVAOName, touchAxisObjPosBufferName, touchAxisObjTexcoordBufferName, touchAxisObjElementBufferName);
glActiveTexture(TEXTURE_ACTIVE_TOUCHJOY_BUTTON);
glBindTexture(GL_TEXTURE_2D, buttonObjTextureName);
if (buttonTextureDirty) {
buttonTextureDirty = false;
glTexImage2D(GL_TEXTURE_2D, /*level*/0, /*internal format*/GL_RGBA, TOUCHJOY_FB_WIDTH, TOUCHJOY_FB_HEIGHT, /*border*/0, /*format*/GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)buttonObjPixels);
}
glUniform1i(uniformTex2Use, TEXTURE_ID_TOUCHJOY_BUTTON);
_render_object(buttonObjModel, buttonObjVAOName, buttonObjPosBufferName, buttonObjTexcoordBufferName, buttonObjElementBufferName);
}
static void gltouchjoy_reshape(int w, int h) {
LOG("gltouchjoy_reshape(%d, %d)", w, h);
if (w > viewportWidth) {
viewportWidth = w;
}
if (h > viewportHeight) {
viewportHeight = h;
}
}
static void gltouchjoy_resetJoystick(void) {
// no-op
}
static inline bool _is_point_on_axis(float x, float y) {
return (x >= touchAxisObjModelScreenX && x <= touchAxisObjModelScreenXMax && y >= touchAxisObjModelScreenY && y <= touchAxisObjModelScreenYMax);
}
static inline bool _is_point_on_button0(float x, float y) {
return (x >= buttonObj0ScreenX && x <= buttonObj0ScreenXMax && y >= buttonObj0ScreenY && y <= buttonObj0ScreenYMax);
}
static inline bool _is_point_on_button1(float x, float y) {
return (x >= buttonObj1ScreenX && x <= buttonObj1ScreenXMax && y >= buttonObj1ScreenY && y <= buttonObj1ScreenYMax);
}
static inline void _move_joystick_axis(float x, float y) {
int buttonW = touchAxisObjModelScreenXMax - touchAxisObjModelScreenX;
float halfJoyX = buttonW/2.f;
int buttonH = touchAxisObjModelScreenYMax - touchAxisObjModelScreenY;
float halfJoyY = buttonH/2.f;
float x_mod = 256.f/buttonW;
float y_mod = 256.f/buttonH;
float x0 = (x - touchAxisObjModelScreenX) * x_mod;
float y0 = (y - touchAxisObjModelScreenY) * y_mod;
joy_x = (uint16_t)x0;
if (joy_x > 0xff) {
joy_x = 0xff;
}
joy_y = (uint16_t)y0;
if (joy_y > 0xff) {
joy_y = 0xff;
}
LOG("\tjoystick : (%d,%d)", joy_x, joy_y);
}
static bool gltouchjoy_onTouchEvent(joystick_touch_event_t action, int pointer_count, int pointer_idx, float *x_coords, float *y_coords) {
if (!isAvailable) {
return false;
}
if (!isEnabled) {
return false;
}
bool axisConsumed = false;
bool buttonConsumed = false;
float x = x_coords[pointer_idx];
float y = y_coords[pointer_idx];
switch (action) {
case TOUCH_DOWN:
LOG("---TOUCH DOWN");
case TOUCH_POINTER_DOWN:
if (action == TOUCH_POINTER_DOWN) {
LOG("---TOUCH POINTER DOWN");
}
if (_is_point_on_axis(x, y)) {
if (trackingAxisIndex >= 0) {
// already tracking a different pointer for the axis ...
axisConsumed = true;
trackingAxisIndex = pointer_idx;
LOG("\taxis event : saw %d but already tracking %d", pointer_idx, trackingAxisIndex);
_move_joystick_axis(x, y);
} else {
axisConsumed = true;
trackingAxisIndex = pointer_idx;
LOG("\taxis event : begin tracking %d", trackingAxisIndex);
_move_joystick_axis(x, y);
}
} else {
bool isOn0 = _is_point_on_button0(x, y);
bool isOn1 = _is_point_on_button1(x, y);
if (isOn0 && isOn1) {
trackingButton0Index = TOUCHED_NONE;
trackingButton1Index = TOUCHED_NONE;
trackingButtonBothIndex = pointer_idx;
buttonConsumed = true;
joy_button0 = 0x80;
joy_button1 = 0x80;
LOG("\tbutton0&1 event : index:%d joy_button0:%02X joy_button1:%02X", pointer_idx, joy_button0, joy_button1);
} else if (isOn0) {
trackingButton0Index = pointer_idx;
trackingButton1Index = TOUCHED_NONE;
trackingButtonBothIndex = TOUCHED_NONE;
buttonConsumed = true;
joy_button0 = 0x80;
joy_button1 = 0x0;
LOG("\tbutton0 event : index:%d joy_button0:%02X", pointer_idx, joy_button0);
} else if (isOn1) {
trackingButton0Index = TOUCHED_NONE;
trackingButton1Index = pointer_idx;
trackingButtonBothIndex = TOUCHED_NONE;
buttonConsumed = true;
joy_button0 = 0x0;
joy_button1 = 0x80;
LOG("\tbutton1 event : index:%d joy_button1:%02X", pointer_idx, joy_button1);
}
}
break;
case TOUCH_MOVE:
LOG("---TOUCH MOVE");
if (trackingAxisIndex >= 0) {
axisConsumed = true;
x = x_coords[trackingAxisIndex];
y = y_coords[trackingAxisIndex];
LOG("\t...tracking axis:%d (count:%d)", trackingAxisIndex, pointer_count);
_move_joystick_axis(x, y);
}
break;
case TOUCH_UP:
LOG("---TOUCH UP");
case TOUCH_POINTER_UP:
if (action == TOUCH_POINTER_UP) {
LOG("---TOUCH POINTER UP");
}
if (pointer_idx == trackingAxisIndex) {
axisConsumed = true;
trackingAxisIndex = TOUCHED_NONE;
joy_x = HALF_JOY_RANGE;
joy_y = HALF_JOY_RANGE;
LOG("\taxis went up");
} else if (pointer_idx == trackingButtonBothIndex) {
buttonConsumed = true;
trackingButtonBothIndex = TOUCHED_NONE;
joy_button0 = 0x0;
joy_button1 = 0x0;
LOG("\tbuttons up joy_button0:%02X joy_button1:%02X", joy_button0, joy_button1);
} else if (pointer_idx == trackingButton0Index) {
buttonConsumed = true;
trackingButton0Index = TOUCHED_NONE;
joy_button0 = 0x0;
LOG("\tbutton0 up joy_button0:%02X", joy_button0);
} else if (pointer_idx == trackingButton1Index) {
buttonConsumed = true;
trackingButton1Index = TOUCHED_NONE;
joy_button1 = 0x0;
LOG("\tbutton1 up joy_button1:%02X", joy_button1);
}
break;
case TOUCH_CANCEL:
LOG("---TOUCH CANCEL");
trackingAxisIndex = TOUCHED_NONE;
trackingButton0Index = TOUCHED_NONE;
trackingButton1Index = TOUCHED_NONE;
trackingButtonBothIndex = TOUCHED_NONE;
joy_button0 = 0x0;
joy_button1 = 0x0;
joy_x = HALF_JOY_RANGE;
joy_y = HALF_JOY_RANGE;
break;
default:
LOG("gltouchjoy saw unknown touch event : %d", action);
break;
}
if (axisConsumed || buttonConsumed) {
LOG("\tconsumed event");
return true;
} else {
LOG("\tDID NOT consume...");
return false;
}
}
static bool gltouchjoy_isTouchJoystickAvailable(void) {
return isAvailable;
}
static void gltouchjoy_setTouchJoyEnabled(bool enabled) {
isEnabled = enabled;
}
void gltouchjoy_setTouchButtonValues(char button0Val, char button1Val) {
button0Char = button0Val;
button1Char = button1Val;
_setup_button_object();
}
void gltouchjoy_setTouchAxisType(touchjoy_axis_type_t axisType) {
touchjoy_axisType = axisType;
_setup_axis_object();
}
void gltouchjoy_setTouchAxisValues(char up, char left, char right, char down) {
upChar = up;
leftChar = left;
rightChar = right;
downChar = down;
if (touchjoy_axisType == AXIS_EMULATED_KEYBOARD) {
_setup_axis_object();
}
}
__attribute__((constructor))
static void _init_gltouchjoy(void) {
LOG("Registering OpenGL software touch joystick");
joydriver_onTouchEvent = &gltouchjoy_onTouchEvent;
joydriver_isTouchJoystickAvailable = &gltouchjoy_isTouchJoystickAvailable;
joydriver_setTouchJoyEnabled = &gltouchjoy_setTouchJoyEnabled;
joydriver_setTouchButtonValues = &gltouchjoy_setTouchButtonValues;
joydriver_setTouchAxisType = &gltouchjoy_setTouchAxisType;
joydriver_setTouchAxisValues = &gltouchjoy_setTouchAxisValues;
touchjoyAnimation.ctor = &gltouchjoy_init;
touchjoyAnimation.dtor = &gltouchjoy_destroy;
touchjoyAnimation.render = &gltouchjoy_render;
touchjoyAnimation.reshape = &gltouchjoy_reshape;
gldriver_register_animation(&touchjoyAnimation);
}
void gldriver_joystick_reset(void) {
#warning FIXME
#warning TODO
#warning expunge
#warning this
#warning API
#warning ...
}

View File

@ -476,6 +476,22 @@ static GLuint _build_program(demoSource *vertexSource, demoSource *fragmentSourc
glUniform1i(messageSamplerLoc, TEXTURE_ID_MESSAGE);
}
#if TOUCH_JOYSTICK
GLint axisSamplerLoc = glGetUniformLocation(prgName, "axisTexture");
if (axisSamplerLoc < 0) {
LOG("OOPS, no axisSamplerLoc shader : %d", axisSamplerLoc);
} else {
glUniform1i(axisSamplerLoc, TEXTURE_ID_TOUCHJOY_AXIS);
}
GLint buttonSamplerLoc = glGetUniformLocation(prgName, "buttonTexture");
if (buttonSamplerLoc < 0) {
LOG("OOPS, no buttonSamplerLoc shader : %d", buttonSamplerLoc);
} else {
glUniform1i(buttonSamplerLoc, TEXTURE_ID_TOUCHJOY_BUTTON);
}
#endif
uniformMVPIdx = glGetUniformLocation(prgName, "modelViewProjectionMatrix");
if (uniformMVPIdx < 0) {
LOG("OOPS, no modelViewProjectionMatrix in shader : %d", uniformMVPIdx);
@ -799,6 +815,9 @@ static void gldriver_reshape(int w, int h) {
#endif
glViewport(viewportX, viewportY, viewportWidth, viewportHeight);
// Prep any other objects/animations
gldriver_animation_reshape(w, h);
}
#if USE_GLUT

View File

@ -44,11 +44,19 @@ enum {
enum {
TEXTURE_ID_FRAMEBUFFER=0,
TEXTURE_ID_MESSAGE,
#if TOUCH_JOYSTICK
TEXTURE_ID_TOUCHJOY_AXIS,
TEXTURE_ID_TOUCHJOY_BUTTON,
#endif
};
enum {
TEXTURE_ACTIVE_FRAMEBUFFER = GL_TEXTURE0,
TEXTURE_ACTIVE_MESSAGE = GL_TEXTURE1,
TEXTURE_ACTIVE_FRAMEBUFFER = GL_TEXTURE0,
TEXTURE_ACTIVE_MESSAGE = GL_TEXTURE1,
#if TOUCH_JOYSTICK
TEXTURE_ACTIVE_TOUCHJOY_AXIS = GL_TEXTURE2,
TEXTURE_ACTIVE_TOUCHJOY_BUTTON = GL_TEXTURE3,
#endif
};
static inline GLsizei _get_gl_type_size(GLenum type) {