Commit ca9fc79971af564e14c0fa123a47c5a980986ef1

Authored by DarkGod
1 parent 57a3677f

fail code

... ... @@ -42,6 +42,10 @@ newoption {
42 42 description = "Enables sanitizer and such",
43 43 }
44 44 newoption {
  45 + trigger = "debuggl",
  46 + description = "Enables GL debug callback log",
  47 +}
  48 +newoption {
45 49 trigger = "profiling",
46 50 description = "Enables gprof profiling data",
47 51 }
... ...
... ... @@ -32,7 +32,7 @@ end
32 32 function enableSanitizer()
33 33 if _OPTIONS.debugdeep then
34 34 buildoptions { "-ggdb", "-fsanitize=address", "-fno-omit-frame-pointer" }
35   - linkoptions { "-fsanitize=address", "-fuse-ld=gold" }
  35 + linkoptions { "-static-libasan", "-fsanitize=address", "-fuse-ld=gold" }
36 36 -- buildoptions { "-ggdb", "-fsanitize=thread", "-fno-omit-frame-pointer" }
37 37 -- linkoptions { "-fsanitize=thread", "-fuse-ld=gold" }
38 38 end
... ... @@ -57,6 +57,9 @@ project "TEngine"
57 57 linkoptions{ "-fno-omit-frame-pointer" }
58 58 links{"profiler"}
59 59 end
  60 + if _OPTIONS.debuggl then
  61 + defines { "TE4_DEBUG_GL_CALLBACK" }
  62 + end
60 63 enableSanitizer()
61 64
62 65 if _OPTIONS.relpath=="32" then linkoptions{"-Wl,-rpath -Wl,\\\$\$ORIGIN/lib "} end
... ...
... ... @@ -219,5 +219,6 @@ function _M:display(nb_keyframes)
219 219 end
220 220
221 221 function _M:setupMouse(mouse)
  222 + self.no_ui=true
222 223 for _, container in ipairs(self.minicontainers) do container:setupMouse(true) end
223 224 end
... ...
... ... @@ -987,6 +987,51 @@ void do_move(int w, int h) {
987 987
988 988 extern void interface_resize(int w, int h); // From Interface.cpp
989 989
  990 +#ifdef TE4_DEBUG_GL_CALLBACK
  991 +void GLAPIENTRY openglDebugCallbackFunction(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) {
  992 + if (type == GL_DEBUG_TYPE_OTHER) return ;
  993 + printf("\x1b[33m---------------------opengl-callback-start------------\n");
  994 + printf("message: %s\n", message);
  995 + printf("type: ");
  996 + switch (type) {
  997 + case GL_DEBUG_TYPE_ERROR:
  998 + printf("ERROR");
  999 + break;
  1000 + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
  1001 + printf("DEPRECATED_BEHAVIOR");
  1002 + break;
  1003 + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
  1004 + printf("UNDEFINED_BEHAVIOR");
  1005 + break;
  1006 + case GL_DEBUG_TYPE_PORTABILITY:
  1007 + printf("PORTABILITY");
  1008 + break;
  1009 + case GL_DEBUG_TYPE_PERFORMANCE:
  1010 + printf("PERFORMANCE");
  1011 + break;
  1012 + case GL_DEBUG_TYPE_OTHER:
  1013 + printf("OTHER");
  1014 + break;
  1015 + }
  1016 + printf("\n");
  1017 +
  1018 + printf("id: %d\n", id);
  1019 + printf("severity: ");
  1020 + switch (severity){
  1021 + case GL_DEBUG_SEVERITY_LOW:
  1022 + printf("LOW");
  1023 + break;
  1024 + case GL_DEBUG_SEVERITY_MEDIUM:
  1025 + printf("MEDIUM");
  1026 + break;
  1027 + case GL_DEBUG_SEVERITY_HIGH:
  1028 + printf("HIGH");
  1029 + break;
  1030 + }
  1031 + printf("\n---------------------opengl-callback-end--------------\x1b[0m\n");
  1032 +}
  1033 +#endif
  1034 +
990 1035 /* @see main.h#do_resize */
991 1036 void do_resize(int w, int h, bool fullscreen, bool borderless, float zoom)
992 1037 {
... ... @@ -1024,7 +1069,9 @@ void do_resize(int w, int h, bool fullscreen, bool borderless, float zoom)
1024 1069 if (!window) {
1025 1070 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
1026 1071 // if (SDL_GL_SetSwapInterval(-1)) SDL_GL_SetSwapInterval(1);
1027   -
  1072 +
  1073 + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
  1074 +
1028 1075 window = SDL_CreateWindow("TE4",
1029 1076 (start_xpos == -1) ? SDL_WINDOWPOS_CENTERED : start_xpos,
1030 1077 (start_ypos == -1) ? SDL_WINDOWPOS_CENTERED : start_ypos, w, h,
... ... @@ -1053,6 +1100,17 @@ void do_resize(int w, int h, bool fullscreen, bool borderless, float zoom)
1053 1100 SDL_SetWindowIcon(window, windowIconSurface);
1054 1101 if (offscreen_render) SDL_HideWindow(window);
1055 1102
  1103 +#if TE4_DEBUG_GL_CALLBACK
  1104 + if (glDebugMessageCallback) {
  1105 + printf("Register OpenGL debug callback\n");
  1106 + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  1107 + glDebugMessageCallback((GLDEBUGPROC)openglDebugCallbackFunction, nullptr);
  1108 + GLuint unusedIds = 0;
  1109 + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, &unusedIds, true);
  1110 + }
  1111 + else printf("glDebugMessageCallback not available\n");
  1112 +#endif
  1113 +
1056 1114 } else {
1057 1115
1058 1116 /* SDL won't allow a fullscreen resolution change in one go. Check. */
... ...
... ... @@ -48,7 +48,7 @@ MapObject::MapObject(int64_t uid, uint8_t nb_textures, bool on_seen, bool on_rem
48 48 {
49 49 for (int i = 0; i < MAX_TEXTURES; i++) {
50 50 textures_ref[i] = LUA_NOREF;
51   - textures[i] = 0;
  51 + textures[i] = {0, GL_TEXTURE_2D};
52 52 }
53 53 root = this;
54 54 }
... ... @@ -85,7 +85,7 @@ void MapObject::chain(sMapObject n) {
85 85 bool MapObject::setTexture(uint8_t slot, GLuint tex, int ref, vec4 coords) {
86 86 if (slot >= MAX_TEXTURES) return false;
87 87 refcleaner(&textures_ref[slot]);
88   - textures[slot] = tex;
  88 + textures[slot] = {tex, GL_TEXTURE_2D};
89 89 textures_ref[slot] = ref;
90 90 tex_coords[slot] = coords;
91 91 notifyChangedMORs();
... ... @@ -727,8 +727,8 @@ void Map2D::toScreen(mat4 cur_model, vec4 color) {
727 727 for (int32_t z = 0; z < zdepth; z++) {
728 728 if (renderers_changed[z]) {
729 729 renderers_changed[z] = false;
730   - renderers[z]->resetDisplayLists();
731   - renderers[z]->setChanged(true);
  730 + // renderers[z]->resetDisplayLists();
  731 + // renderers[z]->setChanged(true);
732 732
733 733 int32_t mini, maxi;
734 734 int32_t minj, maxj;
... ...
... ... @@ -119,7 +119,7 @@ protected:
119 119 const static uint8_t MAX_TEXTURES = 5;
120 120 uint8_t nb_textures = 0;
121 121 int textures_ref[MAX_TEXTURES];
122   - GLuint textures[MAX_TEXTURES];
  122 + texture_do textures[MAX_TEXTURES];
123 123 vec4 tex_coords[MAX_TEXTURES];
124 124
125 125 shader_type *shader = nullptr;
... ...
... ... @@ -576,7 +576,7 @@ void Navmesh::drawDebug(float x, float y) {
576 576 renderer->resetDisplayLists();
577 577 renderer->setChanged(true);
578 578
579   - auto dl = getDisplayList(renderer, {(GLuint)gl_tex_white, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::TRIANGLES);
  579 + auto dl = getDisplayList(renderer, {(texture_do){(GLuint)gl_tex_white, GL_TEXTURE_2D}, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::TRIANGLES);
580 580 for (auto tri : mesh) {
581 581 vertex v1{{tri->p1.x, tri->p1.y, 0, 1}, {0, 0}, {0, 1, 0.5, 0.5}};
582 582 vertex v2{{tri->p2.x, tri->p2.y, 0, 1}, {0, 0}, {0, 1, 0.5, 0.5}};
... ... @@ -586,7 +586,7 @@ void Navmesh::drawDebug(float x, float y) {
586 586 dl->list.push_back(v3);
587 587 }
588 588
589   - dl = getDisplayList(renderer, {(GLuint)gl_tex_white, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::LINES);
  589 + dl = getDisplayList(renderer, {(texture_do){(GLuint)gl_tex_white, GL_TEXTURE_2D}, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::LINES);
590 590 for (auto tri : mesh) {
591 591 vertex v1{{tri->p1.x, tri->p1.y, 0, 1}, {0, 0}, {0, 1, 1, 1}};
592 592 vertex v2{{tri->p2.x, tri->p2.y, 0, 1}, {0, 0}, {0, 1, 1, 1}};
... ...
... ... @@ -83,7 +83,7 @@ void DisplayObject::setParent(DisplayObject *parent) {
83 83 void DisplayObject::setChanged(bool force) {
84 84 DisplayObject *p = this;
85 85 while (p) {
86   - if (p->stop_parent_recursing && p != this) {
  86 + if (p->stop_parent_recursing) {
87 87 p->changed_children = true;
88 88 if (force) p->changed = true;
89 89 break;
... ...
... ... @@ -58,7 +58,7 @@ public:
58 58 float p1x = p1->x * PhysicSimulator::unit_scale; float p1y = -p1->y * PhysicSimulator::unit_scale;
59 59 float p2x = p2->x * PhysicSimulator::unit_scale; float p2y = -p2->y * PhysicSimulator::unit_scale;
60 60
61   - auto dl = getDisplayList(this, {(GLuint)gl_tex_white, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::LINES);
  61 + auto dl = getDisplayList(this, {(texture_do){(GLuint)gl_tex_white, GL_TEXTURE_2D}, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::LINES);
62 62 dl->list.push_back({{p1x, p1y, 0, 1}, {0, 0}, {color.r, color.g, color.b, color.a}});
63 63 dl->list.push_back({{p2x, p2y, 0, 1}, {0, 0}, {color.r, color.g, color.b, color.a}});
64 64 }
... ... @@ -72,7 +72,7 @@ public:
72 72 float p2x = vertices[i ].x * PhysicSimulator::unit_scale; float p2y = -vertices[i ].y * PhysicSimulator::unit_scale;
73 73 float p3x = vertices[i+1].x * PhysicSimulator::unit_scale; float p3y = -vertices[i+1].y * PhysicSimulator::unit_scale;
74 74
75   - auto dl = getDisplayList(this, {(GLuint)gl_tex_white, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::TRIANGLES);
  75 + auto dl = getDisplayList(this, {(texture_do){(GLuint)gl_tex_white, GL_TEXTURE_2D}, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::TRIANGLES);
76 76 dl->list.push_back({{p1x, p1y, 0, 1}, {0, 0}, {color.r, color.g, color.b, color.a * 0.7}});
77 77 dl->list.push_back({{p2x, p2y, 0, 1}, {0, 0}, {color.r, color.g, color.b, color.a * 0.7}});
78 78 dl->list.push_back({{p3x, p3y, 0, 1}, {0, 0}, {color.r, color.g, color.b, color.a * 0.7}});
... ... @@ -85,7 +85,7 @@ public:
85 85 float p1x = p1->x * PhysicSimulator::unit_scale; float p1y = -p1->y * PhysicSimulator::unit_scale;
86 86 float p2x = p2->x * PhysicSimulator::unit_scale; float p2y = -p2->y * PhysicSimulator::unit_scale;
87 87
88   - auto dl = getDisplayList(this, {(GLuint)gl_tex_white, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::LINES);
  88 + auto dl = getDisplayList(this, {(texture_do){(GLuint)gl_tex_white, GL_TEXTURE_2D}, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::LINES);
89 89 dl->list.push_back({{p1x, p1y, 0, 1}, {0, 0}, {color.r, color.g, color.b, color.a}});
90 90 dl->list.push_back({{p2x, p2y, 0, 1}, {0, 0}, {color.r, color.g, color.b, color.a}});
91 91 }
... ... @@ -101,7 +101,7 @@ public:
101 101 float32 cosInc = cosf(k_increment);
102 102 b2Vec2 r1(1.0f, 0.0f);
103 103 b2Vec2 v1 = center + radius * r1;
104   - auto dl = getDisplayList(this, {(GLuint)gl_tex_white, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::LINES);
  104 + auto dl = getDisplayList(this, {(texture_do){(GLuint)gl_tex_white, GL_TEXTURE_2D}, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::LINES);
105 105 for (int32 i = 0; i < k_segments; ++i)
106 106 {
107 107 // Perform rotation to avoid additional trigonometry.
... ... @@ -128,7 +128,7 @@ public:
128 128 b2Vec2 v1 = center + radius * r1;
129 129 b2Vec2 v0 = center;
130 130
131   - auto dl = getDisplayList(this, {(GLuint)gl_tex_white, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::TRIANGLES);
  131 + auto dl = getDisplayList(this, {(texture_do){(GLuint)gl_tex_white, GL_TEXTURE_2D}, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::TRIANGLES);
132 132 for (int32 i = 0; i < k_segments; ++i)
133 133 {
134 134 // Perform rotation to avoid additional trigonometry.
... ... @@ -145,7 +145,7 @@ public:
145 145
146 146 r1.Set(1.0f, 0.0f);
147 147 v1 = center + radius * r1;
148   - dl = getDisplayList(this, {(GLuint)gl_tex_white, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::LINES);
  148 + dl = getDisplayList(this, {(texture_do){(GLuint)gl_tex_white, GL_TEXTURE_2D}, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::LINES);
149 149 for (int32 i = 0; i < k_segments; ++i)
150 150 {
151 151 // Perform rotation to avoid additional trigonometry.
... ... @@ -165,7 +165,7 @@ public:
165 165 float p1x = p1.x * PhysicSimulator::unit_scale; float p1y = -p1.y * PhysicSimulator::unit_scale;
166 166 float p2x = p2.x * PhysicSimulator::unit_scale; float p2y = -p2.y * PhysicSimulator::unit_scale;
167 167
168   - auto dl = getDisplayList(this, {(GLuint)gl_tex_white, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::LINES);
  168 + auto dl = getDisplayList(this, {(texture_do){(GLuint)gl_tex_white, GL_TEXTURE_2D}, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::LINES);
169 169 dl->list.push_back({{p1x, p1y, 0, 1}, {0, 0}, {color.r, color.g, color.b, color.a}});
170 170 dl->list.push_back({{p2x, p2y, 0, 1}, {0, 0}, {color.r, color.g, color.b, color.a}});
171 171 }
... ... @@ -179,7 +179,7 @@ public:
179 179 b2Vec2 p1(xf.p.x * PhysicSimulator::unit_scale, -xf.p.y * PhysicSimulator::unit_scale);
180 180 b2Vec2 p2;
181 181
182   - auto dl = getDisplayList(this, {(GLuint)gl_tex_white, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::LINES);
  182 + auto dl = getDisplayList(this, {(texture_do){(GLuint)gl_tex_white, GL_TEXTURE_2D}, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::LINES);
183 183 dl->list.push_back({{p1.x, p1.y, 0, 1}, {0, 0}, {red.r, red.g, red.b, 1.0}});
184 184 p2 = p1 + k_axisScale * xf.q.GetXAxis();
185 185 dl->list.push_back({{p2.x, p2.y, 0, 1}, {0, 0}, {red.r, red.g, red.b, 1.0}});
... ... @@ -193,7 +193,7 @@ public:
193 193 virtual void DrawPoint(const b2Vec2& p, float32 size, const b2Color& color) {
194 194 float px = p.x * PhysicSimulator::unit_scale, py = -p.y * PhysicSimulator::unit_scale;
195 195 size *= PhysicSimulator::unit_scale;
196   - auto dl = getDisplayList(this, {(GLuint)gl_tex_white, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::POINTS);
  196 + auto dl = getDisplayList(this, {(texture_do){(GLuint)gl_tex_white, GL_TEXTURE_2D}, 0, 0}, NULL, VERTEX_MAP_INFO, RenderKind::POINTS);
197 197 dl->list.push_back({{px, py, 0, 1}, {0, 0}, {color.r, color.g, color.b, color.a}});
198 198 }
199 199 };
... ...
... ... @@ -54,7 +54,6 @@ using namespace std;
54 54 #include "renderer-moderngl/RendererGL.hpp"
55 55 //#include "renderer-moderngl/TileMap.hpp"
56 56
57   -extern DisplayList* getDisplayList(RendererGL *container, GLuint tex, shader_type *shader);
58 57 extern void releaseDisplayList(DisplayList *dl);
59 58
60 59 template<class T=DisplayObject>T* userdata_to_DO(lua_State *L, int index, const char *auxclass=nullptr) {
... ...
... ... @@ -42,7 +42,7 @@ void stopDisplayList() {
42 42 DisplayList* getDisplayList(RendererGL *container) {
43 43 return getDisplayList(container, {0,0,0}, NULL, VERTEX_BASE, RenderKind::QUADS);
44 44 }
45   -DisplayList* getDisplayList(RendererGL *container, array<texture_do, DO_MAX_TEX> tex, shader_type *shader, uint8_t data_kind, RenderKind render_kind) {
  45 +DisplayList* getDisplayList(RendererGL *container, array<GLuint, DO_MAX_TEX> tex, shader_type *shader, uint8_t data_kind, RenderKind render_kind) {
46 46 if (available_dls.empty()) {
47 47 available_dls.push(new DisplayList());
48 48 }
... ... @@ -231,7 +231,7 @@ void RendererGL::resetDisplayLists() {
231 231
232 232 // DGDGDGDG: make that (optionally?) process in a second thread; making it nearly costless
233 233 void RendererGL::update() {
234   - // printf("Renderer %s needs updating\n", getRendererName());
  234 + printf("Renderer %s needs updating\n", getRendererName());
235 235
236 236 if (!manual_dl_management) {
237 237 resetDisplayLists();
... ... @@ -359,7 +359,7 @@ void RendererGL::update() {
359 359 printf("Upping vbo_elements to %d in renderer %s\n", nb_quads, getRendererName());
360 360 }
361 361 }
362   - // printf(" => %d\n", nb_quads);
  362 + printf(" => %d\n", nb_quads);
363 363 }
364 364
365 365 void RendererGL::activateCutting(mat4 cur_model, bool v) {
... ... @@ -399,7 +399,6 @@ void RendererGL::toScreen(mat4 cur_model, vec4 cur_color) {
399 399 if (zsort == SortMode::GL) glEnable(GL_DEPTH_TEST);
400 400 if (!allow_blending) glDisable(GL_BLEND);
401 401 if (premultiplied_alpha) glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
402   - if (disable_depth_writing) glDepthMask(GL_FALSE);
403 402
404 403 // Draw all display lists
405 404 int nb_vert = 0;
... ... @@ -417,10 +416,10 @@ void RendererGL::toScreen(mat4 cur_model, vec4 cur_color) {
417 416 // Bind the vertices
418 417 glBindBuffer(GL_ARRAY_BUFFER, (*dl)->vbo[0]);
419 418 tglActiveTexture(GL_TEXTURE0);
420   - tglBindTexture((*dl)->tex[0].kind, (*dl)->tex[0].tex);
421   - for (int i = 1; i < DO_MAX_TEX; i++) { if ((*dl)->tex[i].tex) {
  419 + tglBindTexture(GL_TEXTURE_2D, (*dl)->tex[0]);
  420 + for (int i = 1; i < DO_MAX_TEX; i++) { if ((*dl)->tex[i]) {
422 421 tglActiveTexture(GL_TEXTURE0 + i);
423   - tglBindTexture((*dl)->tex[i].kind, (*dl)->tex[i].tex);
  422 + tglBindTexture(GL_TEXTURE_2D, (*dl)->tex[i]);
424 423 } }
425 424 // printf("=r= binding vbo %d\n", (*dl)->vbo);
426 425 // printf("=r= binding tex %d\n", (*dl)->tex);
... ... @@ -544,7 +543,6 @@ void RendererGL::toScreen(mat4 cur_model, vec4 cur_color) {
544 543 if (zsort == SortMode::GL) glDisable(GL_DEPTH_TEST);
545 544 if (!allow_blending) glEnable(GL_BLEND);
546 545 if (premultiplied_alpha) glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
547   - if (disable_depth_writing) glDepthMask(GL_TRUE);
548 546
549 547 if (view) view->use(false);
550 548
... ...
... ... @@ -147,7 +147,7 @@ TE4SpriterImageFile::~TE4SpriterImageFile() {
147 147 void TE4SpriterImageFile::renderSprite(UniversalObjectInterface *spriteInfo) {
148 148 DORSpriter *spriter = DORSpriter::currently_processing;
149 149
150   - auto dl = getDisplayList(spriter->render_container, {texture->tex.tex, 0, 0}, spriter->shader, VERTEX_BASE + (spriter->billboarding ? VERTEX_MAP_INFO : 0) + (spriter->picking ? VERTEX_PICKING_INFO : 0), RenderKind::QUADS);
  150 + auto dl = getDisplayList(spriter->render_container, {(texture_do){texture->tex.tex, texture->tex.kind}, 0, 0}, spriter->shader, VERTEX_BASE + (spriter->billboarding ? VERTEX_MAP_INFO : 0) + (spriter->picking ? VERTEX_PICKING_INFO : 0), RenderKind::QUADS);
151 151
152 152 // Make the matrix corresponding to the shape
153 153 mat4 qm = mat4();
... ...
... ... @@ -64,7 +64,7 @@ void DORSpriterCache::releaseTexture(texture_cache* tex) {
64 64 if (it->second == tex) {
65 65 tex->used--;
66 66 if (tex->used <= 0) {
67   - printf("[SPRITER] Releasing texture %s = %d\n", it->first.c_str(), tex->tex);
  67 + printf("[SPRITER] Releasing texture %s = %d\n", it->first.c_str(), tex->tex.tex);
68 68 tex_cache.erase(it);
69 69 glDeleteTextures(1, &tex->tex.tex);
70 70 delete tex;
... ...
... ... @@ -40,9 +40,8 @@
40 40
41 41 #include <stdio.h>
42 42 struct texture_type {
43   - texture_type() { printf("NEW TEXTURE!\n"); }
44   - GLuint tex = 0;
45 43 GLenum kind = GL_TEXTURE_2D;
  44 + GLuint tex = 0;
46 45 int w = 0, h = 0;
47 46 bool no_free = false;
48 47 };
... ...