mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-02-07 04:31:50 +00:00
REFACTOR : begin consolidating common code for OpenGL HUD interfaces
This commit is contained in:
parent
5712850e84
commit
e876cd03b6
@ -10,6 +10,9 @@ android {
|
||||
targetSdkVersion 10
|
||||
versionCode 1
|
||||
versionName "0.9.1"
|
||||
ndk {
|
||||
moduleName "apple2ix"
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
release {
|
||||
@ -27,6 +30,7 @@ android {
|
||||
}
|
||||
debug {
|
||||
debuggable true
|
||||
jniDebuggable true
|
||||
}
|
||||
}
|
||||
productFlavors {
|
||||
|
@ -59,10 +59,15 @@
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
// custom annotations
|
||||
#define INPARM
|
||||
#define OUTPARM
|
||||
#define INOUT
|
||||
|
||||
#if VIDEO_OPENGL
|
||||
#include "video_util/glUtil.h"
|
||||
#define CRASH_APP_ON_LOAD_BECAUSE_YAY_GJ_APPLE 0
|
||||
// 2014/11/29 -- Yay GJ Apple! ... you would think that early app lifecycle calls to glGetError() would not segfault on Macs
|
||||
// 2015/04/01 ... early calls to glGetError()--before a context exists--causes segfaults on MacOS X
|
||||
extern bool safe_to_do_opengl_logging;
|
||||
static inline GLenum safeGLGetError(void) {
|
||||
if (safe_to_do_opengl_logging) {
|
||||
|
@ -64,7 +64,7 @@ extern void (*joydriver_setTouchButtonValues)(char button0Val, char button1Val);
|
||||
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);
|
||||
extern void (*joydriver_setTouchAxisValues)(char north, char west, char east, char south);
|
||||
|
||||
#endif // TOUCH_JOYSTICK
|
||||
|
||||
|
@ -73,8 +73,8 @@ static void _create_message_model(void) {
|
||||
messageObj->positionSize = 4; // x,y,z coordinates
|
||||
messageObj->positionArraySize = sizeof(messageObj_positions);
|
||||
|
||||
messageObj->texcoords = malloc(sizeof(messageObj_texcoords));
|
||||
memcpy(messageObj->texcoords, &messageObj_texcoords[0], sizeof(messageObj_texcoords));
|
||||
messageObj->texCoords = malloc(sizeof(messageObj_texcoords));
|
||||
memcpy(messageObj->texCoords, &messageObj_texcoords[0], sizeof(messageObj_texcoords));
|
||||
messageObj->texcoordType = GL_FLOAT;
|
||||
messageObj->texcoordSize = 2; // s,t coordinates
|
||||
messageObj->texcoordArraySize = sizeof(messageObj_texcoords);
|
||||
@ -89,7 +89,7 @@ static void _create_message_model(void) {
|
||||
messageObj->elementType = GL_UNSIGNED_SHORT;
|
||||
messageObj->elementArraySize = sizeof(indices);
|
||||
|
||||
mdlDestroyModel(cpuMessageObjModel);
|
||||
mdlDestroyModel(&cpuMessageObjModel);
|
||||
cpuMessageObjModel = messageObj;
|
||||
}
|
||||
|
||||
@ -124,13 +124,13 @@ static void _create_message_VAO_VBOs(const GLModel *messageModel, GLuint *messag
|
||||
0); // What is the offset in the VBO to the position data?
|
||||
#endif
|
||||
|
||||
if (messageModel->texcoords) {
|
||||
if (messageModel->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, messageModel->texcoordArraySize, messageModel->texcoords, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, messageModel->texcoordArraySize, messageModel->texCoords, GL_STATIC_DRAW);
|
||||
|
||||
#if USE_VAO
|
||||
// Enable the texcoord attribute for this VAO
|
||||
@ -269,7 +269,7 @@ static void cpuanim_destroy(void) {
|
||||
cpuMessageObjTexcoordBufferName = UNINITIALIZED_GL;
|
||||
cpuMessageObjElementBufferName = UNINITIALIZED_GL;
|
||||
|
||||
mdlDestroyModel(cpuMessageObjModel);
|
||||
mdlDestroyModel(&cpuMessageObjModel);
|
||||
cpuMessageObjModel = NULL;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include "common.h"
|
||||
#include "video/glvideo.h"
|
||||
|
||||
#define MODEL_DEPTH -0.03125
|
||||
|
||||
#define AXIS_TEMPLATE_COLS 5
|
||||
#define AXIS_TEMPLATE_ROWS 5
|
||||
|
||||
@ -45,6 +47,8 @@ enum {
|
||||
TOUCHED_BOTH,
|
||||
};
|
||||
|
||||
// general configurations
|
||||
|
||||
static bool isAvailable = false;
|
||||
static bool isEnabled = true;
|
||||
static bool isVisible = true;
|
||||
@ -66,6 +70,7 @@ static glanim_t touchjoyAnimation = { 0 };
|
||||
static int viewportWidth = 0;
|
||||
static int viewportHeight = 0;
|
||||
|
||||
#warning FIXME TODO ... consolidate these into internal structs ....
|
||||
static int axisSideX = 0;
|
||||
static int axisSideXMax = 0;
|
||||
static int axisSideY = 0;
|
||||
@ -79,250 +84,47 @@ static int buttSideYMax = 0;
|
||||
// touch axis variables
|
||||
|
||||
static GLModel *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 uint8_t touchAxisObjFB[AXIS_FB_WIDTH * AXIS_FB_HEIGHT] = { 0 };
|
||||
static uint8_t touchAxisObjPixels[AXIS_FB_WIDTH * AXIS_FB_HEIGHT * 4] = { 0 };// RGBA8888
|
||||
static bool axisTextureDirty = true;
|
||||
static bool axisModelDirty = true;
|
||||
|
||||
static int axisCenterX = 480;
|
||||
static int axisCenterY = 320;
|
||||
static int axisCenterX = 240;
|
||||
static int axisCenterY = 160;
|
||||
static int trackingAxisIndex = TOUCHED_NONE;
|
||||
static struct timespec axisTimingBegin = { 0 };
|
||||
|
||||
static touchjoy_axis_type_t touchjoy_axisType = AXIS_EMULATED_DEVICE;
|
||||
static uint8_t northChar = MOUSETEXT_UP;
|
||||
static uint8_t westChar = MOUSETEXT_LEFT;
|
||||
static uint8_t eastChar = MOUSETEXT_RIGHT;
|
||||
static uint8_t southChar = MOUSETEXT_DOWN;
|
||||
|
||||
// button object variables
|
||||
|
||||
static GLModel *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 uint8_t buttonObjFB[BUTTON_FB_WIDTH * BUTTON_FB_HEIGHT] = { 0 };
|
||||
static uint8_t buttonObjPixels[BUTTON_FB_WIDTH * BUTTON_FB_HEIGHT * 4] = { 0 };// RGBA8888
|
||||
static bool buttonTextureDirty = true;
|
||||
static bool buttonModelDirty = true;
|
||||
|
||||
static int buttonCenterX = 480;
|
||||
static int buttonCenterY = 320;
|
||||
static int buttonCenterX = 240;
|
||||
static int buttonCenterY = 160;
|
||||
static int trackingButtonIndex = TOUCHED_NONE;
|
||||
static int touchDownButton = TOUCHED_BUTTON0;
|
||||
static int upButtonAxisButton = TOUCHED_BOTH;
|
||||
static int downButtonAxisButton = TOUCHED_BUTTON1;
|
||||
static int buttonSwitchThreshold = BUTTON_SWITCH_THRESHOLD_DEFAULT;
|
||||
static struct timespec buttonTimingBegin = { 0 };
|
||||
|
||||
// configurables for current touchjoy
|
||||
static int touchDownButton = TOUCHED_BUTTON0;
|
||||
static int northButton = TOUCHED_BOTH;
|
||||
static int southButton = TOUCHED_BUTTON1;
|
||||
|
||||
static uint8_t button0Char = MOUSETEXT_OPENAPPLE;
|
||||
static uint8_t buttonActiveChar = MOUSETEXT_OPENAPPLE;
|
||||
static uint8_t button1Char = MOUSETEXT_CLOSEDAPPLE;
|
||||
static uint8_t buttonBothChar = '+';
|
||||
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 uint8_t buttonActiveChar = MOUSETEXT_OPENAPPLE;
|
||||
static int buttonSwitchThreshold = BUTTON_SWITCH_THRESHOLD_DEFAULT;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static GLModel *_create_model(GLfloat skew_x, GLfloat skew_y, GLfloat obj_w, GLfloat obj_h) {
|
||||
|
||||
/* 2...3
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* 0...1
|
||||
*/
|
||||
|
||||
const GLfloat obj_positions[] = {
|
||||
skew_x, skew_y, -0.03125, 1.0,
|
||||
skew_x+obj_w, skew_y, -0.03125, 1.0,
|
||||
skew_x, skew_y+obj_h, -0.03125, 1.0,
|
||||
skew_x+obj_w, skew_y+obj_h, -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
|
||||
};
|
||||
|
||||
GLModel *obj = calloc(1, sizeof(GLModel));
|
||||
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 GLModel *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_DYNAMIC_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_DYNAMIC_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_DYNAMIC_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, int w, int h) {
|
||||
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, w, h, /*border*/0, /*format*/GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
GL_ERRLOG("gltouchjoy texture");
|
||||
|
||||
return texName;
|
||||
}
|
||||
|
||||
static void _setup_object(char *submenu, unsigned int cols, unsigned int rows, uint8_t *fb, unsigned int fb_w, unsigned int fb_h, uint8_t *pixels) {
|
||||
|
||||
// render template into indexed fb
|
||||
@ -347,18 +149,18 @@ static void _setup_object(char *submenu, unsigned int cols, unsigned int rows, u
|
||||
}
|
||||
|
||||
static void _setup_axis_object(void) {
|
||||
axisTemplate[0][2] = upChar;
|
||||
axisTemplate[2][0] = leftChar;
|
||||
axisTemplate[2][4] = rightChar;
|
||||
axisTemplate[4][2] = downChar;
|
||||
_setup_object(axisTemplate[0], AXIS_TEMPLATE_COLS, AXIS_TEMPLATE_ROWS, touchAxisObjFB, AXIS_FB_WIDTH, AXIS_FB_HEIGHT, touchAxisObjPixels);
|
||||
axisTextureDirty = true;
|
||||
axisTemplate[0][2] = northChar;
|
||||
axisTemplate[2][0] = westChar;
|
||||
axisTemplate[2][4] = eastChar;
|
||||
axisTemplate[4][2] = southChar;
|
||||
_setup_object(axisTemplate[0], AXIS_TEMPLATE_COLS, AXIS_TEMPLATE_ROWS, touchAxisObjFB, AXIS_FB_WIDTH, AXIS_FB_HEIGHT, touchAxisObjModel->texPixels);
|
||||
touchAxisObjModel->texDirty = true;
|
||||
}
|
||||
|
||||
static void _setup_button_object(void) {
|
||||
buttonTemplate[0][0] = buttonActiveChar;
|
||||
_setup_object(buttonTemplate[0], BUTTON_TEMPLATE_COLS, BUTTON_TEMPLATE_ROWS, buttonObjFB, BUTTON_FB_WIDTH, BUTTON_FB_HEIGHT, buttonObjPixels);
|
||||
buttonTextureDirty = true;
|
||||
_setup_object(buttonTemplate[0], BUTTON_TEMPLATE_COLS, BUTTON_TEMPLATE_ROWS, buttonObjFB, BUTTON_FB_WIDTH, BUTTON_FB_HEIGHT, buttonObjModel->texPixels);
|
||||
buttonObjModel->texDirty = true;
|
||||
}
|
||||
|
||||
static inline void _screen_to_model(float x, float y, float *screenX, float *screenY) {
|
||||
@ -373,12 +175,7 @@ static void _model_to_screen(float screenCoords[4], GLModel *model) {
|
||||
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)
|
||||
#warning NOTE: we possibly should use matrix calculations (but assuming HUD elements are 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);
|
||||
@ -399,7 +196,6 @@ static void _model_to_screen(float screenCoords[4], GLModel *model) {
|
||||
y1 = y;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// OpenGL screen origin is bottom-left (Android is top-left)
|
||||
float yFlip0 = viewportHeight - (y1 * viewportHeight);
|
||||
@ -414,49 +210,28 @@ static void _model_to_screen(float screenCoords[4], GLModel *model) {
|
||||
static void gltouchjoy_init(void) {
|
||||
LOG("gltouchjoy_init ...");
|
||||
|
||||
mdlDestroyModel(touchAxisObjModel);
|
||||
mdlDestroyModel(buttonObjModel);
|
||||
mdlDestroyModel(&touchAxisObjModel);
|
||||
mdlDestroyModel(&buttonObjModel);
|
||||
|
||||
touchAxisObjModel = _create_model(-1.05, -1.0, AXIS_OBJ_W, AXIS_OBJ_H);
|
||||
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)
|
||||
{
|
||||
touchAxisObjModel = mdlCreateQuad(-1.05, -1.0, AXIS_OBJ_W, AXIS_OBJ_H, MODEL_DEPTH, AXIS_FB_WIDTH, AXIS_FB_HEIGHT, GL_RGBA); // RGBA8888
|
||||
if (!touchAxisObjModel) {
|
||||
LOG("gltouchjoy not initializing axis");
|
||||
return;
|
||||
}
|
||||
|
||||
touchAxisObjTextureName = _create_texture(touchAxisObjPixels, AXIS_FB_WIDTH, AXIS_FB_HEIGHT);
|
||||
if (touchAxisObjTextureName == UNINITIALIZED_GL) {
|
||||
LOG("gltouchjoy not initializing axis: texture error");
|
||||
return;
|
||||
}
|
||||
_setup_axis_object();
|
||||
|
||||
// button object
|
||||
|
||||
buttonObjModel = _create_model(1.05-BUTTON_OBJ_W, -1.0, BUTTON_OBJ_W, BUTTON_OBJ_H);
|
||||
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)
|
||||
{
|
||||
buttonObjModel = mdlCreateQuad(1.05-BUTTON_OBJ_W, -1.0, BUTTON_OBJ_W, BUTTON_OBJ_H, MODEL_DEPTH, BUTTON_FB_WIDTH, BUTTON_FB_HEIGHT, GL_RGBA); // RGBA8888
|
||||
if (!buttonObjModel) {
|
||||
LOG("gltouchjoy not initializing buttons");
|
||||
return;
|
||||
}
|
||||
|
||||
buttonObjTextureName = _create_texture(buttonObjPixels, BUTTON_FB_WIDTH, BUTTON_FB_HEIGHT);
|
||||
if (buttonObjTextureName == UNINITIALIZED_GL) {
|
||||
LOG("not initializing buttons: texture error");
|
||||
return;
|
||||
}
|
||||
_setup_button_object();
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &axisTimingBegin);
|
||||
clock_gettime(CLOCK_MONOTONIC, &buttonTimingBegin);
|
||||
|
||||
isAvailable = true;
|
||||
}
|
||||
|
||||
@ -468,34 +243,17 @@ static void gltouchjoy_destroy(void) {
|
||||
|
||||
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;
|
||||
mdlDestroyModel(&touchAxisObjModel);
|
||||
mdlDestroyModel(&buttonObjModel);
|
||||
}
|
||||
|
||||
static void _render_object(GLModel *model, GLuint vaoName, GLuint posBufferName, GLuint texcoordBufferName, GLuint elementBufferName) {
|
||||
static void _render_object(GLModel *model) {
|
||||
|
||||
// Bind our vertex array object
|
||||
#if USE_VAO
|
||||
glBindVertexArray(vaoName);
|
||||
glBindVertexArray(model->vaoName);
|
||||
#else
|
||||
glBindBuffer(GL_ARRAY_BUFFER, posBufferName);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->posBufferName);
|
||||
|
||||
GLsizei posTypeSize = _get_gl_type_size(model->positionType);
|
||||
GLsizei texcoordTypeSize = _get_gl_type_size(model->texcoordType);
|
||||
@ -512,7 +270,7 @@ static void _render_object(GLModel *model, GLuint vaoName, GLuint posBufferName,
|
||||
|
||||
// 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);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->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?
|
||||
@ -521,11 +279,11 @@ static void _render_object(GLModel *model, GLuint vaoName, GLuint posBufferName,
|
||||
0); // What is the offset in the VBO to the texcoord data?
|
||||
glEnableVertexAttribArray(TEXCOORD_ATTRIB_IDX);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferName);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->elementBufferName);
|
||||
#endif
|
||||
|
||||
// Draw the object
|
||||
glDrawElements(GL_TRIANGLES, model->numElements, model->elementType, 0);
|
||||
glDrawElements(model->primType, model->numElements, model->elementType, 0);
|
||||
GL_ERRLOG("gltouchjoy render");
|
||||
}
|
||||
|
||||
@ -540,6 +298,7 @@ static void gltouchjoy_render(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE : show these HUD elements beyond the framebuffer dimensions
|
||||
glViewport(0, 0, viewportWidth, viewportHeight);
|
||||
|
||||
struct timespec now = { 0 };
|
||||
@ -564,18 +323,18 @@ static void gltouchjoy_render(void) {
|
||||
glUniform1f(alphaValue, alpha);
|
||||
|
||||
glActiveTexture(TEXTURE_ACTIVE_TOUCHJOY_AXIS);
|
||||
glBindTexture(GL_TEXTURE_2D, touchAxisObjTextureName);
|
||||
if (axisTextureDirty) {
|
||||
axisTextureDirty = false;
|
||||
glTexImage2D(GL_TEXTURE_2D, /*level*/0, /*internal format*/GL_RGBA, AXIS_FB_WIDTH, AXIS_FB_HEIGHT, /*border*/0, /*format*/GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)touchAxisObjPixels);
|
||||
glBindTexture(GL_TEXTURE_2D, touchAxisObjModel->textureName);
|
||||
if (touchAxisObjModel->texDirty) {
|
||||
touchAxisObjModel->texDirty = false;
|
||||
glTexImage2D(GL_TEXTURE_2D, /*level*/0, /*internal format*/GL_RGBA, AXIS_FB_WIDTH, AXIS_FB_HEIGHT, /*border*/0, /*format*/GL_RGBA, GL_UNSIGNED_BYTE, touchAxisObjModel->texPixels);
|
||||
}
|
||||
if (axisModelDirty) {
|
||||
axisModelDirty = false;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, touchAxisObjPosBufferName);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, touchAxisObjModel->posBufferName);
|
||||
glBufferData(GL_ARRAY_BUFFER, touchAxisObjModel->positionArraySize, touchAxisObjModel->positions, GL_DYNAMIC_DRAW);
|
||||
}
|
||||
glUniform1i(uniformTex2Use, TEXTURE_ID_TOUCHJOY_AXIS);
|
||||
_render_object(touchAxisObjModel, touchAxisObjVAOName, touchAxisObjPosBufferName, touchAxisObjTexcoordBufferName, touchAxisObjElementBufferName);
|
||||
_render_object(touchAxisObjModel);
|
||||
|
||||
// draw button(s)
|
||||
|
||||
@ -594,18 +353,18 @@ static void gltouchjoy_render(void) {
|
||||
glUniform1f(alphaValue, alpha);
|
||||
|
||||
glActiveTexture(TEXTURE_ACTIVE_TOUCHJOY_BUTTON);
|
||||
glBindTexture(GL_TEXTURE_2D, buttonObjTextureName);
|
||||
if (buttonTextureDirty) {
|
||||
buttonTextureDirty = false;
|
||||
glTexImage2D(GL_TEXTURE_2D, /*level*/0, /*internal format*/GL_RGBA, BUTTON_FB_WIDTH, BUTTON_FB_HEIGHT, /*border*/0, /*format*/GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)buttonObjPixels);
|
||||
glBindTexture(GL_TEXTURE_2D, buttonObjModel->textureName);
|
||||
if (buttonObjModel->texDirty) {
|
||||
buttonObjModel->texDirty = false;
|
||||
glTexImage2D(GL_TEXTURE_2D, /*level*/0, /*internal format*/GL_RGBA, BUTTON_FB_WIDTH, BUTTON_FB_HEIGHT, /*border*/0, /*format*/GL_RGBA, GL_UNSIGNED_BYTE, buttonObjModel->texPixels);
|
||||
}
|
||||
if (buttonModelDirty) {
|
||||
buttonModelDirty = false;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buttonObjPosBufferName);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buttonObjModel->posBufferName);
|
||||
glBufferData(GL_ARRAY_BUFFER, buttonObjModel->positionArraySize, buttonObjModel->positions, GL_DYNAMIC_DRAW);
|
||||
}
|
||||
glUniform1i(uniformTex2Use, TEXTURE_ID_TOUCHJOY_BUTTON);
|
||||
_render_object(buttonObjModel, buttonObjVAOName, buttonObjPosBufferName, buttonObjTexcoordBufferName, buttonObjElementBufferName);
|
||||
_render_object(buttonObjModel);
|
||||
}
|
||||
|
||||
static void gltouchjoy_reshape(int w, int h) {
|
||||
@ -701,15 +460,15 @@ static inline void _move_button_axis(int x, int y) {
|
||||
if ((y < -buttonSwitchThreshold) || (y > buttonSwitchThreshold)) {
|
||||
if (y < 0) {
|
||||
//LOG("\tbutton neg y threshold (%d)", y);
|
||||
if (upButtonAxisButton == TOUCHED_BUTTON0) {
|
||||
if (northButton == TOUCHED_BUTTON0) {
|
||||
joy_button0 = 0x80;
|
||||
joy_button1 = 0;
|
||||
_setup_button_object_with_char(button0Char);
|
||||
} else if (upButtonAxisButton == TOUCHED_BUTTON1) {
|
||||
} else if (northButton == TOUCHED_BUTTON1) {
|
||||
joy_button0 = 0;
|
||||
joy_button1 = 0x80;
|
||||
_setup_button_object_with_char(button1Char);
|
||||
} else if (upButtonAxisButton == TOUCHED_BOTH) {
|
||||
} else if (northButton == TOUCHED_BOTH) {
|
||||
joy_button0 = 0x80;
|
||||
joy_button1 = 0x80;
|
||||
_setup_button_object_with_char(buttonBothChar);
|
||||
@ -719,15 +478,15 @@ static inline void _move_button_axis(int x, int y) {
|
||||
}
|
||||
} else {
|
||||
//LOG("\tbutton pos y threshold (%d)", y);
|
||||
if (downButtonAxisButton == TOUCHED_BUTTON0) {
|
||||
if (southButton == TOUCHED_BUTTON0) {
|
||||
joy_button0 = 0x80;
|
||||
joy_button1 = 0;
|
||||
_setup_button_object_with_char(button0Char);
|
||||
} else if (downButtonAxisButton == TOUCHED_BUTTON1) {
|
||||
} else if (southButton == TOUCHED_BUTTON1) {
|
||||
joy_button0 = 0;
|
||||
joy_button1 = 0x80;
|
||||
_setup_button_object_with_char(button1Char);
|
||||
} else if (downButtonAxisButton == TOUCHED_BOTH) {
|
||||
} else if (southButton == TOUCHED_BOTH) {
|
||||
joy_button0 = 0x80;
|
||||
joy_button1 = 0x80;
|
||||
_setup_button_object_with_char(buttonBothChar);
|
||||
@ -881,11 +640,11 @@ static void gltouchjoy_setTouchAxisType(touchjoy_axis_type_t axisType) {
|
||||
_setup_axis_object();
|
||||
}
|
||||
|
||||
static void gltouchjoy_setTouchAxisValues(char up, char left, char right, char down) {
|
||||
upChar = up;
|
||||
leftChar = left;
|
||||
rightChar = right;
|
||||
downChar = down;
|
||||
static void gltouchjoy_setTouchAxisValues(char north, char west, char east, char south) {
|
||||
northChar = north;
|
||||
westChar = west;
|
||||
eastChar = east;
|
||||
southChar = south;
|
||||
if (touchjoy_axisType == AXIS_EMULATED_KEYBOARD) {
|
||||
_setup_axis_object();
|
||||
}
|
||||
@ -910,10 +669,5 @@ static void _init_gltouchjoy(void) {
|
||||
}
|
||||
|
||||
void gldriver_joystick_reset(void) {
|
||||
#warning FIXME
|
||||
#warning TODO
|
||||
#warning expunge
|
||||
#warning this
|
||||
#warning API
|
||||
#warning ...
|
||||
#warning FIXME TODO expunge this olde API ...
|
||||
}
|
||||
|
@ -96,8 +96,8 @@ static void _create_CRT_model(void) {
|
||||
crt->positionSize = 4; // x,y,z coordinates
|
||||
crt->positionArraySize = sizeof(crt_positions);
|
||||
|
||||
crt->texcoords = malloc(sizeof(crt_texcoords));
|
||||
memcpy(crt->texcoords, &crt_texcoords[0], sizeof(crt_texcoords));
|
||||
crt->texCoords = malloc(sizeof(crt_texcoords));
|
||||
memcpy(crt->texCoords, &crt_texcoords[0], sizeof(crt_texcoords));
|
||||
crt->texcoordType = GL_FLOAT;
|
||||
crt->texcoordSize = 2; // s,t coordinates
|
||||
crt->texcoordArraySize = sizeof(crt_texcoords);
|
||||
@ -112,7 +112,7 @@ static void _create_CRT_model(void) {
|
||||
crt->elementType = GL_UNSIGNED_SHORT;
|
||||
crt->elementArraySize = sizeof(indices);
|
||||
|
||||
mdlDestroyModel(crtModel);
|
||||
mdlDestroyModel(&crtModel);
|
||||
crtModel = crt;
|
||||
}
|
||||
|
||||
@ -176,13 +176,13 @@ static void _create_VAO_VBOs(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (crtModel->texcoords) {
|
||||
if (crtModel->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, crtModel->texcoordArraySize, crtModel->texcoords, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, crtModel->texcoordArraySize, crtModel->texCoords, GL_STATIC_DRAW);
|
||||
|
||||
#if USE_VAO
|
||||
// Enable the texcoord attribute for this VAO
|
||||
@ -564,7 +564,7 @@ static void gldriver_init_common(void) {
|
||||
#if USE_VAO
|
||||
// We're using VBOs we can destroy all this memory since buffers are
|
||||
// loaded into GL and we've saved anything else we need
|
||||
mdlDestroyModel(crtModel);
|
||||
mdlDestroyModel(&crtModel);
|
||||
crtModel = NULL;
|
||||
#endif
|
||||
|
||||
@ -625,7 +625,7 @@ static void gldriver_shutdown(void) {
|
||||
a2TextureName = UNINITIALIZED_GL;
|
||||
_destroy_VAO(crtVAOName);
|
||||
crtVAOName = UNINITIALIZED_GL;
|
||||
mdlDestroyModel(crtModel);
|
||||
mdlDestroyModel(&crtModel);
|
||||
crtModel = NULL;
|
||||
glDeleteProgram(program);
|
||||
program = UNINITIALIZED_GL;
|
||||
|
@ -25,7 +25,8 @@
|
||||
// VAO optimization (may not be available on all platforms)
|
||||
#ifdef ANDROID
|
||||
#include "glanimation.h"
|
||||
#warning Certain Android and Android-ish devices (*cough* Kindle *cough*) have buggy OpenGL VAO support ...
|
||||
// NOTE : 2015/04/01 ... Certain Android and Android-ish devices (*cough* Kindle *cough*) have buggy OpenGL VAO support,
|
||||
// so don't rely on it. Is it the future yet?
|
||||
#define USE_VAO 0
|
||||
#elif !defined(USE_VAO)
|
||||
#define USE_VAO 1
|
||||
|
@ -52,7 +52,7 @@ GLModel *mdlLoadModel(const char *filepathname) {
|
||||
FILE *curFile = fopen(filepathname, "r");
|
||||
|
||||
if (!curFile) {
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -60,19 +60,19 @@ GLModel *mdlLoadModel(const char *filepathname) {
|
||||
sizeRead = fread(&header, 1, sizeof(modelHeader), curFile);
|
||||
if (sizeRead != sizeof(modelHeader)) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strncmp(header.fileIdentifier, "AppleOpenGLDemoModelWWDC2010", sizeof(header.fileIdentifier))) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (header.majorVersion != 0 && header.minorVersion != 1) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -80,13 +80,13 @@ GLModel *mdlLoadModel(const char *filepathname) {
|
||||
sizeRead = fread(&toc, 1, sizeof(modelTOC), curFile);
|
||||
if (sizeRead != sizeof(modelTOC)) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (toc.attribHeaderSize > sizeof(modelAttrib)) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -94,14 +94,14 @@ GLModel *mdlLoadModel(const char *filepathname) {
|
||||
error = fseek(curFile, toc.byteElementOffset, SEEK_SET);
|
||||
if (error < 0) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sizeRead = fread(&attrib, 1, toc.attribHeaderSize, curFile);
|
||||
if (sizeRead != toc.attribHeaderSize) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ GLModel *mdlLoadModel(const char *filepathname) {
|
||||
sizeRead = fread(uiElements, 1, model->elementArraySize, curFile);
|
||||
if (sizeRead != model->elementArraySize) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -130,7 +130,7 @@ GLModel *mdlLoadModel(const char *filepathname) {
|
||||
// can't handle this model if an element is out of the UNSIGNED_INT range
|
||||
if (((GLuint *)uiElements)[elemNum] >= 0xFFFF) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ GLModel *mdlLoadModel(const char *filepathname) {
|
||||
|
||||
if (sizeRead != model->elementArraySize) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -156,7 +156,7 @@ GLModel *mdlLoadModel(const char *filepathname) {
|
||||
sizeRead = fread(&attrib, 1, toc.attribHeaderSize, curFile);
|
||||
if (sizeRead != toc.attribHeaderSize) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -164,26 +164,26 @@ GLModel *mdlLoadModel(const char *filepathname) {
|
||||
model->positionType = attrib.datatype;
|
||||
model->positionSize = attrib.sizePerElement;
|
||||
model->numVertices = attrib.numElements;
|
||||
model->positions = (GLubyte*) malloc(model->positionArraySize);
|
||||
model->positions = (GLubyte*)malloc(model->positionArraySize);
|
||||
|
||||
sizeRead = fread(model->positions, 1, model->positionArraySize, curFile);
|
||||
if (sizeRead != model->positionArraySize) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
error = fseek(curFile, toc.byteTexcoordOffset, SEEK_SET);
|
||||
if (error < 0) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sizeRead = fread(&attrib, 1, toc.attribHeaderSize, curFile);
|
||||
if (sizeRead != toc.attribHeaderSize) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -194,23 +194,23 @@ GLModel *mdlLoadModel(const char *filepathname) {
|
||||
// must have the same number of texcoords as positions
|
||||
if (model->numVertices != attrib.numElements) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
model->texcoords = (GLubyte*) malloc(model->texcoordArraySize);
|
||||
model->texCoords = (GLubyte*)malloc(model->texcoordArraySize);
|
||||
|
||||
sizeRead = fread(model->texcoords, 1, model->texcoordArraySize, curFile);
|
||||
sizeRead = fread(model->texCoords, 1, model->texcoordArraySize, curFile);
|
||||
if (sizeRead != model->texcoordArraySize) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
error = fseek(curFile, toc.byteNormalOffset, SEEK_SET);
|
||||
if (error < 0) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -218,7 +218,7 @@ GLModel *mdlLoadModel(const char *filepathname) {
|
||||
|
||||
if (sizeRead != toc.attribHeaderSize) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -229,16 +229,16 @@ GLModel *mdlLoadModel(const char *filepathname) {
|
||||
// must have the same number of normals as positions
|
||||
if (model->numVertices != attrib.numElements) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
model->normals = (GLubyte*) malloc(model->normalArraySize );
|
||||
model->normals = (GLubyte*)malloc(model->normalArraySize );
|
||||
|
||||
sizeRead = fread(model->normals, 1, model->normalArraySize , curFile);
|
||||
if (sizeRead != model->normalArraySize) {
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
mdlDestroyModel(&model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -247,7 +247,7 @@ GLModel *mdlLoadModel(const char *filepathname) {
|
||||
return model;
|
||||
}
|
||||
|
||||
GLModel *mdlLoadQuadModel() {
|
||||
GLModel *mdlLoadQuadModel(void) {
|
||||
GLfloat posArray[] = {
|
||||
-200.0f, 0.0f, -200.0f,
|
||||
200.0f, 0.0f, -200.0f,
|
||||
@ -289,8 +289,8 @@ GLModel *mdlLoadQuadModel() {
|
||||
model->texcoordType = GL_FLOAT;
|
||||
model->texcoordSize = 2;
|
||||
model->texcoordArraySize = sizeof(texcoordArray);
|
||||
model->texcoords = (GLubyte*)malloc(model->texcoordArraySize);
|
||||
memcpy(model->texcoords, texcoordArray, model->texcoordArraySize );
|
||||
model->texCoords = (GLubyte*)malloc(model->texcoordArraySize);
|
||||
memcpy(model->texCoords, texcoordArray, model->texcoordArraySize );
|
||||
|
||||
model->normalType = GL_FLOAT;
|
||||
model->normalSize = 3;
|
||||
@ -311,16 +311,288 @@ GLModel *mdlLoadQuadModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
void mdlDestroyModel(GLModel *model) {
|
||||
if (!model) {
|
||||
static void _quadCreateVAOAndVBOs(GLModel *model) {
|
||||
|
||||
// Create a vertex array object (VAO) to cache model parameters
|
||||
#if USE_VAO
|
||||
glGenVertexArrays(1, &(model->vaoName));
|
||||
glBindVertexArray(model->vaoName);
|
||||
#endif
|
||||
|
||||
// Create a vertex buffer object (VBO) to store positions and load data
|
||||
glGenBuffers(1, &(model->posBufferName));
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->posBufferName);
|
||||
glBufferData(GL_ARRAY_BUFFER, model->positionArraySize, model->positions, GL_DYNAMIC_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, &(model->texcoordBufferName));
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->texcoordBufferName);
|
||||
|
||||
// Allocate and load texcoord data into the VBO
|
||||
glBufferData(GL_ARRAY_BUFFER, model->texcoordArraySize, model->texCoords, GL_DYNAMIC_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, &(model->elementBufferName));
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->elementBufferName);
|
||||
|
||||
// Allocate and load vertex array element data into VBO
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, model->elementArraySize, model->elements, GL_DYNAMIC_DRAW);
|
||||
|
||||
GL_ERRLOG("quad creation of VAO/VBOs");
|
||||
}
|
||||
|
||||
static GLuint _quadCreateTexture(GLModel *model) {
|
||||
|
||||
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*/model->texFormat, model->texWidth, model->texHeight, /*border*/0, /*format*/model->texFormat, GL_UNSIGNED_BYTE, model->texPixels);
|
||||
|
||||
GL_ERRLOG("quad texture creation");
|
||||
|
||||
return texName;
|
||||
}
|
||||
|
||||
GLModel *mdlCreateQuad(GLfloat skew_x, GLfloat skew_y, GLfloat obj_w, GLfloat obj_h, GLfloat z, GLsizei tex_w, GLsizei tex_h, GLenum tex_format) {
|
||||
|
||||
/* 2...3
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* 0...1
|
||||
*/
|
||||
|
||||
const GLfloat obj_positions[] = {
|
||||
skew_x, skew_y, z, 1.0,
|
||||
skew_x+obj_w, skew_y, z, 1.0,
|
||||
skew_x, skew_y+obj_h, z, 1.0,
|
||||
skew_x+obj_w, skew_y+obj_h, z, 1.0,
|
||||
};
|
||||
const GLfloat obj_texcoords[] = {
|
||||
0.f, 1.f,
|
||||
1.f, 1.f,
|
||||
0.f, 0.f,
|
||||
1.f, 0.f,
|
||||
};
|
||||
const GLushort indices[] = {
|
||||
0, 1, 2, 2, 1, 3
|
||||
};
|
||||
|
||||
GLModel *model = NULL;
|
||||
|
||||
do {
|
||||
model = calloc(1, sizeof(GLModel));
|
||||
if (!model) {
|
||||
break;
|
||||
}
|
||||
model->numVertices = 4;
|
||||
model->numElements = 6;
|
||||
model->primType = GL_TRIANGLES;
|
||||
|
||||
model->positions = malloc(sizeof(obj_positions));
|
||||
if (!(model->positions)) {
|
||||
break;
|
||||
}
|
||||
memcpy(model->positions, &obj_positions[0], sizeof(obj_positions));
|
||||
model->positionType = GL_FLOAT;
|
||||
model->positionSize = 4; // x,y,z coordinates
|
||||
model->positionArraySize = sizeof(obj_positions);
|
||||
|
||||
if (tex_w > 0 && tex_h > 0) {
|
||||
model->texCoords = malloc(sizeof(obj_texcoords));
|
||||
if (!(model->texCoords)) {
|
||||
break;
|
||||
}
|
||||
memcpy(model->texCoords, &obj_texcoords[0], sizeof(obj_texcoords));
|
||||
model->texcoordType = GL_FLOAT;
|
||||
model->texcoordSize = 2; // s,t coordinates
|
||||
model->texcoordArraySize = sizeof(obj_texcoords);
|
||||
}
|
||||
|
||||
{
|
||||
// NO NORMALS for now
|
||||
model->normals = NULL;
|
||||
model->normalType = GL_NONE;
|
||||
model->normalSize = GL_NONE;
|
||||
model->normalArraySize = 0;
|
||||
}
|
||||
|
||||
model->elements = malloc(sizeof(indices));
|
||||
if (!(model->elements)) {
|
||||
break;
|
||||
}
|
||||
memcpy(model->elements, &indices[0], sizeof(indices));
|
||||
model->elementType = GL_UNSIGNED_SHORT;
|
||||
model->elementArraySize = sizeof(indices);
|
||||
|
||||
model->custom = NULL;
|
||||
|
||||
#if USE_VAO
|
||||
model->vaoName = UNINITIALIZED_GL;
|
||||
#endif
|
||||
model->posBufferName = UNINITIALIZED_GL;
|
||||
model->texcoordBufferName = UNINITIALIZED_GL;
|
||||
model->elementBufferName = UNINITIALIZED_GL;
|
||||
|
||||
_quadCreateVAOAndVBOs(model);
|
||||
if (model->posBufferName == UNINITIALIZED_GL || model->texcoordBufferName == UNINITIALIZED_GL || model->elementBufferName == UNINITIALIZED_GL) {
|
||||
LOG("Error creating model buffers!");
|
||||
break;
|
||||
}
|
||||
|
||||
model->texDirty = true;
|
||||
model->texWidth = tex_w;
|
||||
model->texHeight = tex_h;
|
||||
model->texFormat = tex_format;
|
||||
if (tex_format == GL_RGBA) {
|
||||
model->texPixels = (GLvoid *)calloc(tex_w*tex_h*4, 1);
|
||||
} else {
|
||||
ERRQUIT("non-GL_RBGA format textures untested ... FIXME!");
|
||||
}
|
||||
if (model->texPixels == NULL) {
|
||||
break;
|
||||
}
|
||||
model->textureName = _quadCreateTexture(model);
|
||||
if (model->textureName == UNINITIALIZED_GL) {
|
||||
LOG("Error creating model texture!");
|
||||
break;
|
||||
}
|
||||
|
||||
GL_ERRLOG("quad creation");
|
||||
|
||||
return model;
|
||||
} while (0);
|
||||
|
||||
ERRLOG("error in quad creation");
|
||||
if (model) {
|
||||
mdlDestroyModel(&model);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mdlDestroyModel(INOUT GLModel **model) {
|
||||
if (!model || (!*model)) {
|
||||
return;
|
||||
}
|
||||
|
||||
free(model->elements);
|
||||
free(model->positions);
|
||||
free(model->normals);
|
||||
free(model->texcoords);
|
||||
GLModel *m = *model;
|
||||
|
||||
free(model);
|
||||
FREE(m->elements);
|
||||
FREE(m->positions);
|
||||
FREE(m->normals);
|
||||
FREE(m->texCoords);
|
||||
FREE(m->texPixels);
|
||||
|
||||
if (m->textureName != UNINITIALIZED_GL) {
|
||||
glDeleteTextures(1, &(m->textureName));
|
||||
m->textureName = UNINITIALIZED_GL;
|
||||
}
|
||||
#if USE_VAO
|
||||
if (m->vaoName != UNINITIALIZED_GL) {
|
||||
glBindVertexArray(m->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, &(m->vaoName));
|
||||
}
|
||||
#else
|
||||
if (m->posBufferName != UNINITIALIZED_GL) {
|
||||
glDeleteBuffers(1, &(m->posBufferName));
|
||||
m->posBufferName = UNINITIALIZED_GL;
|
||||
}
|
||||
if (m->texcoordBufferName != UNINITIALIZED_GL) {
|
||||
glDeleteBuffers(1, &(m->texcoordBufferName));
|
||||
m->texcoordBufferName = UNINITIALIZED_GL;
|
||||
}
|
||||
if (m->elementBufferName != UNINITIALIZED_GL) {
|
||||
glDeleteBuffers(1, &(m->elementBufferName));
|
||||
m->elementBufferName = UNINITIALIZED_GL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m->custom) {
|
||||
m->custom->dtor(&(m->custom));
|
||||
}
|
||||
|
||||
FREE(*model);
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,15 @@
|
||||
#ifndef __MODEL_UTIL_H__
|
||||
#define __MODEL_UTIL_H__
|
||||
|
||||
#include "glUtil.h"
|
||||
#include "common.h"
|
||||
|
||||
#define UNINITIALIZED_GL 31337
|
||||
|
||||
typedef struct GLCustom {
|
||||
void (*dtor)(INOUT struct GLCustom **custom); // custom data destructor
|
||||
// overridden objects must at least implement interface methods
|
||||
} GLCustom;
|
||||
|
||||
typedef struct GLModel {
|
||||
GLuint numVertices;
|
||||
|
||||
@ -26,7 +31,7 @@ typedef struct GLModel {
|
||||
GLuint positionSize;
|
||||
GLsizei positionArraySize;
|
||||
|
||||
GLvoid *texcoords;
|
||||
GLvoid *texCoords;
|
||||
GLenum texcoordType;
|
||||
GLuint texcoordSize;
|
||||
GLsizei texcoordArraySize;
|
||||
@ -41,14 +46,33 @@ typedef struct GLModel {
|
||||
GLuint numElements;
|
||||
GLsizei elementArraySize;
|
||||
|
||||
GLsizei texWidth;
|
||||
GLsizei texHeight;
|
||||
GLsizei texFormat;
|
||||
GLvoid *texPixels;
|
||||
bool texDirty;
|
||||
|
||||
GLenum primType;
|
||||
|
||||
// GL generated data
|
||||
#if USE_VAO
|
||||
GLuint vaoName;
|
||||
#endif
|
||||
GLuint textureName;
|
||||
GLuint posBufferName;
|
||||
GLuint texcoordBufferName;
|
||||
GLuint elementBufferName;
|
||||
|
||||
// Custom
|
||||
GLCustom *custom;
|
||||
} GLModel;
|
||||
|
||||
GLModel *mdlLoadModel(const char *filepathname);
|
||||
|
||||
GLModel *mdlLoadQuadModel();
|
||||
|
||||
void mdlDestroyModel(GLModel *model);
|
||||
GLModel *mdlCreateQuad(GLfloat skew_x, GLfloat skew_y, GLfloat obj_w, GLfloat obj_h, GLfloat z, GLsizei tex_w, GLsizei tex_h, GLenum tex_format);
|
||||
|
||||
void mdlDestroyModel(INOUT GLModel **model);
|
||||
|
||||
#endif //__MODEL_UTIL_H__
|
||||
|
Loading…
x
Reference in New Issue
Block a user