-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontext.cpp
142 lines (119 loc) · 5.1 KB
/
context.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <gl_layer/context.h>
#include <gl_layer/private/types.h>
#include <gl_layer/private/context.h>
#include <string_view>
#include <cstdio>
#include <cstdarg>
namespace gl_layer {
const char* enum_str(GLenum v) {
switch(v) {
case GL_SHADER_TYPE: return "GL_SHADER_TYPE";
case GL_DELETE_STATUS: return "GL_DELETE_STATUS";
case GL_COMPILE_STATUS: return "GL_COMPILE_STATUS";
case GL_LINK_STATUS: return "GL_LINK_STATUS";
case GL_INFO_LOG_LENGTH: return "GL_INFO_LOG_LENGTH";
case GL_SHADER_SOURCE_LENGTH: return "GL_SHADER_SOURCE_LENGTH";
case GL_TEXTURE_1D: return "GL_TEXTURE_1D";
case GL_TEXTURE_2D: return "GL_TEXTURE_2D";
case GL_TEXTURE_3D: return "GL_TEXTURE_3D";
case GL_TEXTURE_1D_ARRAY: return "GL_TEXTURE_1D_ARRAY";
case GL_TEXTURE_2D_ARRAY: return "GL_TEXTURE_2D_ARRAY";
case GL_TEXTURE_RECTANGLE: return "GL_TEXTURE_RECTANGLE";
case GL_TEXTURE_CUBE_MAP: return "GL_TEXTURE_CUBE_MAP";
case GL_TEXTURE_CUBE_MAP_ARRAY: return "GL_TEXTURE_CUBE_MAP_ARRAY";
case GL_TEXTURE_BUFFER: return "GL_TEXTURE_BUFFER";
case GL_TEXTURE_2D_MULTISAMPLE: return "GL_TEXTURE_2D_MULTISAMPLE";
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: return "GL_TEXTURE_2D_MULTISAMPLE_ARRAY";
default:
return "";
}
}
static void default_output_func(const char* text, void* = nullptr) {
printf("%s\n", text);
}
Context::Context(Version version, const ContextGLFunctions* gl_functions)
: gl_version(version), gl(*gl_functions) {
output_fun = &default_output_func;
}
void Context::set_output_callback(GLLayerOutputFun callback, void* user_data) {
output_fun = callback;
output_user_data = user_data;
}
namespace {
Context* g_context = nullptr;
}
} // namespace gl_layer
static bool is_func(std::string_view name, std::string_view func) {
return func == name;
}
[[maybe_unused]] static bool func_has(std::string_view name, std::string_view substr) {
return name.find(substr) != std::string_view::npos;
}
int gl_layer_init(unsigned int gl_version_major, unsigned int gl_version_minor, const ContextGLFunctions* gl_functions) {
gl_layer::g_context = new gl_layer::Context(gl_layer::Version{ gl_version_major, gl_version_minor }, gl_functions);
if (gl_layer::g_context) return 0;
return -1;
}
void gl_layer_terminate() {
delete gl_layer::g_context;
}
void gl_layer_callback(const char* name_c, void* func_ptr, int num_args, ...) {
if (!gl_layer::g_context) {
// Report error: context not initialized.
return;
}
using namespace gl_layer; // GL types
std::string_view name = name_c;
va_list args;
va_start(args, num_args);
if (is_func(name, "glCompileShader")) {
auto shader = va_arg(args, GLuint);
gl_layer::g_context->glCompileShader(shader);
} else if (is_func(name, "glGetShaderiv")) {
auto shader = va_arg(args, GLuint);
gl_layer::GLenum param = va_arg(args, GLenum);
auto* params = va_arg(args, GLint*);
gl_layer::g_context->glGetShaderiv(shader, param, params);
} else if (is_func(name, "glAttachShader")) {
// Note that the parameters must be pulled outside the function call, since there is no guarantee that they will evaluate in order!
auto program = va_arg(args, GLuint);
auto shader = va_arg(args, GLuint);
gl_layer::g_context->glAttachShader(program, shader);
} else if (is_func(name, "glGetProgramiv")) {
auto program = va_arg(args, GLuint);
gl_layer::GLenum param = va_arg(args, GLenum);
auto* params = va_arg(args, GLint*);
gl_layer::g_context->glGetProgramiv(program, param, params);
} else if (is_func(name, "glUseProgram")) {
auto program = va_arg(args, GLuint);
gl_layer::g_context->glUseProgram(program);
} else if (is_func(name, "glLinkProgram")) {
auto program = va_arg(args, GLuint);
gl_layer::g_context->glLinkProgram(program);
} else if (is_func(name, "glGenTextures")) {
auto count = va_arg(args, GLsizei);
auto textures = va_arg(args, GLuint*);
gl_layer::g_context->glGenTextures(count, textures);
} else if (is_func(name, "glCreateTextures")) {
auto target = va_arg(args, GLenum);
auto count = va_arg(args, GLsizei);
auto textures = va_arg(args, GLuint*);
gl_layer::g_context->glCreateTextures(target, count, textures);
} else if (is_func(name, "glDeleteTextures")) {
auto count = va_arg(args, GLsizei);
auto textures = va_arg(args, GLuint*);
gl_layer::g_context->glDeleteTextures(count, textures);
} else if (is_func(name, "glBindTexture")) {
auto target = va_arg(args, GLenum);
auto texture = va_arg(args, GLuint);
gl_layer::g_context->glBindTexture(target, texture);
}
va_end(args);
}
[[maybe_unused]] void gl_layer_set_output_callback(GLLayerOutputFun callback, void* user_data) {
if (!gl_layer::g_context) {
// Report error: context not initialized.
return;
}
gl_layer::g_context->set_output_callback(callback, user_data);
}