Android opengl debug callback, Android device properties, fix texture internal format
This commit is contained in:
@@ -26,6 +26,24 @@
|
|||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "..\..\..\..\engine\asset.h"
|
#include "..\..\..\..\engine\asset.h"
|
||||||
|
|
||||||
|
typedef void (*GLDEBUGPROC)(GLenum source,
|
||||||
|
GLenum type,
|
||||||
|
GLuint id,
|
||||||
|
GLenum severity,
|
||||||
|
GLsizei length,
|
||||||
|
const GLchar* message,
|
||||||
|
const void* userParam);
|
||||||
|
|
||||||
|
typedef void (*fnDebugMessageCallback)(GLDEBUGPROC callback, const void* userParam);
|
||||||
|
|
||||||
|
#define GL_DEBUG_SEVERITY_HIGH 0x9146
|
||||||
|
#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
|
||||||
|
#define GL_DEBUG_SEVERITY_LOW 0x9148
|
||||||
|
#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
|
||||||
|
|
||||||
|
#define GL_DEBUG_OUTPUT 0x92E0
|
||||||
|
#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Our saved state data.
|
* Our saved state data.
|
||||||
*/
|
*/
|
||||||
@@ -116,8 +134,10 @@ static int engine_init_display(struct engine* engine) {
|
|||||||
surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);
|
surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);
|
||||||
|
|
||||||
const EGLint attribs_test[] = {
|
const EGLint attribs_test[] = {
|
||||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||||
EGL_NONE
|
EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR,
|
||||||
|
//EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,
|
||||||
|
EGL_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT, attribs_test);
|
context = eglCreateContext(display, config, EGL_NO_CONTEXT, attribs_test);
|
||||||
@@ -138,11 +158,92 @@ static int engine_init_display(struct engine* engine) {
|
|||||||
engine->state.angle = 0;
|
engine->state.angle = 0;
|
||||||
|
|
||||||
// Check openGL on the system
|
// Check openGL on the system
|
||||||
auto opengl_info = {GL_VENDOR, GL_RENDERER, GL_VERSION/*, GL_EXTENSIONS*/};
|
auto opengl_info = { GL_VENDOR, GL_RENDERER, GL_VERSION/*, GL_EXTENSIONS*/ };
|
||||||
for (auto name : opengl_info) {
|
for (auto name : opengl_info) {
|
||||||
auto info = glGetString(name);
|
auto info = glGetString(name);
|
||||||
LOG("OpenGL Info: %s", info);
|
LOG("OpenGL Info: %s", info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* ext = (const char*) glGetString(GL_EXTENSIONS);
|
||||||
|
int ext_len = strlen(ext);
|
||||||
|
std::map<std::string, bool> ext_map;
|
||||||
|
static char ext_name[256];
|
||||||
|
int ext_name_i = 0;
|
||||||
|
for (int i = 0; i < ext_len; i++)
|
||||||
|
{
|
||||||
|
char c = ext[i];
|
||||||
|
if (c == ' ')
|
||||||
|
{
|
||||||
|
ext_map.emplace(std::string(ext_name, ext_name_i), true);
|
||||||
|
ext_name_i = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ext_name[ext_name_i++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ext_map.count("GL_KHR_debug"))
|
||||||
|
{
|
||||||
|
LOG("GL_KHR_debug supported");
|
||||||
|
auto glDebugMessageCallback = (fnDebugMessageCallback)eglGetProcAddress("glDebugMessageCallbackKHR");
|
||||||
|
if (glDebugMessageCallback)
|
||||||
|
{
|
||||||
|
LOG("glDebugMessageCallback proc found at %p", glDebugMessageCallback);
|
||||||
|
glDebugMessageCallback([](GLenum source, GLenum type, GLuint id,
|
||||||
|
GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
|
||||||
|
{
|
||||||
|
//if (severity == GL_DEBUG_SEVERITY_MEDIUM || severity == GL_DEBUG_SEVERITY_HIGH)
|
||||||
|
{
|
||||||
|
LOG("OPENGL: %.*s", length, message);
|
||||||
|
}
|
||||||
|
}, nullptr);
|
||||||
|
glEnable(GL_DEBUG_OUTPUT);
|
||||||
|
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG("glDebugMessageCallback proc NOT FOUND");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ret = -1;
|
||||||
|
FILE* file = popen("getprop", "r");
|
||||||
|
std::map<std::string, std::string> os_props;
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
char output[100];
|
||||||
|
while (fgets(output, sizeof(output), file) != nullptr)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
int l = strlen(output);
|
||||||
|
char buf[64];
|
||||||
|
int j = 0;
|
||||||
|
while (i < l && output[i] != '[') i++;
|
||||||
|
i++;
|
||||||
|
while (i < l && output[i] != ']') { buf[j++] = output[i]; i++; }
|
||||||
|
std::string key(buf, j);
|
||||||
|
j = 0;
|
||||||
|
while (i < l && output[i] != '[') i++;
|
||||||
|
i++;
|
||||||
|
while (i < l && output[i] != ']') { buf[j++] = output[i]; i++; }
|
||||||
|
os_props[key] = std::string(buf, j);
|
||||||
|
//LOG("PROP: %s -> %s", key.c_str(), os_props[key].c_str());
|
||||||
|
}
|
||||||
|
pclose(file);
|
||||||
|
}
|
||||||
|
LOG("PROP Android Version: %s", os_props["ro.build.version.release"].c_str());
|
||||||
|
LOG("PROP Android SDK: %s", os_props["ro.build.version.sdk"].c_str());
|
||||||
|
LOG("PROP Country Code: %s", os_props["ro.csc.country_code"].c_str());
|
||||||
|
LOG("PROP ABI: %s", os_props["ro.product.cpu.abilist"].c_str());
|
||||||
|
LOG("PROP Brand: %s", os_props["ro.product.brand"].c_str());
|
||||||
|
LOG("PROP Maker: %s", os_props["ro.product.manufacturer"].c_str());
|
||||||
|
LOG("PROP Mode: %s", os_props["ro.product.model"].c_str());
|
||||||
|
//LOG("PROP: %s", os_props[""].c_str());
|
||||||
|
//LOG("PROP: %s", os_props[""].c_str());
|
||||||
|
//LOG("PROP: %s", os_props[""].c_str());
|
||||||
|
|
||||||
// Initialize GL state.
|
// Initialize GL state.
|
||||||
//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||||
//glEnable(GL_CULL_FACE);
|
//glEnable(GL_CULL_FACE);
|
||||||
@@ -203,7 +304,7 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
|
|||||||
struct engine* engine = (struct engine*)app->userData;
|
struct engine* engine = (struct engine*)app->userData;
|
||||||
float x = AMotionEvent_getX(event, 0);
|
float x = AMotionEvent_getX(event, 0);
|
||||||
float y = AMotionEvent_getY(event, 0);
|
float y = AMotionEvent_getY(event, 0);
|
||||||
LOG("event source: %d", AInputEvent_getSource(event));
|
//LOG("event source: %d", AInputEvent_getSource(event));
|
||||||
MouseEvent e;
|
MouseEvent e;
|
||||||
int32_t eventType = AInputEvent_getType(event);
|
int32_t eventType = AInputEvent_getType(event);
|
||||||
switch (eventType) {
|
switch (eventType) {
|
||||||
@@ -225,7 +326,7 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
|
|||||||
App::I.mouse_move(x, y);
|
App::I.mouse_move(x, y);
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
LOG("motion action: %d", action);
|
//LOG("motion action: %d", action);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -459,16 +459,17 @@ void App::init()
|
|||||||
{ GL_DEBUG_SEVERITY_MEDIUM, FOREGROUND_GREEN | FOREGROUND_INTENSITY },
|
{ GL_DEBUG_SEVERITY_MEDIUM, FOREGROUND_GREEN | FOREGROUND_INTENSITY },
|
||||||
{ GL_DEBUG_SEVERITY_HIGH, FOREGROUND_RED | FOREGROUND_INTENSITY },
|
{ GL_DEBUG_SEVERITY_HIGH, FOREGROUND_RED | FOREGROUND_INTENSITY },
|
||||||
};
|
};
|
||||||
if (severity == GL_DEBUG_SEVERITY_MEDIUM || severity == GL_DEBUG_SEVERITY_HIGH)
|
if (severity == GL_DEBUG_SEVERITY_MEDIUM || severity == GL_DEBUG_SEVERITY_HIGH || severity == GL_DEBUG_SEVERITY_LOW)
|
||||||
{
|
{
|
||||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors[severity]);
|
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors[severity]);
|
||||||
LOG("%.*s", length, message);
|
LOG("OPENGL: %.*s", length, message);
|
||||||
FlushConsoleInputBuffer(GetStdHandle(STD_OUTPUT_HANDLE));
|
FlushConsoleInputBuffer(GetStdHandle(STD_OUTPUT_HANDLE));
|
||||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), info.wAttributes);
|
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), info.wAttributes);
|
||||||
__debugbreak();
|
// __debugbreak();
|
||||||
}
|
}
|
||||||
}, nullptr);
|
}, nullptr);
|
||||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
glEnable(GL_DEBUG_OUTPUT);
|
||||||
|
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//int n;
|
//int n;
|
||||||
@@ -550,7 +551,7 @@ bool App::mouse_down(int button, float x, float y)
|
|||||||
e.m_type = button ? kEventType::MouseDownR : kEventType::MouseDownL;
|
e.m_type = button ? kEventType::MouseDownR : kEventType::MouseDownL;
|
||||||
e.m_pos = { x / zoom, y / zoom };
|
e.m_pos = { x / zoom, y / zoom };
|
||||||
auto ret = layout[main_id]->on_event(&e);
|
auto ret = layout[main_id]->on_event(&e);
|
||||||
LOG("mouse click button%d pos %f %f", button, x, y);
|
//LOG("mouse click button%d pos %f %f", button, x, y);
|
||||||
|
|
||||||
// if (popup)
|
// if (popup)
|
||||||
// {
|
// {
|
||||||
@@ -584,7 +585,7 @@ bool App::mouse_up(int button, float x, float y)
|
|||||||
e.m_pos = { x / zoom, y / zoom };
|
e.m_pos = { x / zoom, y / zoom };
|
||||||
auto ret = layout[main_id]->on_event(&e);
|
auto ret = layout[main_id]->on_event(&e);
|
||||||
layout[main_id]->update();
|
layout[main_id]->update();
|
||||||
LOG("mouse up button%d pos %f %f", button, x, y);
|
//LOG("mouse up button%d pos %f %f", button, x, y);
|
||||||
return ret == kEventResult::Consumed;
|
return ret == kEventResult::Consumed;
|
||||||
}
|
}
|
||||||
bool App::key_down(int key)
|
bool App::key_down(int key)
|
||||||
@@ -594,7 +595,7 @@ bool App::key_down(int key)
|
|||||||
e.m_key = key;
|
e.m_key = key;
|
||||||
auto ret = layout[main_id]->on_event(&e);
|
auto ret = layout[main_id]->on_event(&e);
|
||||||
layout[main_id]->update();
|
layout[main_id]->update();
|
||||||
LOG("key down %d '%c'", key, key);
|
//LOG("key down %d '%c'", key, key);
|
||||||
return ret == kEventResult::Consumed;
|
return ret == kEventResult::Consumed;
|
||||||
}
|
}
|
||||||
bool App::key_up(int key)
|
bool App::key_up(int key)
|
||||||
@@ -604,7 +605,7 @@ bool App::key_up(int key)
|
|||||||
e.m_key = key;
|
e.m_key = key;
|
||||||
auto ret = layout[main_id]->on_event(&e);
|
auto ret = layout[main_id]->on_event(&e);
|
||||||
layout[main_id]->update();
|
layout[main_id]->update();
|
||||||
LOG("key up %d '%c'", key, key);
|
//LOG("key up %d '%c'", key, key);
|
||||||
return ret == kEventResult::Consumed;
|
return ret == kEventResult::Consumed;
|
||||||
}
|
}
|
||||||
bool App::key_char(int key)
|
bool App::key_char(int key)
|
||||||
@@ -614,6 +615,6 @@ bool App::key_char(int key)
|
|||||||
e.m_key = key;
|
e.m_key = key;
|
||||||
auto ret = layout[main_id]->on_event(&e);
|
auto ret = layout[main_id]->on_event(&e);
|
||||||
layout[main_id]->update();
|
layout[main_id]->update();
|
||||||
LOG("key up %d '%c'", key, key);
|
//LOG("key up %d '%c'", key, key);
|
||||||
return ret == kEventResult::Consumed;
|
return ret == kEventResult::Consumed;
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ AAssetManager* Asset::m_am;
|
|||||||
|
|
||||||
bool Asset::open(const char* path)
|
bool Asset::open(const char* path)
|
||||||
{
|
{
|
||||||
LOG("Asset::open %s", path);
|
//LOG("Asset::open %s", path);
|
||||||
m_current_path = path;
|
m_current_path = path;
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
if (!(m_asset = AAssetManager_open(m_am, path, AASSET_MODE_RANDOM)))
|
if (!(m_asset = AAssetManager_open(m_am, path, AASSET_MODE_RANDOM)))
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ bool Font::load(const char* ttf, int font_size)
|
|||||||
auto bitmap = std::make_unique<uint8_t[]>(w*h);
|
auto bitmap = std::make_unique<uint8_t[]>(w*h);
|
||||||
chars.resize(num_chars);
|
chars.resize(num_chars);
|
||||||
int ret = stbtt_BakeFontBitmap(file.m_data, 0, (float)font_size, bitmap.get(), w, h, start_char, num_chars, chars.data());
|
int ret = stbtt_BakeFontBitmap(file.m_data, 0, (float)font_size, bitmap.get(), w, h, start_char, num_chars, chars.data());
|
||||||
font_tex.create(w, h, GL_RED, bitmap.get());
|
font_tex.create(w, h, GL_R8, GL_RED, bitmap.get());
|
||||||
file.close();
|
file.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1529,11 +1529,11 @@ public:
|
|||||||
::FindClose(hFind);
|
::FindClose(hFind);
|
||||||
}
|
}
|
||||||
#elif __ANDROID__
|
#elif __ANDROID__
|
||||||
LOG("listing brushes");
|
//LOG("listing brushes");
|
||||||
AAssetDir* dir = AAssetManager_openDir(Asset::m_am, "data/Icons");
|
AAssetDir* dir = AAssetManager_openDir(Asset::m_am, "data/Icons");
|
||||||
while (const char* name = AAssetDir_getNextFileName(dir))
|
while (const char* name = AAssetDir_getNextFileName(dir))
|
||||||
{
|
{
|
||||||
LOG("asset: %s", name);
|
//LOG("asset: %s", name);
|
||||||
names.push_back(name);
|
names.push_back(name);
|
||||||
}
|
}
|
||||||
AAssetDir_close(dir);
|
AAssetDir_close(dir);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#elif __ANDROID__
|
#elif __ANDROID__
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
|
#include <EGL/eglext.h>
|
||||||
#include <GLES3/gl3.h>
|
#include <GLES3/gl3.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ bool TextureManager::load(const char* path)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureManager::assign(uint16_t id, GLuint tex, int w/* = -1*/, int h/* = -1*/, GLuint format/* = GL_RGBA*/)
|
void TextureManager::assign(uint16_t id, GLuint tex, int w/* = -1*/, int h/* = -1*/, GLuint internal_format/* = GL_RGBA8*/, GLuint format/* = GL_RGBA*/)
|
||||||
{
|
{
|
||||||
m_textures[id].assign(tex, w, h, format);
|
m_textures[id].assign(tex, w, h, internal_format, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture2D& TextureManager::get(uint16_t id)
|
Texture2D& TextureManager::get(uint16_t id)
|
||||||
@@ -24,29 +24,32 @@ Texture2D& TextureManager::get(uint16_t id)
|
|||||||
return m_textures[id];
|
return m_textures[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Texture2D::create(int width, int height, GLint format, const uint8_t* data)
|
bool Texture2D::create(int width, int height, GLint internal_format, GLint format, const uint8_t* data)
|
||||||
{
|
{
|
||||||
m_width = width;
|
m_width = width;
|
||||||
m_height = height;
|
m_height = height;
|
||||||
m_format = format;
|
m_format = format;
|
||||||
|
m_iformat = internal_format;
|
||||||
glGenTextures(1, &m_tex);
|
glGenTextures(1, &m_tex);
|
||||||
bind();
|
bind();
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
||||||
unbind();
|
unbind();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool Texture2D::create(const ui::Image& img)
|
bool Texture2D::create(const ui::Image& img)
|
||||||
{
|
{
|
||||||
static GLint formats[] = { GL_RED, GL_RG, GL_RGB, GL_RGBA };
|
static GLint formats[] = { GL_RED, GL_RG, GL_RGB, GL_RGBA };
|
||||||
return create(img.width, img.height, formats[img.comp - 1], img.data());
|
static GLint iformats[] = { GL_R8, GL_RG8, GL_RGB8, GL_RGBA8 };
|
||||||
|
return create(img.width, img.height, iformats[img.comp - 1], formats[img.comp - 1], img.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture2D::assign(GLuint tex, int w/* = -1*/, int h/* = -1*/, GLuint format/* = GL_RGBA*/)
|
void Texture2D::assign(GLuint tex, int w/* = -1*/, int h/* = -1*/, GLuint internal_format/* = GL_RGBA8*/, GLuint format/* = GL_RGBA*/)
|
||||||
{
|
{
|
||||||
m_tex = tex;
|
m_tex = tex;
|
||||||
m_width = w;
|
m_width = w;
|
||||||
m_height = h;
|
m_height = h;
|
||||||
m_format = format;
|
m_format = format;
|
||||||
|
m_iformat = internal_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Texture2D::load(std::string filename)
|
bool Texture2D::load(std::string filename)
|
||||||
|
|||||||
@@ -7,10 +7,11 @@ class Texture2D
|
|||||||
int m_width;
|
int m_width;
|
||||||
int m_height;
|
int m_height;
|
||||||
GLint m_format;
|
GLint m_format;
|
||||||
|
GLint m_iformat;
|
||||||
public:
|
public:
|
||||||
bool create(int width, int height, GLint format = GL_RGBA, const uint8_t* data = nullptr);
|
bool create(int width, int height, GLint internal_format, GLint format = GL_RGBA, const uint8_t* data = nullptr);
|
||||||
bool create(const ui::Image& img);
|
bool create(const ui::Image& img);
|
||||||
void assign(GLuint tex, int w = -1, int h = -1, GLuint format = GL_RGBA);
|
void assign(GLuint tex, int w = -1, int h = -1, GLuint internal_format = GL_RGBA8, GLuint format = GL_RGBA);
|
||||||
bool load(std::string filename);
|
bool load(std::string filename);
|
||||||
void destroy() { glDeleteTextures(1, &m_tex); }
|
void destroy() { glDeleteTextures(1, &m_tex); }
|
||||||
void bind() const { glBindTexture(GL_TEXTURE_2D, m_tex); }
|
void bind() const { glBindTexture(GL_TEXTURE_2D, m_tex); }
|
||||||
@@ -37,6 +38,6 @@ class TextureManager
|
|||||||
public:
|
public:
|
||||||
static std::map<uint16_t, Texture2D> m_textures;
|
static std::map<uint16_t, Texture2D> m_textures;
|
||||||
static bool load(const char* path);
|
static bool load(const char* path);
|
||||||
static void assign(uint16_t id, GLuint tex, int w = -1, int h = -1, GLuint format = GL_RGBA);
|
static void assign(uint16_t id, GLuint tex, int w = -1, int h = -1, GLuint internal_format = GL_RGBA8, GLuint format = GL_RGBA);
|
||||||
static Texture2D& get(uint16_t id);
|
static Texture2D& get(uint16_t id);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,14 +12,7 @@ glm::vec4 rand_color();
|
|||||||
glm::vec3 convert_hsv2rgb(const glm::vec3 c);
|
glm::vec3 convert_hsv2rgb(const glm::vec3 c);
|
||||||
glm::vec3 convert_rgb2hsv(const glm::vec3 c);
|
glm::vec3 convert_rgb2hsv(const glm::vec3 c);
|
||||||
|
|
||||||
//void check_OpenGLError(const char* stmt, const char* fname, int line)
|
void check_OpenGLError(const char* stmt, const char* fname, int line);
|
||||||
//{
|
|
||||||
// GLenum err;
|
|
||||||
// while ((err = glGetError()) != GL_NO_ERROR)
|
|
||||||
// {
|
|
||||||
// //LOG("OpenGL error %08x (%s), at %s:%i - for %s", err, gluErrorString(err), fname, line, stmt);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
template<typename T, int N> struct cbuffer
|
template<typename T, int N> struct cbuffer
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user