# HG changeset patch # User John Tsiombikas # Date 1443935724 -10800 # Node ID 9d53a4938ce8c81e32fc8b225e27caf5dea046e9 # Parent 7d795dade0bced99de5810df49955a2beadb774d port to android mostly complete, ads not done, and needs some polishing diff -r 7d795dade0bc -r 9d53a4938ce8 .hgignore --- a/.hgignore Sat Oct 03 06:10:30 2015 +0300 +++ b/.hgignore Sun Oct 04 08:15:24 2015 +0300 @@ -16,6 +16,7 @@ ^android/res/ ^android/src/ ^android/assets/ +^android/gen/ \.xml$ \.properties$ proguard-project\.txt$ diff -r 7d795dade0bc -r 9d53a4938ce8 Makefile --- a/Makefile Sat Oct 03 06:10:30 2015 +0300 +++ b/Makefile Sun Oct 04 08:15:24 2015 +0300 @@ -1,3 +1,4 @@ +root = . src = $(wildcard src/*.c) $(wildcard src/glut/*.c) ccsrc = $(wildcard src/*.cc) diff -r 7d795dade0bc -r 9d53a4938ce8 android/Makefile --- a/android/Makefile Sat Oct 03 06:10:30 2015 +0300 +++ b/android/Makefile Sun Oct 04 08:15:24 2015 +0300 @@ -12,6 +12,7 @@ # ------------------------ src += $(wildcard $(root)/src/android/*.c) +jsrc = $(wildcard $(root)/src/android/*.java) obj = $(src:.c=.o) $(ccsrc:.cc=.o) lib = libs/armeabi/lib$(name).so @@ -19,7 +20,7 @@ apk-debug = bin/$(name)-debug.apk pkg = $(pkgprefix).$(name) -act = android.app.NativeActivity +act = $(pkg).MainActivity CC = arm-linux-androideabi-gcc CXX = arm-linux-androideabi-g++ @@ -95,7 +96,7 @@ AndroidManifest.xml: manifest.xml.in android create project -p . -t $(android_platform) -k $(pkg) -a NativeActivity -n $(name) cat manifest.xml.in | sed 's/$$APPNAME/$(name)/g' | sed 's/$$APPTITLE/$(title)/g' >$@ -# cd src && rm -f *.java && ln -s ../../src/android/*.java . + cd src && rm -f *.java && ln -s ../../src/android/*.java . .PHONY: update-project update-project: build.xml diff -r 7d795dade0bc -r 9d53a4938ce8 android/manifest.xml.in --- a/android/manifest.xml.in Sat Oct 03 06:10:30 2015 +0300 +++ b/android/manifest.xml.in Sun Oct 04 08:15:24 2015 +0300 @@ -4,14 +4,14 @@ android:versionCode="1" android:versionName="1.0"> - + + - - + + - diff -r 7d795dade0bc -r 9d53a4938ce8 src/android/MainActivity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/android/MainActivity.java Sun Oct 04 08:15:24 2015 +0300 @@ -0,0 +1,56 @@ +package com.mutantstargoat.stereotunnel; + +import android.os.Bundle; +import android.app.NativeActivity; +import android.view.*; +import android.view.WindowManager.LayoutParams; +//import android.util.Log; + +public class MainActivity extends NativeActivity +{ + //public static String tag = "stereotunnel"; + + @Override + protected void onCreate(Bundle saved_inst) + { + super.onCreate(saved_inst); + + // go fullscreen + int winflags = LayoutParams.FLAG_FULLSCREEN | + LayoutParams.FLAG_LAYOUT_NO_LIMITS | LayoutParams.FLAG_LAYOUT_IN_SCREEN; + Window win = getWindow(); + win.setFlags(winflags, winflags); + } + + @Override + public void onWindowFocusChanged(boolean focus) + { + super.onWindowFocusChanged(focus); + if(focus) { + set_fullscreen(); + } + } + + protected void onResume() + { + super.onResume(); + set_fullscreen(); + } + + public void set_fullscreen() + { + int uiflags = View.SYSTEM_UI_FLAG_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LOW_PROFILE; + + if(android.os.Build.VERSION.SDK_INT >= 19) { + uiflags |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; + } + + View decor = getWindow().getDecorView(); + decor.setSystemUiVisibility(uiflags); + } +} diff -r 7d795dade0bc -r 9d53a4938ce8 src/android/amain.c --- a/src/android/amain.c Sat Oct 03 06:10:30 2015 +0300 +++ b/src/android/amain.c Sun Oct 04 08:15:24 2015 +0300 @@ -2,8 +2,8 @@ #include #include #include -#include #include "android_native_app_glue.h" +#include #include #include "logger.h" #include "istereo.h" @@ -33,6 +33,8 @@ app->onAppCmd = handle_command; app->onInputEvent = handle_input; + //ANativeActivity_setWindowFlags(app->activity, AWINDOW_FLAG_FULLSCREEN, 0); + start_logger(); for(;;) { @@ -81,6 +83,7 @@ break; case APP_CMD_INIT_WINDOW: + printf("APP_CMD_INIT_WINDOW\n"); if(init_gl() == -1) { exit(1); } @@ -88,21 +91,25 @@ if(init() == -1) { exit(1); /* initialization failed, quit */ } + reshape(width, height); init_done = 1; break; case APP_CMD_TERM_WINDOW: /* cleanup */ + printf("APP_CMD_TERM_WINDOW\n"); init_done = 0; cleanup(); destroy_gl(); break; case APP_CMD_GAINED_FOCUS: + printf("APP_CMD_GAINED_FOCUS\n"); /* app focused */ break; case APP_CMD_LOST_FOCUS: + printf("APP_CMD_LOST_FOCUS\n"); /* app lost focus */ break; @@ -112,6 +119,7 @@ int nx = ANativeWindow_getWidth(app->window); int ny = ANativeWindow_getHeight(app->window); if(nx != width || ny != height) { + printf("reshape(%d, %d)\n", nx, ny); reshape(nx, ny); width = nx; height = ny; @@ -250,6 +258,7 @@ eglQuerySurface(dpy, surf, EGL_WIDTH, &width); eglQuerySurface(dpy, surf, EGL_HEIGHT, &height); + printf("initial reshape call: %dx%d\n", width, height); reshape(width, height); return 0; diff -r 7d795dade0bc -r 9d53a4938ce8 src/android/assman.c --- a/src/android/assman.c Sat Oct 03 06:10:30 2015 +0300 +++ b/src/android/assman.c Sun Oct 04 08:15:24 2015 +0300 @@ -1,3 +1,4 @@ +#include #include #include #include "assman.h" @@ -37,6 +38,9 @@ prev = *mode++; } + assert(app); + assert(app->activity); + assert(app->activity->assetManager); if(!(ass = AAssetManager_open(app->activity->assetManager, fname, flags))) { return 0; } diff -r 7d795dade0bc -r 9d53a4938ce8 src/android/logger.c --- a/src/android/logger.c Sat Oct 03 06:10:30 2015 +0300 +++ b/src/android/logger.c Sun Oct 04 08:15:24 2015 +0300 @@ -5,6 +5,10 @@ #include #include "logger.h" +#ifndef APP_NAME +#define APP_NAME "stereotunnel" +#endif + static void *thread_func(void *arg); static int pfd[2]; diff -r 7d795dade0bc -r 9d53a4938ce8 src/istereo.c --- a/src/istereo.c Sat Oct 03 06:10:30 2015 +0300 +++ b/src/istereo.c Sun Oct 04 08:15:24 2015 +0300 @@ -410,7 +410,7 @@ glViewport(0, 0, x, y); float aspect = (float)x / (float)y; - float maxfov = 40.0; + float maxfov = 42.0; float vfov = aspect > 1.0 ? maxfov / aspect : maxfov; cam_fov(vfov); @@ -466,14 +466,14 @@ { unsigned int prog, vs, ps; - if(!(vs = get_vertex_shader(find_resource(vfile, 0, 0)))) { + if(!(vs = load_vertex_shader(find_resource(vfile, 0, 0)))) { return 0; } - if(!(ps = get_pixel_shader(find_resource(pfile, 0, 0)))) { + if(!(ps = load_pixel_shader(find_resource(pfile, 0, 0)))) { return 0; } - if(!(prog = create_program_link(vs, ps))) { + if(!(prog = create_program_link(vs, ps, 0))) { return 0; } return prog; diff -r 7d795dade0bc -r 9d53a4938ce8 src/respath.c --- a/src/respath.c Sat Oct 03 06:10:30 2015 +0300 +++ b/src/respath.c Sun Oct 04 08:15:24 2015 +0300 @@ -24,6 +24,7 @@ #include #include "respath.h" #include "config.h" +#include "assman.h" #ifdef IPHONE #include @@ -64,8 +65,11 @@ node = pathlist; while(node) { + ass_file *fp; + snprintf(path, sz, "%s/%s", node->path, fname); - if(access(path, F_OK) != -1) { + if((fp = ass_fopen(path, "r"))) { + ass_fclose(fp); return path; } node = node->next; diff -r 7d795dade0bc -r 9d53a4938ce8 src/sdr.c --- a/src/sdr.c Sat Oct 03 06:10:30 2015 +0300 +++ b/src/sdr.c Sun Oct 04 08:15:24 2015 +0300 @@ -1,27 +1,11 @@ -/* -Stereoscopic tunnel for iOS. -Copyright (C) 2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - #include #include #include #include +#include #include #include "opengl.h" +#include "assman.h" #if defined(unix) || defined(__unix__) #include @@ -30,6 +14,7 @@ #include "sdr.h" +static const char *sdrtypestr(unsigned int sdrtype); unsigned int create_vertex_shader(const char *src) { @@ -41,6 +26,33 @@ return create_shader(src, GL_FRAGMENT_SHADER); } +unsigned int create_tessctl_shader(const char *src) +{ +#ifdef GL_TESS_CONTROL_SHADER + return create_shader(src, GL_TESS_CONTROL_SHADER); +#else + return 0; +#endif +} + +unsigned int create_tesseval_shader(const char *src) +{ +#ifdef GL_TESS_EVALUATION_SHADER + return create_shader(src, GL_TESS_EVALUATION_SHADER); +#else + return 0; +#endif +} + +unsigned int create_geometry_shader(const char *src) +{ +#ifdef GL_GEOMETRY_SHADER + return create_shader(src, GL_GEOMETRY_SHADER); +#else + return 0; +#endif +} + unsigned int create_shader(const char *src, unsigned int sdr_type) { unsigned int sdr; @@ -65,6 +77,7 @@ if((info_str = malloc(info_len + 1))) { glGetShaderInfoLog(sdr, info_len, 0, info_str); assert(glGetError() == GL_NO_ERROR); + info_str[info_len] = 0; } } @@ -95,39 +108,58 @@ return load_shader(fname, GL_FRAGMENT_SHADER); } +unsigned int load_tessctl_shader(const char *fname) +{ +#ifdef GL_TESS_CONTROL_SHADER + return load_shader(fname, GL_TESS_CONTROL_SHADER); +#else + return 0; +#endif +} + +unsigned int load_tesseval_shader(const char *fname) +{ +#ifdef GL_TESS_EVALUATION_SHADER + return load_shader(fname, GL_TESS_EVALUATION_SHADER); +#else + return 0; +#endif +} + +unsigned int load_geometry_shader(const char *fname) +{ +#ifdef GL_GEOMETRY_SHADER + return load_shader(fname, GL_GEOMETRY_SHADER); +#else + return 0; +#endif +} + unsigned int load_shader(const char *fname, unsigned int sdr_type) { -#if defined(unix) || defined(__unix__) - struct stat st; -#endif unsigned int sdr; size_t filesize; - FILE *fp; + ass_file *fp; char *src; - if(!(fp = fopen(fname, "r"))) { + if(!(fp = ass_fopen(fname, "rb"))) { fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno)); return 0; } -#if defined(unix) || defined(__unix__) - fstat(fileno(fp), &st); - filesize = st.st_size; -#else - fseek(fp, 0, SEEK_END); - filesize = ftell(fp); - fseek(fp, 0, SEEK_SET); -#endif /* unix */ + filesize = ass_fseek(fp, 0, SEEK_END); + /*filesize = ass_ftell(fp);*/ + ass_fseek(fp, 0, SEEK_SET); if(!(src = malloc(filesize + 1))) { - fclose(fp); + ass_fclose(fp); return 0; } - fread(src, 1, filesize, fp); + ass_fread(src, 1, filesize, fp); src[filesize] = 0; - fclose(fp); + ass_fclose(fp); - fprintf(stderr, "compiling %s shader: %s... ", (sdr_type == GL_VERTEX_SHADER ? "vertex" : "pixel"), fname); + fprintf(stderr, "compiling %s shader: %s... ", sdrtypestr(sdr_type), fname); sdr = create_shader(src, sdr_type); free(src); @@ -135,27 +167,6 @@ } -unsigned int get_vertex_shader(const char *fname) -{ - return get_shader(fname, GL_VERTEX_SHADER); -} - -unsigned int get_pixel_shader(const char *fname) -{ - return get_shader(fname, GL_FRAGMENT_SHADER); -} - -unsigned int get_shader(const char *fname, unsigned int sdr_type) -{ - unsigned int sdr; - - if(!fname || !(sdr = load_shader(fname, sdr_type))) { - return 0; - } - return sdr; -} - - /* ---- gpu programs ---- */ unsigned int create_program(void) @@ -165,18 +176,28 @@ return prog; } -unsigned int create_program_link(unsigned int vs, unsigned int ps) +unsigned int create_program_link(unsigned int sdr0, ...) { - unsigned int prog; + unsigned int prog, sdr; + va_list ap; if(!(prog = create_program())) { return 0; } - attach_shader(prog, vs); - assert(glGetError() == GL_NO_ERROR); - attach_shader(prog, ps); - assert(glGetError() == GL_NO_ERROR); + attach_shader(prog, sdr0); + if(glGetError()) { + return 0; + } + + va_start(ap, sdr0); + while((sdr = va_arg(ap, unsigned int))) { + attach_shader(prog, sdr); + if(glGetError()) { + return 0; + } + } + va_end(ap); if(link_program(prog) == -1) { free_program(prog); @@ -187,12 +208,15 @@ unsigned int create_program_load(const char *vfile, const char *pfile) { - unsigned int vs, ps; + unsigned int vs = 0, ps = 0; - if(!(vs = get_vertex_shader(vfile)) || !(ps = get_pixel_shader(pfile))) { + if(vfile && *vfile && !(vs = load_vertex_shader(vfile))) { return 0; } - return create_program_link(vs, ps); + if(pfile && *pfile && !(ps = load_pixel_shader(pfile))) { + return 0; + } + return create_program_link(vs, ps, 0); } void free_program(unsigned int sdr) @@ -202,8 +226,16 @@ void attach_shader(unsigned int prog, unsigned int sdr) { - glAttachShader(prog, sdr); - assert(glGetError() == GL_NO_ERROR); + int err; + + if(prog && sdr) { + assert(glGetError() == GL_NO_ERROR); + glAttachShader(prog, sdr); + if((err = glGetError()) != GL_NO_ERROR) { + fprintf(stderr, "failed to attach shader %u to program %u (err: 0x%x)\n", sdr, prog, err); + abort(); + } + } } int link_program(unsigned int prog) @@ -222,6 +254,7 @@ if((info_str = malloc(info_len + 1))) { glGetProgramInfoLog(prog, info_len, 0, info_str); assert(glGetError() == GL_NO_ERROR); + info_str[info_len] = 0; } } @@ -259,13 +292,13 @@ #define BEGIN_UNIFORM_CODE \ int loc, curr_prog; \ glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \ - if(curr_prog != prog && bind_program(prog) == -1) { \ + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \ return -1; \ } \ if((loc = glGetUniformLocation(prog, name)) != -1) #define END_UNIFORM_CODE \ - if(curr_prog != prog) { \ + if((unsigned int)curr_prog != prog) { \ bind_program(curr_prog); \ } \ return loc == -1 ? -1 : 0 @@ -286,6 +319,14 @@ END_UNIFORM_CODE; } +int set_uniform_float2(unsigned int prog, const char *name, float x, float y) +{ + BEGIN_UNIFORM_CODE { + glUniform2f(loc, x, y); + } + END_UNIFORM_CODE; +} + int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z) { BEGIN_UNIFORM_CODE { @@ -323,13 +364,13 @@ int loc, curr_prog; glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); - if(curr_prog != prog && bind_program(prog) == -1) { + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { return -1; } loc = glGetAttribLocation(prog, (char*)name); - if(curr_prog != prog) { + if((unsigned int)curr_prog != prog) { bind_program(curr_prog); } return loc; @@ -339,3 +380,29 @@ { glVertexAttrib3f(attr_loc, x, y, z); } + +static const char *sdrtypestr(unsigned int sdrtype) +{ + switch(sdrtype) { + case GL_VERTEX_SHADER: + return "vertex"; + case GL_FRAGMENT_SHADER: + return "pixel"; +#ifdef GL_TESS_CONTROL_SHADER + case GL_TESS_CONTROL_SHADER: + return "tessellation control"; +#endif +#ifdef GL_TESS_EVALUATION_SHADER + case GL_TESS_EVALUATION_SHADER: + return "tessellation evaluation"; +#endif +#ifdef GL_GEOMETRY_SHADER + case GL_GEOMETRY_SHADER: + return "geometry"; +#endif + + default: + break; + } + return ""; +} diff -r 7d795dade0bc -r 9d53a4938ce8 src/sdr.h --- a/src/sdr.h Sat Oct 03 06:10:30 2015 +0300 +++ b/src/sdr.h Sun Oct 04 08:15:24 2015 +0300 @@ -1,21 +1,3 @@ -/* -Stereoscopic tunnel for iOS. -Copyright (C) 2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - #ifndef SDR_H_ #define SDR_H_ @@ -26,23 +8,25 @@ /* ---- shaders ---- */ unsigned int create_vertex_shader(const char *src); unsigned int create_pixel_shader(const char *src); +unsigned int create_tessctl_shader(const char *src); +unsigned int create_tesseval_shader(const char *src); +unsigned int create_geometry_shader(const char *src); unsigned int create_shader(const char *src, unsigned int sdr_type); void free_shader(unsigned int sdr); unsigned int load_vertex_shader(const char *fname); unsigned int load_pixel_shader(const char *fname); +unsigned int load_tessctl_shader(const char *fname); +unsigned int load_tesseval_shader(const char *fname); +unsigned int load_geometry_shader(const char *fname); unsigned int load_shader(const char *src, unsigned int sdr_type); -unsigned int get_vertex_shader(const char *fname); -unsigned int get_pixel_shader(const char *fname); -unsigned int get_shader(const char *fname, unsigned int sdr_type); - int add_shader(const char *fname, unsigned int sdr); int remove_shader(const char *fname); /* ---- gpu programs ---- */ unsigned int create_program(void); -unsigned int create_program_link(unsigned int vs, unsigned int ps); +unsigned int create_program_link(unsigned int sdr0, ...); unsigned int create_program_load(const char *vfile, const char *pfile); void free_program(unsigned int sdr); @@ -52,6 +36,7 @@ int set_uniform_int(unsigned int prog, const char *name, int val); int set_uniform_float(unsigned int prog, const char *name, float val); +int set_uniform_float2(unsigned int prog, const char *name, float x, float y); int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z); int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w); int set_uniform_matrix4(unsigned int prog, const char *name, float *mat); diff -r 7d795dade0bc -r 9d53a4938ce8 src/tex.c --- a/src/tex.c Sat Oct 03 06:10:30 2015 +0300 +++ b/src/tex.c Sun Oct 04 08:15:24 2015 +0300 @@ -1,6 +1,6 @@ /* Stereoscopic tunnel for iOS. -Copyright (C) 2011 John Tsiombikas +Copyright (C) 2011-2015 John Tsiombikas This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,29 +24,63 @@ #include "tex.h" #include "config.h" #include "imago2.h" +#include "assman.h" + +static size_t ioread(void *buf, size_t bytes, void *uptr); +static long ioseek(long offs, int whence, void *uptr); unsigned int load_texture(const char *fname) { - int xsz, ysz; unsigned int tex; - void *pixels; + ass_file *fp; + struct img_io io; + struct img_pixmap img; if(!fname) { return 0; } - if(!(pixels = img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGBA32))) { - fprintf(stderr, "failed to load image: %s\n", fname); + if(!(fp = ass_fopen(fname, "rb"))) { + fprintf(stderr, "failed to open texture file: %s: %s\n", fname, strerror(errno)); return 0; } + io.uptr = fp; + io.read = ioread; + io.write = 0; + io.seek = ioseek; + + img_init(&img); + if(img_read(&img, &io) == -1) { + fprintf(stderr, "failed to load image: %s\n", fname); + ass_fclose(fp); + return 0; + } + ass_fclose(fp); + img_convert(&img, IMG_FMT_RGBA32); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - img_free_pixels(pixels); + +#ifdef __GLEW_H__ + if(GLEW_SGIS_generate_mipmap) { + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); +#endif + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.width, img.height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, img.pixels); +#ifdef __GLEW_H__ + } else { + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, img.width, img.height, + GL_RGBA, GL_UNSIGNED_BYTE, img.pixels); + } +#endif + +#ifdef GL_ES_VERSION_2_0 + glGenerateMipmap(GL_TEXTURE_2D); +#endif + img_destroy(&img); return tex; } @@ -55,7 +89,7 @@ { glActiveTexture(GL_TEXTURE0 + unit); -#ifndef IPHONE +#ifndef GL_ES_VERSION_2_0 if(tex) { glEnable(GL_TEXTURE_2D); } else { @@ -65,3 +99,13 @@ glBindTexture(GL_TEXTURE_2D, tex); } + +static size_t ioread(void *buf, size_t bytes, void *uptr) +{ + return ass_fread(buf, 1, bytes, uptr); +} + +static long ioseek(long offs, int whence, void *uptr) +{ + return ass_fseek(uptr, offs, whence); +}