#include "ofGLUtils.h"
#include <set>
#include "ofGLProgrammableRenderer.h"
#include "ofGraphics.h"
#include "ofShader.h"
#include "ofGraphicsBaseTypes.h"
#include "ofRendererCollection.h"
#include "ofGLRenderer.h"
#include "ofPixels.h"
#include "ofLog.h"
#include "ofGraphicsConstants.h"
using namespace std;
int ofGetGlInternalFormat(const ofPixels& pixels) {
return ofGetGLInternalFormat(pixels);
}
int ofGetGlInternalFormat(const ofShortPixels& pixels) {
return ofGetGLInternalFormat(pixels);
}
int ofGetGlInternalFormat(const ofFloatPixels& pixels) {
return ofGetGLInternalFormat(pixels);
}
std::string ofGetGlInternalFormatName(int glInternalFormat) {
return ofGetGLInternalFormatName(glInternalFormat);
}
int ofGetGlTypeFromInternal(int glInternalFormat) {
return ofGetGLTypeFromInternal(glInternalFormat);
}
int ofGetGlType(const ofPixels & pixels) {
return ofGetGLType(pixels);
}
int ofGetGlType(const ofShortPixels & pixels) {
return ofGetGLType(pixels);
}
int ofGetGlType(const ofFloatPixels & pixels) {
return ofGetGLType(pixels);
}
int ofGetGLInternalFormat(const ofPixels& pixels) {
return ofGetGLInternalFormatFromPixelFormat(pixels.getPixelFormat());
}
int ofGetGLInternalFormat(const ofShortPixels& pixels) {
#ifndef TARGET_OPENGLES
switch(pixels.getNumChannels()) {
case 3: return GL_RGB16;
case 4: return GL_RGBA16;
case 2:
if(ofIsGLProgrammableRenderer()){
return GL_RG16;
}else{
return GL_LUMINANCE16_ALPHA16;
}
default:
if(ofIsGLProgrammableRenderer()){
return GL_R16;
}else{
return GL_LUMINANCE16;
}
}
#else
ofLogWarning("ofGLUtils") << "ofGetGLInternalFormat(): 16bit textures are not supported in OpenGL ES";
switch(pixels.getNumChannels()) {
case 3: return GL_RGB;
case 4: return GL_RGBA;
case 2:
return GL_LUMINANCE_ALPHA;
default:
return GL_LUMINANCE;
}
#endif
}
int ofGetGLInternalFormat(const ofFloatPixels& pixels) {
#ifndef TARGET_OPENGLES
switch(pixels.getNumChannels()) {
case 3: return GL_RGB32F;
case 4: return GL_RGBA32F;
case 2:
if(ofIsGLProgrammableRenderer()){
return GL_RG32F;
}else{
return GL_LUMINANCE_ALPHA32F_ARB;
}
default:
if(ofIsGLProgrammableRenderer()){
return GL_R32F;
}else{
return GL_LUMINANCE32F_ARB;
}
}
#else
ofLogWarning("ofGLUtils") << "ofGetGLInternalFormat(): float textures not supported in OpenGL ES";
switch(pixels.getNumChannels()) {
case 3: return GL_RGB;
case 4: return GL_RGBA;
case 2:
return GL_LUMINANCE_ALPHA;
default:
return GL_LUMINANCE;
}
#endif
}
string ofGetGLInternalFormatName(int glInternalFormat) {
switch(glInternalFormat) {
case GL_RGBA: return "GL_RGBA";
#ifndef TARGET_OPENGLES
case GL_RGBA8: return "GL_RGBA8";
#endif
case GL_RGB: return "GL_RGB";
#ifndef TARGET_OPENGLES
case GL_RGB8: return "GL_RGB8";
#endif
case GL_LUMINANCE: return "GL_LUMINANCE";
#ifndef TARGET_OPENGLES
case GL_LUMINANCE8: return "GL_LUMINANCE8";
case GL_RGBA16: return "GL_RGBA16";
case GL_RGB16: return "GL_RGB16";
case GL_LUMINANCE16: return "GL_LUMINANCE16";
case GL_RGBA32F_ARB: return "GL_RGBA32F_ARB";
case GL_RGB32F_ARB: return "GL_RGB32F_ARB";
case GL_LUMINANCE32F_ARB: return "GL_LUMINANCE32F_ARB";
#endif
case GL_LUMINANCE_ALPHA: return "GL_LUMINANCE_ALPHA";
#ifndef TARGET_OPENGLES
case GL_LUMINANCE8_ALPHA8: return "GL_LUMINANCE8_ALPHA8";
#endif
default: return "unknown glInternalFormat";
}
}
int ofGetGLFormatFromInternal(int glInternalFormat){
switch(glInternalFormat) {
case GL_RGBA:
#ifndef TARGET_OPENGLES
case GL_RGBA8:
case GL_RGBA16:
case GL_RGBA16F:
case GL_RGBA16I:
case GL_RGBA16UI:
case GL_RGBA32F:
case GL_RGBA32I:
case GL_RGBA32UI:
#endif
return GL_RGBA;
case GL_RGB:
#ifndef TARGET_OPENGLES
case GL_RGB8:
case GL_RGB16:
case GL_RGB16F:
case GL_RGB16I:
case GL_RGB16UI:
case GL_RGB32F:
case GL_RGB32I:
case GL_RGB32UI:
#endif
return GL_RGB;
case GL_LUMINANCE:
#ifndef TARGET_OPENGLES
case GL_LUMINANCE8:
case GL_LUMINANCE16:
case GL_LUMINANCE32F_ARB:
#endif
return GL_LUMINANCE;
case GL_LUMINANCE_ALPHA:
#ifndef TARGET_OPENGLES
case GL_LUMINANCE8_ALPHA8:
case GL_LUMINANCE16_ALPHA16:
case GL_LUMINANCE_ALPHA32F_ARB:
#endif
return GL_LUMINANCE_ALPHA;
case GL_DEPTH_STENCIL:
return GL_DEPTH_STENCIL;
case GL_DEPTH_COMPONENT:
#ifndef TARGET_OPENGLES
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32:
#endif
return GL_DEPTH_COMPONENT;
case GL_STENCIL_INDEX:
return GL_STENCIL_INDEX;
#ifndef TARGET_OPENGLES
case GL_R8:
case GL_R16:
case GL_R16I:
case GL_R16UI:
case GL_R16F:
case GL_R32F:
case GL_R32I:
case GL_R32UI:
return GL_RED;
case GL_RG8:
case GL_RG16:
case GL_RG16I:
case GL_RG16UI:
case GL_RG16F:
case GL_RG32F:
case GL_RG32I:
case GL_RG32UI:
return GL_RG;
#endif
#ifndef TARGET_OPENGLES
case GL_ALPHA8:
#endif
case GL_ALPHA:
return GL_ALPHA;
default:
ofLogError("ofGLUtils") << "ofGetGLFormatFromInternal(): unknown internal format " << glInternalFormat << ", returning GL_RGBA";
return GL_RGBA;
}
}
int ofGetGLTypeFromInternal(int glInternalFormat){
switch(glInternalFormat) {
case GL_RGB:
case GL_RGBA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
case GL_ALPHA:
#ifndef TARGET_OPENGLES
case GL_LUMINANCE8:
case GL_LUMINANCE8_ALPHA8:
case GL_R8:
case GL_RG8:
case GL_RGB8:
case GL_RGBA8:
case GL_ALPHA8:
#endif
return GL_UNSIGNED_BYTE;
#if !defined(TARGET_OPENGLES) && defined(GL_RGB565)
case GL_RGB565:
return GL_UNSIGNED_SHORT_5_6_5;
break;
#endif
#ifndef TARGET_OPENGLES
case GL_LUMINANCE32F_ARB:
case GL_LUMINANCE_ALPHA32F_ARB:
case GL_R32F:
case GL_RG32F:
case GL_RGB32F:
case GL_RGBA32F:
return GL_FLOAT;
case GL_R16F:
case GL_RG16F:
case GL_RGB16F:
case GL_RGBA16F:
case GL_LUMINANCE16:
case GL_LUMINANCE16_ALPHA16:
case GL_R16:
case GL_RG16:
case GL_RGB16:
case GL_RGBA16:
return GL_HALF_FLOAT;
#endif
case GL_DEPTH_STENCIL:
return GL_UNSIGNED_INT_24_8;
case GL_DEPTH_COMPONENT:
#ifndef TARGET_OPENGLES
case GL_DEPTH_COMPONENT16:
case GL_R16UI:
case GL_RG16UI:
case GL_RGB16UI:
case GL_RGBA16UI:
#endif
return GL_UNSIGNED_SHORT;
#ifndef TARGET_OPENGLES
case GL_R16I:
case GL_RG16I:
case GL_RGB16I:
case GL_RGBA16I:
return GL_SHORT;
#endif
#ifndef TARGET_OPENGLES
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32:
case GL_R32UI:
case GL_RG32UI:
case GL_RGB32UI:
case GL_RGBA32UI:
return GL_UNSIGNED_INT;
#endif
#ifndef TARGET_OPENGLES
case GL_R32I:
case GL_RG32I:
case GL_RGB32I:
case GL_RGBA32I:
return GL_INT;
#endif
case GL_STENCIL_INDEX:
return GL_UNSIGNED_BYTE;
default:
ofLogError("ofGLUtils") << "ofGetGLTypeFromInternal(): unknown internal format " << glInternalFormat << ", returning GL_UNSIGNED_BYTE";
return GL_UNSIGNED_BYTE;
}
}
int ofGetGLType(const ofPixels & pixels) {
#ifndef TARGET_OPENGLES
if(pixels.getPixelFormat() == OF_PIXELS_RGB565){
return GL_UNSIGNED_SHORT_5_6_5;
}else{
#endif
return GL_UNSIGNED_BYTE;
#ifndef TARGET_OPENGLES
}
#endif
}
int ofGetGLType(const ofShortPixels & pixels) {
return GL_UNSIGNED_SHORT;
}
int ofGetGLType(const ofFloatPixels & pixels) {
return GL_FLOAT;
}
ofImageType ofGetImageTypeFromGLType(int glType){
switch(glType){
case GL_LUMINANCE:
#ifndef TARGET_OPENGLES
case GL_LUMINANCE8:
case GL_LUMINANCE16:
case GL_LUMINANCE32F_ARB:
case GL_R8:
case GL_R16:
case GL_R16F:
case GL_R16I:
case GL_R16UI:
case GL_R32F:
case GL_R32I:
case GL_R32UI:
case GL_DEPTH_COMPONENT32F:
case GL_DEPTH_COMPONENT32:
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT:
#endif
return OF_IMAGE_GRAYSCALE;
case GL_RGB:
#ifndef TARGET_OPENGLES
case GL_RGB8:
case GL_RGB16:
case GL_RGB16F:
case GL_RGB16I:
case GL_RGB16UI:
case GL_RGB32F:
case GL_RGB32I:
case GL_RGB32UI:
#endif
return OF_IMAGE_COLOR;
case GL_RGBA:
#ifndef TARGET_OPENGLES
case GL_RGBA8:
case GL_RGBA16:
case GL_RGBA16F:
case GL_RGBA16I:
case GL_RGBA16UI:
case GL_RGBA32F:
case GL_RGBA32I:
case GL_RGBA32UI:
#endif
return OF_IMAGE_COLOR_ALPHA;
}
return OF_IMAGE_UNDEFINED;
}
GLuint ofGetGLPolyMode(ofPolyRenderMode mode){
#ifndef TARGET_OPENGLES
switch(mode){
case(OF_MESH_POINTS):
return GL_POINT;
break;
case(OF_MESH_WIREFRAME):
return GL_LINE;
break;
case(OF_MESH_FILL):
return GL_FILL;
break;
default:
ofLogError("ofGLUtils") << "ofGetGLPolyMode(): unknown OF poly mode " << ofToString(mode) << ", returning GL_FILL";
return GL_FILL;
break;
}
#else
return 0;
#endif
}
ofPolyRenderMode ofGetOFPolyMode(GLuint mode){
#ifndef TARGET_OPENGLES
switch(mode){
case(GL_POINT):
return OF_MESH_POINTS;
break;
case(GL_LINE):
return OF_MESH_WIREFRAME;
break;
case(GL_FILL):
return OF_MESH_FILL;
break;
default:
ofLogError("ofGLUtils") << "ofGetOFPolyMode(): unknown GL poly mode " << ofToString(mode) << ", returning OF_MESH_FILL";
return OF_MESH_FILL;
break;
}
#else
return OF_MESH_FILL;
#endif
}
GLuint ofGetGLPrimitiveMode(ofPrimitiveMode mode){
switch(mode){
case OF_PRIMITIVE_TRIANGLES:
return GL_TRIANGLES;
break;
case OF_PRIMITIVE_TRIANGLE_STRIP:
return GL_TRIANGLE_STRIP;
break;
case OF_PRIMITIVE_TRIANGLE_FAN:
return GL_TRIANGLE_FAN;
break;
case OF_PRIMITIVE_LINES:
return GL_LINES;
break;
case OF_PRIMITIVE_LINE_STRIP:
return GL_LINE_STRIP;
break;
case OF_PRIMITIVE_LINE_LOOP:
return GL_LINE_LOOP;
break;
case OF_PRIMITIVE_POINTS:
return GL_POINTS;
break;
#ifndef TARGET_OPENGLES
case OF_PRIMITIVE_LINES_ADJACENCY:
return GL_LINES_ADJACENCY;
break;
case OF_PRIMITIVE_LINE_STRIP_ADJACENCY:
return GL_LINE_STRIP_ADJACENCY;
break;
case OF_PRIMITIVE_TRIANGLES_ADJACENCY:
return GL_TRIANGLES_ADJACENCY;
break;
case OF_PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
return GL_TRIANGLE_STRIP_ADJACENCY;
break;
case OF_PRIMITIVE_PATCHES:
return GL_PATCHES;
break;
#endif
default:
ofLogError("ofGLUtils") << "ofGetGLPrimitiveMode(): unknown OF primitive mode " << ofToString(mode) << ", returning GL_TRIANGLES";
return GL_TRIANGLES;
break;
}
}
ofPrimitiveMode ofGetOFPrimitiveMode(GLuint mode){
switch(mode){
case GL_TRIANGLES:
return OF_PRIMITIVE_TRIANGLES;
break;
case GL_TRIANGLE_STRIP:
return OF_PRIMITIVE_TRIANGLE_STRIP;
break;
case GL_TRIANGLE_FAN:
return OF_PRIMITIVE_TRIANGLE_FAN;
break;
case GL_LINES:
return OF_PRIMITIVE_LINES;
break;
case GL_LINE_STRIP:
return OF_PRIMITIVE_LINE_STRIP;
break;
case GL_LINE_LOOP:
return OF_PRIMITIVE_LINE_LOOP;
break;
case GL_POINTS:
return OF_PRIMITIVE_POINTS;
break;
#ifndef TARGET_OPENGLES
case GL_LINES_ADJACENCY:
return OF_PRIMITIVE_LINES_ADJACENCY;
break;
case GL_LINE_STRIP_ADJACENCY:
return OF_PRIMITIVE_LINE_STRIP_ADJACENCY;
break;
case GL_TRIANGLES_ADJACENCY:
return OF_PRIMITIVE_TRIANGLES_ADJACENCY;
break;
case GL_TRIANGLE_STRIP_ADJACENCY:
return OF_PRIMITIVE_TRIANGLE_STRIP_ADJACENCY;
break;
case GL_PATCHES:
return OF_PRIMITIVE_PATCHES;
break;
#endif
default:
ofLogError("ofGLUtils") << "ofGetOFPrimitiveMode(): unknown GL primitive mode " << ofToString(mode) << ", returning OF_PRIMITIVE_TRIANGLES";
return OF_PRIMITIVE_TRIANGLES;
break;
}
}
int ofGetGLInternalFormatFromPixelFormat(ofPixelFormat pixelFormat){
switch(pixelFormat){
case OF_PIXELS_BGRA:
case OF_PIXELS_RGBA:
#ifndef TARGET_OPENGLES
return GL_RGBA8;
#else
return GL_RGBA;
#endif
case OF_PIXELS_RGB:
case OF_PIXELS_BGR:
#ifndef TARGET_OPENGLES
return GL_RGB8;
#else
return GL_RGB;
#endif
case OF_PIXELS_RGB565:
#if defined(TARGET_ANDROID) || defined(TARGET_RASPBERRY_PI_LEGACY)
return GL_RGB565_OES;
#elif defined(GL_RGB565)
return GL_RGB565;
#else
return GL_RGB;
#endif
case OF_PIXELS_GRAY:
case OF_PIXELS_NV12:
case OF_PIXELS_NV21:
case OF_PIXELS_YV12:
case OF_PIXELS_I420:
case OF_PIXELS_Y:
case OF_PIXELS_U:
case OF_PIXELS_V:
#ifndef TARGET_OPENGLES
if(ofIsGLProgrammableRenderer()){
return GL_R8;
}else{
#endif
return GL_LUMINANCE;
#ifndef TARGET_OPENGLES
}
#endif
case OF_PIXELS_GRAY_ALPHA:
case OF_PIXELS_YUY2:
case OF_PIXELS_UV:
case OF_PIXELS_VU:
#ifndef TARGET_OPENGLES
if(ofIsGLProgrammableRenderer()){
return GL_RG8;
}else{
#endif
return GL_LUMINANCE_ALPHA;
#ifndef TARGET_OPENGLES
}
#endif
default:
ofLogError("ofGLUtils") << "ofGetGLInternalFormatFromPixelFormat(): unknown OF pixel format "
<< ofToString(pixelFormat) << ", returning GL_RGBA";
return GL_RGBA;
}
}
int ofGetGLFormatFromPixelFormat(ofPixelFormat pixelFormat){
switch(pixelFormat){
case OF_PIXELS_BGRA:
#ifdef TARGET_OPENGLES
return GL_BGRA_EXT;
#else
return GL_BGRA;
#endif
case OF_PIXELS_RGB:
return GL_RGB;
case OF_PIXELS_BGR:
#ifdef TARGET_OPENGLES
return GL_RGB;
#else
return GL_BGR;
#endif
case OF_PIXELS_RGBA:
return GL_RGBA;
case OF_PIXELS_RGB565:
return GL_RGB;
case OF_PIXELS_GRAY:
case OF_PIXELS_NV12:
case OF_PIXELS_NV21:
case OF_PIXELS_YV12:
case OF_PIXELS_I420:
case OF_PIXELS_Y:
case OF_PIXELS_U:
case OF_PIXELS_V:
#ifndef TARGET_OPENGLES
if(ofIsGLProgrammableRenderer()){
return GL_RED;
}else{
#endif
return GL_LUMINANCE;
#ifndef TARGET_OPENGLES
}
#endif
case OF_PIXELS_GRAY_ALPHA:
case OF_PIXELS_YUY2:
case OF_PIXELS_UV:
case OF_PIXELS_VU:
#ifndef TARGET_OPENGLES
if(ofIsGLProgrammableRenderer()){
return GL_RG;
}else{
#endif
return GL_LUMINANCE_ALPHA;
#ifndef TARGET_OPENGLES
}
#endif
default:
#ifndef TARGET_OPENGLES
if(ofIsGLProgrammableRenderer()){
ofLogError("ofGLUtils") << "ofGetGLFormatFromPixelFormat(): unknown OF pixel format "
<< ofToString(pixelFormat) << ", returning GL_RED";
return GL_RED;
}else{
#endif
ofLogError("ofGLUtils") << "ofGetGLFormatFromPixelFormat(): unknown OF pixel format "
<< ofToString(pixelFormat) << ", returning GL_LUMINANCE";
return GL_LUMINANCE;
#ifndef TARGET_OPENGLES
}
#endif
}
}
int ofGetNumChannelsFromGLFormat(int glFormat){
switch(glFormat){
case GL_RGB:
return 3;
case GL_RGBA:
return 4;
case GL_LUMINANCE:
return 1;
case GL_LUMINANCE_ALPHA:
return 2;
#ifndef TARGET_OPENGLES
case GL_RED:
return 1;
case GL_RG:
return 2;
#endif
default:
return 1;
}
}
int ofGetBytesPerChannelFromGLType(int glType){
switch(glType) {
case GL_UNSIGNED_BYTE:
return 1;
case GL_UNSIGNED_SHORT:
return 2;
#if !defined(TARGET_OPENGLES) && defined(GL_RGB565)
case GL_UNSIGNED_SHORT_5_6_5:
return 2;
#endif
#ifndef TARGET_OPENGLES
case GL_FLOAT:
return 4;
#endif
case GL_UNSIGNED_INT_24_8:
return 4;
#ifndef TARGET_OPENGLES
case GL_UNSIGNED_INT:
return 4;
#endif
case GL_HALF_FLOAT:
return 2;
default:
ofLogError("ofGetBytesPerChannelFromGLType") << "unknown type returning 1";
return 1;
}
}
#define OF_ROUND_UP_2(num) (((num)+1)&~1)
#define OF_ROUND_UP_4(num) (((num)+3)&~3)
#define OF_ROUND_UP_8(num) (((num)+7)&~7)
void ofSetPixelStoreiAlignment(GLenum pname, int w, int bpc, int numChannels){
int stride = w * numChannels * bpc;
ofSetPixelStoreiAlignment(pname,stride);
}
void ofSetPixelStoreiAlignment(GLenum pname, int stride){
if (OF_ROUND_UP_8 (stride) == stride) {
glPixelStorei (pname, 8);
} else if (OF_ROUND_UP_4 (stride) == stride) {
glPixelStorei (pname, 4);
} else if (OF_ROUND_UP_2 (stride) == stride) {
glPixelStorei (pname, 2);
} else {
glPixelStorei (pname, 1);
}
}
vector<string> ofGLSupportedExtensions(){
#ifdef TARGET_OPENGLES
char* extensions = (char*)glGetString(GL_EXTENSIONS);
if(extensions){
string extensions_str = extensions;
return ofSplitString(extensions_str," ");
}else{
return vector<string>();
}
#else
int numExtensions=0;
glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
std::vector<std::string> extensions;
for(int i=0;i<numExtensions;i++){
char* extension = (char*)glGetStringi(GL_EXTENSIONS, i);
if(extension){
extensions.emplace_back(extension);
}
}
return extensions;
#endif
}
bool ofGLCheckExtension(string searchName){
#if defined( TARGET_OPENGLES )
vector<string> extensionsList = ofGLSupportedExtensions();
set<string> extensionsSet;
extensionsSet.insert(extensionsList.begin(),extensionsList.end());
return extensionsSet.find(searchName)!=extensionsSet.end();
#else
return glewIsSupported(searchName.c_str());
#endif
}
bool ofGLSupportsNPOTTextures(){
#ifndef TARGET_OPENGLES
return GL_ARB_texture_rectangle;
#elif !defined(TARGET_EMSCRIPTEN)
static bool npotChecked = false;
static bool npotSupported = false;
if(!npotChecked){
vector<string> extensionsList = ofGLSupportedExtensions();
set<string> extensionsSet;
extensionsSet.insert(extensionsList.begin(),extensionsList.end());
npotSupported = extensionsSet.find("GL_OES_texture_npot")!=extensionsSet.end() ||
extensionsSet.find("APPLE_texture_2D_limited_npot")!=extensionsSet.end() ||
extensionsSet.find("GL_NV_texture_npot_2D_mipmap")!=extensionsSet.end() ||
extensionsSet.find("GL_IMG_texture_npot")!=extensionsSet.end() ||
extensionsSet.find("GL_ARB_texture_non_power_of_two")!=extensionsSet.end();
npotChecked = true;
}
return npotSupported;
#else
return true;
#endif
}
string ofGLSLVersionFromGL(int major, int minor){
#ifdef TARGET_OPENGLES
return "ES1";
#else
switch(major){
case 3:
if(minor==0){
return "130";
}else if(minor==1){
return "140";
}else if(minor==2){
return "150";
}else{
return ofToString(major*100+minor*10);
}
case 4:
return ofToString(major*100+minor*10);
default:
return "120";
}
#endif
}
#ifndef TARGET_PROGRAMMABLE_GL
shared_ptr<ofBaseGLRenderer> ofGetGLRenderer(){
if(ofGetCurrentRenderer()->getType()==ofGLRenderer::TYPE || ofGetCurrentRenderer()->getType()==ofGLProgrammableRenderer::TYPE){
return (shared_ptr<ofBaseGLRenderer>&)ofGetCurrentRenderer();
}else if(ofGetCurrentRenderer()->getType()==ofRendererCollection::TYPE){
return ((shared_ptr<ofRendererCollection>&)ofGetCurrentRenderer())->getGLRenderer();
}else{
return shared_ptr<ofGLRenderer>();
}
}
#else
shared_ptr<ofBaseGLRenderer> ofGetGLRenderer(){
if(ofGetCurrentRenderer()->getType()==ofGLProgrammableRenderer::TYPE){
return (shared_ptr<ofBaseGLRenderer>&)ofGetCurrentRenderer();
}else if(ofGetCurrentRenderer()->getType()==ofRendererCollection::TYPE){
return ((shared_ptr<ofRendererCollection>&)ofGetCurrentRenderer())->getGLRenderer();
}else{
return shared_ptr<ofGLProgrammableRenderer>();
}
}
#endif
#ifndef TARGET_OPENGLES
namespace{
void gl_debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, void * user){
ostringstream oss;
oss << "GL Debug: ";
ofLogLevel level;
switch (type) {
case GL_DEBUG_TYPE_ERROR:
level = OF_LOG_ERROR;
oss << "ERROR";
break;
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
level = OF_LOG_WARNING;
oss << "DEPRECATED_BEHAVIOR";
break;
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
level = OF_LOG_WARNING;
oss << "UNDEFINED_BEHAVIOR";
break;
case GL_DEBUG_TYPE_PORTABILITY:
level = OF_LOG_NOTICE;
oss << "PORTABILITY";
break;
case GL_DEBUG_TYPE_PERFORMANCE:
level = OF_LOG_NOTICE;
oss << "PERFORMANCE";
break;
case GL_DEBUG_TYPE_OTHER:
default:
level = OF_LOG_VERBOSE;
oss << "OTHER";
break;
}
switch (severity) {
case GL_DEBUG_SEVERITY_LOW:
oss << " (LOW)";
break;
case GL_DEBUG_SEVERITY_MEDIUM:
oss << " (MEDIUM)";
break;
case GL_DEBUG_SEVERITY_HIGH:
oss << " (HIGH)";
break;
}
oss << ", " << id << ": " << message;
ofLog(level, oss.str());
}
}
void ofEnableGLDebugLog(){
if(ofGLCheckExtension("GL_KHR_debug") && ofGLCheckExtension("GL_ARB_debug_output")){
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback((GLDEBUGPROC)gl_debug_callback, nullptr);
}
}
void ofDisableGLDebugLog(){
if(ofGLCheckExtension("GL_KHR_debug") && ofGLCheckExtension("GL_ARB_debug_output")){
glDisable(GL_DEBUG_OUTPUT);
}
}
#endif
Comments