REFACTOR : interface menus/HUDs

- menu/HUD creation functions moved to better location and renamed
    - CPU change animation now default displays on desktop Linux (exercise common HUD codepaths with mobile)
This commit is contained in:
Aaron Culliney 2015-04-12 14:20:17 -07:00
parent 121e250c62
commit 5b5c6fa533
14 changed files with 230 additions and 242 deletions

View File

@ -39,6 +39,7 @@ VIDEO_SRC = \
src/video/glvideo.c \
src/video/glanimation.c \
src/video/glcpuanim.c \
src/video/glhudmodel.c \
src/video/glutinput.c \
src/video_util/matrixUtil.c \
src/video_util/modelUtil.c \

View File

@ -170,7 +170,7 @@ AC_ARG_ENABLE([opengl], AS_HELP_STRING([--disable-opengl], [Disable OpenGL video
opengl_supported='yes'
AC_DEFINE(VIDEO_OPENGL, 1, [Use OpenGL])
AC_DEFINE(USE_GLUT, 1, [Use GLUT library])
VIDEO_O="src/video/glvideo.o src/video/glanimation.o src/video/glcpuanim.o src/video/glutinput.o src/video_util/matrixUtil.o src/video_util/modelUtil.o src/video_util/sourceUtil.o src/video_util/vectorUtil.o"
VIDEO_O="src/video/glvideo.o src/video/glanimation.o src/video/glcpuanim.o src/video/glhudmodel.o src/video/glutinput.o src/video_util/matrixUtil.o src/video_util/modelUtil.o src/video_util/sourceUtil.o src/video_util/vectorUtil.o"
AC_MSG_RESULT([Building emulator with OpenGL support, w00t!])
], [
AC_MSG_WARN([Did not find OpenGL GLEW library...])

View File

@ -719,9 +719,9 @@ GLUE_C_WRITE(video__write_2e_text1_mixed)
}
// ----------------------------------------------------------------------------
// interface/messages plotting
// Classic interface and printing HUD messages
void video_load_interface_fonts(void) {
static void _load_interface_fonts(void) {
video_loadfont_int(0x00,0x40,ucase_glyphs);
video_loadfont_int(0x40,0x20,ucase_glyphs);
video_loadfont_int(0x60,0x20,lcase_glyphs);
@ -732,146 +732,21 @@ void video_load_interface_fonts(void) {
video_loadfont_int(MOUSETEXT_BEGIN,0x20,mousetext_glyphs);
}
// Classic interface and messages
void video_plotchar_fb(uint8_t *fb, int fb_width, int x, int y, int scheme, uint8_t c) {
void interface_plotChar(uint8_t *fb, int fb_pix_width, int col, int row, interface_colorscheme_t cs, uint8_t c) {
_vid_dirty = true;
unsigned int off = y * fb_width * 16 + x * 7 + 4;
unsigned int off = row * fb_pix_width * FONT_HEIGHT_PIXELS + col * FONT80_WIDTH_PIXELS + _INTERPOLATED_PIXEL_ADJUSTMENT_PRE;
uint8_t *dst = fb + off;
uint8_t *src = video__int_font[scheme] + c * 64;
uint8_t *src = video__int_font[cs] + c * (FONT_GLYPH_X*FONT_GLYPH_Y);
_plot_char80(&dst, &src, fb_width);
_plot_char80(&dst, &src, fb_width);
_plot_char80(&dst, &src, fb_width);
_plot_char80(&dst, &src, fb_width);
_plot_char80(&dst, &src, fb_width);
_plot_char80(&dst, &src, fb_width);
_plot_char80(&dst, &src, fb_width);
_plot_char80(&dst, &src, fb_width);
}
void video_plotchar(int x, int y, int scheme, uint8_t c) {
video_plotchar_fb(video__fb1, SCANWIDTH, x, y, scheme, c);
}
void video_interface_print_fb(uint8_t *fb, int fb_width, int x, int y, int cs, const char *s) {
for (; *s; x++, s++) {
video_plotchar_fb(fb, fb_width, x, y, cs, *s);
}
}
void video_interface_print(int x, int y, int cs, const char *s) {
video_interface_print_fb(video__fb1, SCANWIDTH, x, y, cs, s);
}
#define IsGraphic(c) ((c) == '|' || (((unsigned char)c) >= 0x80 && ((unsigned char)c) <= 0x8A))
#define IsInside(x,y) ((x) >= 0 && (x) <= xlen-1 && (y) >= 0 && (y) <= ylen-1)
static void _convert_screen_graphics(char *screen, const int x, const int y, const int xlen, const int ylen) {
static char map[11][3][4] ={ { "...",
".||",
".|." },
{ "...",
"||.",
".|." },
{ ".|.",
".||",
"..." },
{ ".|.",
"||.",
"..." },
{ "~|~",
".|.",
"~|~" },
{ "~.~",
"|||",
"~.~" },
{ ".|.",
".||",
".|." },
{ ".|.",
"||.",
".|." },
{ "...",
"|||",
".|." },
{ ".|.",
"|||",
"..." },
{ ".|.",
"|||",
".|." } };
bool found_glyph = false;
int k = 10;
for (; k >= 0; k--) {
found_glyph = true;
for (int yy = y - 1; found_glyph && yy <= y + 1; yy++) {
int idx = yy*(xlen+1);
for (int xx = x - 1; xx <= x + 1; xx++) {
char map_ch = map[k][ yy - y + 1 ][ xx - x + 1 ];
if (IsInside(xx, yy)) {
char c = *(screen + idx + xx);
if (!IsGraphic( c ) && (map_ch == '|')) {
found_glyph = false;
break;
} else if (IsGraphic( c ) && (map_ch == '.')) {
found_glyph = false;
break;
}
} else if (map_ch == '|') {
found_glyph = false;
break;
}
}
idx += xlen+1;
}
if (found_glyph) {
break;
}
}
if (found_glyph) {
*(screen + y*(xlen+1) + x) = 0x80 + k;
}
}
void video_interface_translate_screen_x_y(char *screen, const int xlen, const int ylen) {
for (int idx=0, y=0; y < ylen; y++, idx+=xlen+1) {
for (int x = 0; x < xlen; x++) {
if (*(screen + idx + x) == '|') {
_convert_screen_graphics(screen, x, y, xlen, ylen);
}
}
}
}
void video_interface_print_submenu_centered_fb(uint8_t *fb, int submenu_width, int submenu_height, char *submenu, const int xlen, const int ylen) {
video_interface_translate_screen_x_y(submenu, xlen, ylen);
int x = (submenu_width - xlen) >> 1;
int y = (submenu_height - ylen) >> 1;
int fb_width = (submenu_width*7) + INTERPOLATED_PIXEL_ADJUSTMENT; // HACK NOTE : interpolated pixel adjustment still necessary ...
int ymax = y+ylen;
for (int idx=0; y < ymax; y++, idx+=xlen+1) {
video_interface_print_fb(fb, fb_width, x, y, 2, &submenu[ idx ]);
}
}
void video_interface_print_submenu_centered(char *submenu, const int xlen, const int ylen) {
video_interface_print_submenu_centered_fb(video__fb1, INTERFACE_SCREEN_X, TEXT_ROWS, submenu, xlen, ylen);
_plot_char80(&dst, &src, fb_pix_width);
_plot_char80(&dst, &src, fb_pix_width);
_plot_char80(&dst, &src, fb_pix_width);
_plot_char80(&dst, &src, fb_pix_width);
_plot_char80(&dst, &src, fb_pix_width);
_plot_char80(&dst, &src, fb_pix_width);
_plot_char80(&dst, &src, fb_pix_width);
_plot_char80(&dst, &src, fb_pix_width);
}
// ----------------------------------------------------------------------------
@ -1398,3 +1273,9 @@ uint8_t floating_bus_hibit(const bool hibit) {
return (b & ~0x80) | (hibit ? 0x80 : 0);
}
__attribute__((constructor))
static void _init_interface(void) {
LOG("display subsystem startup");
_load_interface_fonts();
}

View File

@ -16,11 +16,139 @@
#include "common.h"
// 2015/04/12 : This was legacy code for rendering the menu interfaces on desktop Linux. Portions here are resurrected
// to render HUD messages on desktop and mobile. Nothing special or pretty here, but has "just worked" for 20+ years ;-)
#define IsGraphic(c) ((c) == '|' || (((unsigned char)c) >= 0x80 && ((unsigned char)c) <= 0x8A))
#define IsInside(x,y) ((x) >= 0 && (x) <= xlen-1 && (y) >= 0 && (y) <= ylen-1)
// Draws special interface menu "characters"
static void _convert_screen_graphics(char *screen, const int x, const int y, const int xlen, const int ylen) {
static char map[11][3][4] ={ { "...",
".||",
".|." },
{ "...",
"||.",
".|." },
{ ".|.",
".||",
"..." },
{ ".|.",
"||.",
"..." },
{ "~|~",
".|.",
"~|~" },
{ "~.~",
"|||",
"~.~" },
{ ".|.",
".||",
".|." },
{ ".|.",
"||.",
".|." },
{ "...",
"|||",
".|." },
{ ".|.",
"|||",
"..." },
{ ".|.",
"|||",
".|." } };
bool found_glyph = false;
int k = 10;
for (; k >= 0; k--) {
found_glyph = true;
for (int yy = y - 1; found_glyph && yy <= y + 1; yy++) {
int idx = yy*(xlen+1);
for (int xx = x - 1; xx <= x + 1; xx++) {
char map_ch = map[k][ yy - y + 1 ][ xx - x + 1 ];
if (IsInside(xx, yy)) {
char c = *(screen + idx + xx);
if (!IsGraphic( c ) && (map_ch == '|')) {
found_glyph = false;
break;
} else if (IsGraphic( c ) && (map_ch == '.')) {
found_glyph = false;
break;
}
} else if (map_ch == '|') {
found_glyph = false;
break;
}
}
idx += xlen+1;
}
if (found_glyph) {
break;
}
}
if (found_glyph) {
*(screen + y*(xlen+1) + x) = 0x80 + k;
}
}
static void _translate_screen_x_y(char *screen, const int xlen, const int ylen) {
for (int idx=0, y=0; y < ylen; y++, idx+=xlen+1) {
for (int x = 0; x < xlen; x++) {
if (*(screen + idx + x) == '|') {
_convert_screen_graphics(screen, x, y, xlen, ylen);
}
}
}
}
// ----------------------------------------------------------------------------
// Menu/HUD message printing
void interface_printMessage(uint8_t *fb, int fb_pix_width, int col, int row, interface_colorscheme_t cs, const char *message) {
for (; *message; col++, message++) {
char c = *message;
interface_plotChar(fb, fb_pix_width, col, row, cs, c);
}
}
void interface_printMessageCentered(uint8_t *fb, int fb_cols, int fb_rows, interface_colorscheme_t cs, char *message, const int message_cols, const int message_rows) {
_translate_screen_x_y(message, message_cols, message_rows);
int col = (fb_cols - message_cols) >> 1;
int row = (fb_rows - message_rows) >> 1;
int fb_pix_width = (fb_cols*FONT80_WIDTH_PIXELS) + INTERPOLATED_PIXEL_ADJUSTMENT; // HACK NOTE : interpolated pixel adjustment still necessary ...
int row_max = row + message_rows;
for (int idx=0; row<row_max; row++, idx+=message_cols+1) {
interface_printMessage(fb, fb_pix_width, col, row, cs, &message[ idx ]);
}
}
// ----------------------------------------------------------------------------
// Desktop Legacy Menu Interface
#ifdef INTERFACE_CLASSIC
static struct stat statbuf = { 0 };
static int altdrive = 0;
bool in_interface = false;
void video_plotchar(const int col, const int row, const interface_colorscheme_t cs, const uint8_t c) {
interface_plotChar(video__fb1, SCANWIDTH, col, row, cs, c);
}
void copy_and_pad_string(char *dest, const char* src, const char c, const int len, const char cap) {
const char* p = src;
char* d = dest;
@ -50,8 +178,8 @@ static void pad_string(char *s, const char c, const int len) {
*p = '\0';
}
void c_interface_print( int x, int y, int cs, const char *s ) {
video_interface_print(x, y, cs, s);
void c_interface_print( int x, int y, const interface_colorscheme_t cs, const char *s ) {
interface_printMessage(video__fb1, SCANWIDTH, x, y, cs, s);
}
/* -------------------------------------------------------------------------
@ -64,15 +192,15 @@ void c_interface_print_screen( char screen[24][INTERFACE_SCREEN_X+1] ) {
}
static void c_interface_translate_screen_x_y(char *screen, const int xlen, const int ylen) {
video_interface_translate_screen_x_y(screen, xlen, ylen);
_translate_screen_x_y(screen, xlen, ylen);
}
void c_interface_translate_screen( char screen[24][INTERFACE_SCREEN_X+1] ) {
c_interface_translate_screen_x_y(screen[0], INTERFACE_SCREEN_X, 24);
}
void c_interface_print_submenu_centered( char *submenu, const int xlen, const int ylen ) {
video_interface_print_submenu_centered(submenu, xlen, ylen);
void c_interface_print_submenu_centered( char *submenu, const int message_cols, const int message_rows ) {
interface_printMessageCentered(video__fb1, INTERFACE_SCREEN_X, TEXT_ROWS, RED_ON_BLACK, submenu, message_cols, message_rows);
}
/* ------------------------------------------------------------------------- */
@ -1441,3 +1569,5 @@ void c_interface_begin(int current_key)
pthread_create(&t, NULL, (void *)&interface_thread, (void *)((__SWORD_TYPE)current_key));
}
#endif

View File

@ -17,13 +17,20 @@
#ifndef A2_INTERFACE_H
#define A2_INTERFACE_H
#include "video/video.h"
#define INTERFACE_SCREEN_X 80
typedef enum interface_colorscheme_t {
GREEN_ON_BLACK = 0,
GREEN_ON_BLUE,
RED_ON_BLACK,
} interface_colorscheme_t;
#ifdef INTERFACE_CLASSIC
extern bool in_interface;
void video_plotchar(int col, int row, interface_colorscheme_t cs, uint8_t c);
void c_interface_begin(int current_key);
void c_interface_print(int x, int y, const int cs, const char *s);
void c_interface_print_submenu_centered(char *submenu, const int xlen, const int ylen);
void c_interface_print(int x, int y, const interface_colorscheme_t cs, const char *s);
void c_interface_print_submenu_centered(char *submenu, int xlen, int ylen);
void c_interface_keyboard_layout();
void c_interface_parameters();
void c_interface_credits();
@ -31,3 +38,14 @@ void c_interface_exit(int ch);
void c_interface_translate_screen(char screen[24][INTERFACE_SCREEN_X+1]);
void c_interface_select_diskette(int);
#endif
// Plots a character into the specified framebuffer
void interface_plotChar(uint8_t *fb, int fb_pix_width, int col, int row, interface_colorscheme_t cs, uint8_t c);
// Plots a string/template into the specified framebuffer
void interface_printMessage(uint8_t *fb, int fb_pix_width, int col, int row, interface_colorscheme_t cs, const char *message);
// Plots a string/template into the specified framebuffer
void interface_printMessageCentered(uint8_t *fb, int fb_cols, int fb_rows, interface_colorscheme_t cs, char *message, int message_cols, int message_rows);
#endif

View File

@ -236,7 +236,8 @@ void c_keys_handle_input(int scancode, int pressed, int is_cooked)
#ifdef INTERFACE_CLASSIC
&& !in_interface
#endif
) {
)
{
do {
int current_key = next_key;
next_key = -1;
@ -252,10 +253,11 @@ void c_keys_handle_input(int scancode, int pressed, int is_cooked)
if (current_key == kF9)
{
timing_toggle_cpu_speed();
if (video_animation_show_cpuspeed) {
video_animation_show_cpuspeed();
}
break;
}
//#define CPUSCALE_ANIMATIONS_KEYS 1
#if CPUSCALE_ANIMATIONS_KEYS
if (current_key == kF3) {
double scale = (alt_speed_enabled ? cpu_altscale_factor : cpu_scale_factor);
@ -319,7 +321,6 @@ void c_keys_handle_input(int scancode, int pressed, int is_cooked)
timing_toggle_cpu_speed();
break;
}
#endif
#endif
if (current_key == kEND)

View File

@ -593,7 +593,6 @@ void reinitialize(void) {
}
void c_initialize_firsttime(void) {
video_load_interface_fonts();
video_init();

View File

@ -27,15 +27,13 @@ void glhud_setupDefault(GLModel *parent) {
const unsigned int cols = hudElement->tplWidth;
const unsigned int rows = hudElement->tplHeight;
uint8_t *fb = hudElement->pixels;
const unsigned int fb_w = hudElement->pixWidth;
const unsigned int fb_h = hudElement->pixHeight;
// render template into indexed fb
const unsigned int submenu_width = cols;
const unsigned int submenu_height = rows;
video_interface_print_submenu_centered_fb(fb, submenu_width, submenu_height, submenu, submenu_width, submenu_height);
interface_printMessageCentered(fb, cols, rows, RED_ON_BLACK, submenu, cols, rows);
// generate RGBA_8888 from indexed color
const unsigned int fb_w = hudElement->pixWidth;
const unsigned int fb_h = hudElement->pixHeight;
const unsigned int count = fb_w * fb_h;
for (unsigned int i=0, j=0; i<count; i++, j+=4) {
uint8_t index = *(fb + i);

View File

@ -16,7 +16,6 @@
#include "video_util/modelUtil.h"
MODEL_CLASS(GLModelHUDElement,
void *(*render)(GLModel *parent);
char *tpl; // ASCII template
unsigned int tplWidth; // template width

View File

@ -12,36 +12,13 @@
#ifndef _GLVIDEO_H_
#define _GLVIDEO_H_
#define UNINITIALIZED_GL 31337
#ifdef __APPLE__
#import <CoreFoundation/CoreFoundation.h>
#define USE_VAO 1
#endif
// TODO: implement 3D CRT object, possibly with perspective drawing?
#define PERSPECTIVE 0
// VAO optimization (may not be available on all platforms)
#ifdef ANDROID
#include "glanimation.h"
// 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
#endif
#include "video_util/modelUtil.h"
#include "video_util/matrixUtil.h"
#include "video_util/sourceUtil.h"
enum {
POS_ATTRIB_IDX,
TEXCOORD_ATTRIB_IDX,
NORMAL_ATTRIB_IDX,
};
enum {
TEXTURE_ID_FRAMEBUFFER=0,
TEXTURE_ID_MESSAGE,
@ -60,26 +37,6 @@ enum {
#endif
};
static inline GLsizei getGLTypeSize(GLenum type) {
switch (type) {
case GL_BYTE:
return sizeof(GLbyte);
case GL_UNSIGNED_BYTE:
return sizeof(GLubyte);
case GL_SHORT:
return sizeof(GLshort);
case GL_UNSIGNED_SHORT:
return sizeof(GLushort);
case GL_INT:
return sizeof(GLint);
case GL_UNSIGNED_INT:
return sizeof(GLuint);
case GL_FLOAT:
return sizeof(GLfloat);
}
return 0;
}
extern GLint uniformTex2Use;
extern GLint alphaValue;

View File

@ -97,11 +97,6 @@ void video_set(int flags);
*/
void video_loadfont(int first, int qty, const uint8_t *data, int mode);
/*
* Loads the interface/messages to a seperate character table for system menus/messages
*/
void video_load_interface_fonts(void);
/*
* Redraw the display. This is called after exiting an interface display,
* when changes have been made to the Apple's emulated framebuffer that
@ -128,35 +123,6 @@ bool video_dirty(void);
// ----------------------------------------------------------------------------
/*
* Plot a character to the text mode screen, *not* writing to apple
* memory. This is used by the interface screens.
*
* ROW, COL, and CODE are self-expanatory. COLOR gives the color scheme
* to use:
*
* 0 - Green text on Black background
* 1 - Green text on Blue background
* 2 - Red text on Black background
*/
void video_plotchar(int row, int col, int color, uint8_t code);
/*
* Same as video_plotchar(), but allows plotting to a separate buffer
*/
void video_plotchar_fb(uint8_t *fb, int fb_width, int row, int col, int color, uint8_t code);
void video_interface_print(int x, int y, const int cs, const char *s);
void video_interface_print_fb(uint8_t *fb, int fb_width, int x, int y, const int cs, const char *s);
void video_interface_print_submenu_centered(char *submenu, const int xlen, const int ylen);
void video_interface_print_submenu_centered_fb(uint8_t *fb, int screen_char_width, int screen_char_height, char *submenu, const int xlen, const int ylen);
// ----------------------------------------------------------------------------
/*
* Show CPU speed animation
*/
@ -184,7 +150,9 @@ uint8_t floating_bus_hibit(const bool hibit);
* machines) for a standard resolution.
*/
#define _SCANWIDTH 560
#define INTERPOLATED_PIXEL_ADJUSTMENT (4+4)
#define _INTERPOLATED_PIXEL_ADJUSTMENT_PRE 4
#define _INTERPOLATED_PIXEL_ADJUSTMENT_POST 4
#define INTERPOLATED_PIXEL_ADJUSTMENT (_INTERPOLATED_PIXEL_ADJUSTMENT_PRE+_INTERPOLATED_PIXEL_ADJUSTMENT_POST)
#define SCANWIDTH (_SCANWIDTH+INTERPOLATED_PIXEL_ADJUSTMENT)
#define SCANHEIGHT 384
@ -193,7 +161,8 @@ uint8_t floating_bus_hibit(const bool hibit);
#define TEXT_COLS 40
#define TEXT80_COLS 80
#define INTERFACE_SCREEN_X TEXT80_COLS
#define FONT_GLYPH_X 8
#define FONT_GLYPH_Y FONT_GLYPH_X
#define FONT_HEIGHT_PIXELS 16
#define FONT_WIDTH_PIXELS 14

View File

@ -15,7 +15,9 @@
#define __GL_UTIL_H__
#if defined(__APPLE__)
# include <TargetConditionals.h>
# define USE_VAO 1
# import <CoreFoundation/CoreFoundation.h>
# import <TargetConditionals.h>
# if TARGET_OS_IPHONE
# import <OpenGLES/ES2/gl.h>
# import <OpenGLES/ES2/glext.h>
@ -27,6 +29,9 @@
# include <GL3/gl3.h>
# include <GL3/gl3w.h>
#elif defined(ANDROID)
// 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
# include <GLES2/gl2.h>
# include <GLES2/gl2ext.h>
#else
@ -36,6 +41,10 @@
# include <GL/freeglut.h>
#endif
#if !defined(USE_VAO)
#define USE_VAO 1
#endif
static inline const char * GetGLErrorString(GLenum error) {
const char *str;
switch (error) {

View File

@ -329,7 +329,7 @@ static void _quadCreateVAOAndVBOs(GLModel *model) {
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);
GLsizei posTypeSize = getGLTypeSize(model->positionType);
// Set up parmeters for position attribute in the VAO including,
// size, type, stride, and offset in the currenly bound VAO
@ -355,7 +355,7 @@ static void _quadCreateVAOAndVBOs(GLModel *model) {
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);
GLsizei texcoordTypeSize = getGLTypeSize(model->texcoordType);
// Set up parmeters for texcoord attribute in the VAO including,
// size, type, stride, and offset in the currenly bound VAO

View File

@ -18,6 +18,12 @@
#define UNINITIALIZED_GL 31337
enum {
POS_ATTRIB_IDX,
TEXCOORD_ATTRIB_IDX,
NORMAL_ATTRIB_IDX,
};
typedef struct GLModel;
#define MODEL_CLASS(CLS, ...) \
@ -83,4 +89,24 @@ GLModel *mdlCreateQuad(GLfloat skew_x, GLfloat skew_y, GLfloat obj_w, GLfloat ob
void mdlDestroyModel(INOUT GLModel **model);
static inline GLsizei getGLTypeSize(GLenum type) {
switch (type) {
case GL_BYTE:
return sizeof(GLbyte);
case GL_UNSIGNED_BYTE:
return sizeof(GLubyte);
case GL_SHORT:
return sizeof(GLshort);
case GL_UNSIGNED_SHORT:
return sizeof(GLushort);
case GL_INT:
return sizeof(GLint);
case GL_UNSIGNED_INT:
return sizeof(GLuint);
case GL_FLOAT:
return sizeof(GLfloat);
}
return 0;
}
#endif //__MODEL_UTIL_H__