parent
4ed11b67e7
commit
1743626113
@ -0,0 +1,29 @@
|
||||
project(media-layer-stubs)
|
||||
|
||||
# Stubs Only Needed For ARM
|
||||
if(MCPI_USE_GLES1_COMPATIBILITY_LAYER AND BUILD_NATIVE_COMPONENTS AND NOT MCPI_HEADLESS_MODE)
|
||||
# GLESv1_CM Compatibility Layer
|
||||
set(GLES1_LINK_MODE "SHARED")
|
||||
if(MCPI_USE_MEDIA_LAYER_PROXY)
|
||||
# Link To Media Layer Proxy Client Statically
|
||||
# (This is so it doesn't interfere with the Media Layer Proxy Server's libGLESv1_CM.so.1 symlink.)
|
||||
set(GLES1_LINK_MODE "OBJECT")
|
||||
endif()
|
||||
add_library(GLESv1_CM "${GLES1_LINK_MODE}" src/compatibility-layer/state.c src/compatibility-layer/passthrough.c src/compatibility-layer/matrix.c src/compatibility-layer/draw.c)
|
||||
target_link_libraries(GLESv1_CM glfw reborn-util dl m)
|
||||
# Install
|
||||
if(NOT MCPI_USE_MEDIA_LAYER_PROXY)
|
||||
install(TARGETS GLESv1_CM DESTINATION "${MCPI_LIB_DIR}")
|
||||
endif()
|
||||
else()
|
||||
# Add GLESv1_CM Stubs For Linking
|
||||
add_library(GLESv1_CM SHARED src/stubs.c)
|
||||
# Install Fake GLESv1_CM Stubs In Server Mode
|
||||
if(MCPI_HEADLESS_MODE AND BUILD_ARM_COMPONENTS)
|
||||
install(TARGETS GLESv1_CM DESTINATION "${MCPI_LIB_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Common
|
||||
target_link_libraries(GLESv1_CM media-layer-headers)
|
||||
set_target_properties(GLESv1_CM PROPERTIES SOVERSION "1")
|
@ -0,0 +1,255 @@
|
||||
#include "state.h"
|
||||
#include "passthrough.h"
|
||||
|
||||
#include <GLES/gl.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
// Shaders
|
||||
#define REAL_GL_FRAGMENT_SHADER 0x8b30
|
||||
#define REAL_GL_VERTEX_SHADER 0x8b31
|
||||
#define REAL_GL_INFO_LOG_LENGTH 0x8b84
|
||||
#define REAL_GL_COMPILE_STATUS 0x8b81
|
||||
GL_FUNC(glUseProgram, void, (GLuint program));
|
||||
GL_FUNC(glGetUniformLocation, GLint, (GLuint program, const GLchar *name));
|
||||
GL_FUNC(glUniformMatrix4fv, void, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value));
|
||||
GL_FUNC(glUniform1i, void, (GLint location, GLint v0));
|
||||
GL_FUNC(glUniform1f, void, (GLint location, GLfloat v0));
|
||||
GL_FUNC(glUniform4f, void, (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3));
|
||||
GL_FUNC(glGetAttribLocation, GLint, (GLuint program, const GLchar *name));
|
||||
GL_FUNC(glEnableVertexAttribArray, void, (GLuint index));
|
||||
GL_FUNC(glDisableVertexAttribArray, void, (GLuint index));
|
||||
GL_FUNC(glVertexAttribPointer, void, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer));
|
||||
GL_FUNC(glVertexAttrib3f, void, (GLuint index, GLfloat v0, GLfloat v1, GLfloat v2));
|
||||
GL_FUNC(glVertexAttrib4f, void, (GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3));
|
||||
GL_FUNC(glCreateShader, GLuint, (GLenum type));
|
||||
GL_FUNC(glShaderSource, void, (GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length));
|
||||
GL_FUNC(glCompileShader, void, (GLuint shader));
|
||||
GL_FUNC(glCreateProgram, GLuint, ());
|
||||
GL_FUNC(glAttachShader, void, (GLuint program, GLuint shader));
|
||||
GL_FUNC(glLinkProgram, void, (GLuint program));
|
||||
GL_FUNC(glGetShaderiv, void, (GLuint shader, GLenum pname, GLint *params));
|
||||
GL_FUNC(glGetShaderInfoLog, void, (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog));
|
||||
|
||||
// Compile Shader
|
||||
static void log_shader(GLuint shader, const char *name) {
|
||||
// Log
|
||||
GLint log_length = 0;
|
||||
real_glGetShaderiv()(shader, REAL_GL_INFO_LOG_LENGTH, &log_length);
|
||||
GLchar *log = malloc(log_length * sizeof (GLchar));
|
||||
ALLOC_CHECK(log);
|
||||
real_glGetShaderInfoLog()(shader, log_length, &log_length, log);
|
||||
if (log_length > 0) {
|
||||
if (log_length > 1 && log[log_length - 1] == '\n') {
|
||||
log[log_length - 1] = '\0';
|
||||
}
|
||||
DEBUG("%s Shader Compile Log: %s", name, log);
|
||||
}
|
||||
free(log);
|
||||
|
||||
// Check Status
|
||||
GLint is_compiled = 0;
|
||||
real_glGetShaderiv()(shader, REAL_GL_COMPILE_STATUS, &is_compiled);
|
||||
if (!is_compiled) {
|
||||
ERR("Failed To Compile %s Shader", name);
|
||||
}
|
||||
}
|
||||
static GLuint compile_shader(const char *vertex_shader_text, const char *fragment_shader_text) {
|
||||
// Vertex Shader
|
||||
const GLuint vertex_shader = real_glCreateShader()(REAL_GL_VERTEX_SHADER);
|
||||
real_glShaderSource()(vertex_shader, 1, &vertex_shader_text, NULL);
|
||||
real_glCompileShader()(vertex_shader);
|
||||
log_shader(vertex_shader, "Vertex");
|
||||
|
||||
// Fragment Shader
|
||||
const GLuint fragment_shader = real_glCreateShader()(REAL_GL_FRAGMENT_SHADER);
|
||||
real_glShaderSource()(fragment_shader, 1, &fragment_shader_text, NULL);
|
||||
real_glCompileShader()(fragment_shader);
|
||||
log_shader(fragment_shader, "Fragment");
|
||||
|
||||
// Link
|
||||
GLuint program = real_glCreateProgram()();
|
||||
real_glAttachShader()(program, vertex_shader);
|
||||
real_glAttachShader()(program, fragment_shader);
|
||||
real_glLinkProgram()(program);
|
||||
|
||||
// Return
|
||||
return program;
|
||||
}
|
||||
|
||||
// Shader
|
||||
static GLuint get_shader() {
|
||||
static GLuint program = 0;
|
||||
if (program == 0) {
|
||||
static const char *vertex_shader_text =
|
||||
"#version 100\n"
|
||||
"precision mediump float;\n"
|
||||
// Matrices
|
||||
"uniform mat4 u_projection;\n"
|
||||
"uniform mat4 u_model_view;\n"
|
||||
"uniform mat4 u_texture;\n"
|
||||
// Texture
|
||||
"attribute vec3 a_vertex_coords;\n"
|
||||
"attribute vec2 a_texture_coords;\n"
|
||||
"varying vec4 v_texture_pos;\n"
|
||||
// Color
|
||||
"attribute vec4 a_color;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
// Fog
|
||||
"varying vec4 v_fog_eye_position;\n"
|
||||
// Main
|
||||
"void main() {\n"
|
||||
" v_texture_pos = u_texture * vec4(a_texture_coords.xy, 0.0, 1.0);\n"
|
||||
" gl_Position = u_projection * u_model_view * vec4(a_vertex_coords.xyz, 1.0);\n"
|
||||
" v_color = a_color;\n"
|
||||
" v_fog_eye_position = u_model_view * vec4(a_vertex_coords.xyz, 1.0);\n"
|
||||
"}";
|
||||
static const char *fragment_shader_text =
|
||||
"#version 100\n"
|
||||
"precision mediump float;\n"
|
||||
// Texture
|
||||
"uniform bool u_has_texture;"
|
||||
"uniform sampler2D u_texture_unit;\n"
|
||||
// Color
|
||||
"varying vec4 v_color;\n"
|
||||
"varying vec4 v_texture_pos;\n"
|
||||
// Alpha Test
|
||||
"uniform bool u_alpha_test;\n"
|
||||
// Fog
|
||||
"uniform bool u_fog;\n"
|
||||
"uniform vec4 u_fog_color;\n"
|
||||
"uniform bool u_fog_is_linear;\n"
|
||||
"uniform float u_fog_start;\n"
|
||||
"uniform float u_fog_end;\n"
|
||||
"varying vec4 v_fog_eye_position;\n"
|
||||
// Main
|
||||
"void main(void) {\n"
|
||||
" gl_FragColor = v_color;\n"
|
||||
" if (u_has_texture) {\n"
|
||||
" gl_FragColor *= texture2D(u_texture_unit, v_texture_pos.xy);\n"
|
||||
" }\n"
|
||||
" if (u_alpha_test && gl_FragColor.a <= 0.1) {\n"
|
||||
" discard;\n"
|
||||
" }\n"
|
||||
" if (u_fog) {\n"
|
||||
" float fog_factor;\n"
|
||||
" if (u_fog_is_linear) {\n"
|
||||
" fog_factor = (u_fog_end - length(v_fog_eye_position)) / (u_fog_end - u_fog_start);\n"
|
||||
" } else {\n"
|
||||
" fog_factor = exp(-u_fog_start * length(v_fog_eye_position));\n"
|
||||
" }\n"
|
||||
" gl_FragColor = mix(gl_FragColor, u_fog_color, 1.0 - clamp(fog_factor, 0.0, 1.0));\n"
|
||||
" }\n"
|
||||
"}";
|
||||
program = compile_shader(vertex_shader_text, fragment_shader_text);
|
||||
}
|
||||
return program;
|
||||
}
|
||||
|
||||
// Shader Switching
|
||||
static void use_shader(GLuint program) {
|
||||
static GLuint current_program = 0;
|
||||
if (current_program != program) {
|
||||
real_glUseProgram()(program);
|
||||
current_program = program;
|
||||
}
|
||||
}
|
||||
|
||||
// Array Pointer Drawing
|
||||
GL_FUNC(glDrawArrays, void, (GLenum mode, GLint first, GLsizei count));
|
||||
void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
|
||||
// Verify
|
||||
if (gl_state.array_pointers.vertex.size != 3 || !gl_state.array_pointers.vertex.enabled || gl_state.array_pointers.vertex.type != GL_FLOAT) {
|
||||
ERR("Unsupported Vertex Conifguration");
|
||||
}
|
||||
|
||||
// Check Mode
|
||||
int use_color_pointer = gl_state.array_pointers.color.enabled;
|
||||
if (use_color_pointer && (gl_state.array_pointers.color.size != 4 || gl_state.array_pointers.color.type != GL_UNSIGNED_BYTE)) {
|
||||
ERR("Unsupported Color Conifguration");
|
||||
}
|
||||
int use_texture = gl_state.texture_2d && gl_state.array_pointers.tex_coord.enabled;
|
||||
if (use_texture && (gl_state.array_pointers.tex_coord.size != 2 || gl_state.array_pointers.tex_coord.type != GL_FLOAT)) {
|
||||
ERR("Unsupported Texture Conifguration");
|
||||
}
|
||||
|
||||
// Load Shader
|
||||
GLuint program = get_shader();
|
||||
use_shader(program);
|
||||
|
||||
// Projection Matrix
|
||||
GLint u_projection_handle = real_glGetUniformLocation()(program, "u_projection");
|
||||
matrix_t *p = &gl_state.matrix_stacks.projection.stack[gl_state.matrix_stacks.projection.i];
|
||||
real_glUniformMatrix4fv()(u_projection_handle, 1, 0, (GLfloat *) &p->data[0][0]);
|
||||
|
||||
// Model View Matrix
|
||||
GLint u_model_view_handle = real_glGetUniformLocation()(program, "u_model_view");
|
||||
p = &gl_state.matrix_stacks.model_view.stack[gl_state.matrix_stacks.model_view.i];
|
||||
real_glUniformMatrix4fv()(u_model_view_handle, 1, 0, (GLfloat *) &p->data[0][0]);
|
||||
|
||||
// Has Texture
|
||||
GLint u_has_texture_handle = real_glGetUniformLocation()(program, "u_has_texture"); \
|
||||
real_glUniform1i()(u_has_texture_handle, use_texture); \
|
||||
|
||||
// Texture Matrix
|
||||
GLint u_texture_handle = real_glGetUniformLocation()(program, "u_texture");
|
||||
p = &gl_state.matrix_stacks.texture.stack[gl_state.matrix_stacks.texture.i];
|
||||
real_glUniformMatrix4fv()(u_texture_handle, 1, 0, (GLfloat *) &p->data[0][0]);
|
||||
|
||||
// Texture Unit
|
||||
GLint u_texture_unit_handle = real_glGetUniformLocation()(program, "u_texture_unit");
|
||||
real_glUniform1i()(u_texture_unit_handle, 0);
|
||||
|
||||
// Alpha Test
|
||||
GLint u_alpha_test_handle = real_glGetUniformLocation()(program, "u_alpha_test");
|
||||
real_glUniform1i()(u_alpha_test_handle, gl_state.alpha_test);
|
||||
|
||||
// Color
|
||||
GLint a_color_handle = real_glGetAttribLocation()(program, "a_color");
|
||||
if (use_color_pointer) {
|
||||
real_glVertexAttribPointer()(a_color_handle, gl_state.array_pointers.color.size, gl_state.array_pointers.color.type, 1, gl_state.array_pointers.color.stride, gl_state.array_pointers.color.pointer);
|
||||
real_glEnableVertexAttribArray()(a_color_handle);
|
||||
} else {
|
||||
real_glVertexAttrib4f()(a_color_handle, gl_state.color.red, gl_state.color.green, gl_state.color.blue, gl_state.color.alpha);
|
||||
}
|
||||
|
||||
// Fog
|
||||
GLint u_fog_handle = real_glGetUniformLocation()(program, "u_fog");
|
||||
real_glUniform1i()(u_fog_handle, gl_state.fog.enabled);
|
||||
if (gl_state.fog.enabled) {
|
||||
GLint u_fog_color_handle = real_glGetUniformLocation()(program, "u_fog_color");
|
||||
real_glUniform4f()(u_fog_color_handle, gl_state.fog.color[0], gl_state.fog.color[1], gl_state.fog.color[2], gl_state.fog.color[3]);
|
||||
GLint u_fog_is_linear_handle = real_glGetUniformLocation()(program, "u_fog_is_linear");
|
||||
real_glUniform1i()(u_fog_is_linear_handle, gl_state.fog.mode == GL_LINEAR);
|
||||
GLint u_fog_start_handle = real_glGetUniformLocation()(program, "u_fog_start");
|
||||
real_glUniform1f()(u_fog_start_handle, gl_state.fog.start);
|
||||
GLint u_fog_end_handle = real_glGetUniformLocation()(program, "u_fog_end");
|
||||
real_glUniform1f()(u_fog_end_handle, gl_state.fog.end);
|
||||
}
|
||||
|
||||
// Vertices
|
||||
GLint a_vertex_coords_handle = real_glGetAttribLocation()(program, "a_vertex_coords");
|
||||
real_glVertexAttribPointer()(a_vertex_coords_handle, gl_state.array_pointers.vertex.size, gl_state.array_pointers.vertex.type, 0, gl_state.array_pointers.vertex.stride, gl_state.array_pointers.vertex.pointer);
|
||||
real_glEnableVertexAttribArray()(a_vertex_coords_handle);
|
||||
|
||||
// Texture Coordinates
|
||||
GLint a_texture_coords_handle = real_glGetAttribLocation()(program, "a_texture_coords");
|
||||
if (use_texture) {
|
||||
real_glVertexAttribPointer()(a_texture_coords_handle, gl_state.array_pointers.tex_coord.size, gl_state.array_pointers.tex_coord.type, 0, gl_state.array_pointers.tex_coord.stride, gl_state.array_pointers.tex_coord.pointer);
|
||||
real_glEnableVertexAttribArray()(a_texture_coords_handle);
|
||||
} else {
|
||||
real_glVertexAttrib3f()(a_texture_coords_handle, 0, 0, 0);
|
||||
}
|
||||
|
||||
// Draw
|
||||
real_glDrawArrays()(mode, first, count);
|
||||
|
||||
// Cleanup
|
||||
if (use_color_pointer) {
|
||||
real_glDisableVertexAttribArray()(a_color_handle);
|
||||
}
|
||||
real_glDisableVertexAttribArray()(a_vertex_coords_handle);
|
||||
if (use_texture) {
|
||||
real_glDisableVertexAttribArray()(a_texture_coords_handle);
|
||||
}
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#include "state.h"
|
||||
#include "passthrough.h"
|
||||
|
||||
// Matrix Common
|
||||
static void matrix_copy(matrix_t *src, matrix_t *dst) {
|
||||
memcpy((void *) dst->data, (void *) src->data, MATRIX_DATA_SIZE);
|
||||
}
|
||||
|
||||
// Identity Matrix
|
||||
static matrix_t identity_matrix = {
|
||||
.data = {
|
||||
{1, 0, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 0, 1, 0},
|
||||
{0, 0, 0, 1}
|
||||
}
|
||||
};
|
||||
static void init_matrix_stack(matrix_stack_t *stack) {
|
||||
matrix_copy(&identity_matrix, &stack->stack[0]);
|
||||
}
|
||||
__attribute__((constructor)) static void init_matrix_stacks() {
|
||||
init_matrix_stack(&gl_state.matrix_stacks.model_view);
|
||||
init_matrix_stack(&gl_state.matrix_stacks.projection);
|
||||
init_matrix_stack(&gl_state.matrix_stacks.texture);
|
||||
}
|
||||
|
||||
// Matrix Mode
|
||||
static matrix_stack_t *get_matrix_stack() {
|
||||
switch (gl_state.matrix_stacks.mode) {
|
||||
case GL_MODELVIEW: {
|
||||
return &gl_state.matrix_stacks.model_view;
|
||||
}
|
||||
case GL_PROJECTION: {
|
||||
return &gl_state.matrix_stacks.projection;
|
||||
}
|
||||
case GL_TEXTURE: {
|
||||
return &gl_state.matrix_stacks.texture;
|
||||
}
|
||||
default: {
|
||||
ERR("Unsupported Matrix Mode: %i", gl_state.matrix_stacks.mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Matrix Functions
|
||||
void glMatrixMode(GLenum mode) {
|
||||
gl_state.matrix_stacks.mode = mode;
|
||||
}
|
||||
void glPopMatrix() {
|
||||
get_matrix_stack()->i--;
|
||||
}
|
||||
void glLoadIdentity() {
|
||||
matrix_stack_t *stack = get_matrix_stack();
|
||||
matrix_copy(&identity_matrix, &stack->stack[stack->i]);
|
||||
}
|
||||
void glPushMatrix() {
|
||||
matrix_stack_t *stack = get_matrix_stack();
|
||||
matrix_copy(&stack->stack[stack->i], &stack->stack[stack->i + 1]);
|
||||
stack->i++;
|
||||
}
|
||||
void glMultMatrixf(const GLfloat *m) {
|
||||
matrix_t new_matrix;
|
||||
matrix_stack_t *stack = get_matrix_stack();
|
||||
matrix_t *current_matrix = &stack->stack[stack->i];
|
||||
for (int x = 0; x < MATRIX_SIZE; x++) {
|
||||
for (int y = 0; y < MATRIX_SIZE; y++) {
|
||||
GLfloat result = 0;
|
||||
for (int i = 0; i < MATRIX_SIZE; i++) {
|
||||
result += (current_matrix->data[i][y] * m[(x * MATRIX_SIZE) + i]);
|
||||
}
|
||||
new_matrix.data[x][y] = result;
|
||||
}
|
||||
}
|
||||
matrix_copy(&new_matrix, current_matrix);
|
||||
}
|
||||
void glScalef(GLfloat x, GLfloat y, GLfloat z) {
|
||||
GLfloat m[] = {
|
||||
x, 0, 0, 0,
|
||||
0, y, 0, 0,
|
||||
0, 0, z, 0,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
glMultMatrixf(m);
|
||||
}
|
||||
void glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
|
||||
GLfloat m[] = {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
x, y, z, 1
|
||||
};
|
||||
glMultMatrixf(m);
|
||||
}
|
||||
void glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far) {
|
||||
GLfloat m[] = {
|
||||
(2.f / (right - left)), 0, 0, 0,
|
||||
0, (2.f / (top - bottom)), 0, 0,
|
||||
0, 0, (-2.f / (far - near)), 0,
|
||||
-((right + left) / (right - left)), -((top + bottom) / (top - bottom)), -((far + near) / (far - near)), 1
|
||||
};
|
||||
glMultMatrixf(m);
|
||||
}
|
||||
#define DEG2RAD (M_PI / 180.f)
|
||||
void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
|
||||
// Normalize
|
||||
GLfloat length = sqrtf((x * x) + (y * y) + (z * z));
|
||||
x /= length;
|
||||
y /= length;
|
||||
z /= length;
|
||||
|
||||
// Values
|
||||
GLfloat angle_radians = angle * DEG2RAD;
|
||||
GLfloat c = cosf(angle_radians);
|
||||
GLfloat s = sinf(angle_radians);
|
||||
GLfloat x2 = x * x;
|
||||
GLfloat y2 = y * y;
|
||||
GLfloat z2 = z * z;
|
||||
|
||||
// Multiply
|
||||
GLfloat m[] = {
|
||||
x2 * (1.f - c) + c, (x * y) * (1.f - c) + (z * s), (x * z) * (1.f - c) - (y * s), 0,
|
||||
(x * y) * (1.f - c) - (z * s), y2 * (1.f - c) + c, (y * z) * (1.f - c) + (x * s), 0,
|
||||
(x * z) * (1.f - c) + (y * s), (y * z) * (1.f - c) - (x * s), z2 * (1.f - c) + c, 0,
|
||||
0, 0, 0, 1.f
|
||||
};
|
||||
glMultMatrixf(m);
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#include <GLES/gl.h>
|
||||
|
||||
// Matrix Common
|
||||
#define MATRIX_SIZE 4
|
||||
#define MATRIX_DATA_SIZE (sizeof (float) * MATRIX_SIZE * MATRIX_SIZE)
|
||||
// OpenGL Matricies Are Column-Major
|
||||
typedef struct {
|
||||
GLfloat data[MATRIX_SIZE][MATRIX_SIZE];
|
||||
} matrix_t;
|
@ -0,0 +1,113 @@
|
||||
#include <GLES/gl.h>
|
||||
|
||||
#include "passthrough.h"
|
||||
|
||||
// Simple v1.1 -> v2.0 Passthrough Functions
|
||||
GL_FUNC(glLineWidth, void, (GLfloat width));
|
||||
void glLineWidth(GLfloat width) {
|
||||
real_glLineWidth()(width);
|
||||
}
|
||||
GL_FUNC(glBlendFunc, void, (GLenum sfactor, GLenum dfactor));
|
||||
void glBlendFunc(GLenum sfactor, GLenum dfactor) {
|
||||
real_glBlendFunc()(sfactor, dfactor);
|
||||
}
|
||||
GL_FUNC(glClear, void, (GLbitfield mask));
|
||||
void glClear(GLbitfield mask) {
|
||||
real_glClear()(mask);
|
||||
}
|
||||
GL_FUNC(glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage));
|
||||
void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage) {
|
||||
real_glBufferData()(target, size, data, usage);
|
||||
}
|
||||
GL_FUNC(glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height));
|
||||
void glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
real_glScissor()(x, y, width, height);
|
||||
}
|
||||
GL_FUNC(glTexParameteri, void, (GLenum target, GLenum pname, GLint param));
|
||||
void glTexParameteri(GLenum target, GLenum pname, GLint param) {
|
||||
real_glTexParameteri()(target, pname, param);
|
||||
}
|
||||
GL_FUNC(glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels));
|
||||
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) {
|
||||
real_glTexImage2D()(target, level, internalformat, width, height, border, format, type, pixels);
|
||||
}
|
||||
GL_FUNC(glPolygonOffset, void, (GLfloat factor, GLfloat units));
|
||||
void glPolygonOffset(GLfloat factor, GLfloat units) {
|
||||
real_glPolygonOffset()(factor, units);
|
||||
}
|
||||
GL_FUNC(glDepthRangef, void, (GLclampf near, GLclampf far));
|
||||
void glDepthRangef(GLclampf near, GLclampf far) {
|
||||
real_glDepthRangef()(near, far);
|
||||
}
|
||||
GL_FUNC(glDepthFunc, void, (GLenum func));
|
||||
void glDepthFunc(GLenum func) {
|
||||
real_glDepthFunc()(func);
|
||||
}
|
||||
GL_FUNC(glBindBuffer, void, (GLenum target, GLuint buffer));
|
||||
void glBindBuffer(GLenum target, GLuint buffer) {
|
||||
real_glBindBuffer()(target, buffer);
|
||||
}
|
||||
GL_FUNC(glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha));
|
||||
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
|
||||
real_glClearColor()(red, green, blue, alpha);
|
||||
}
|
||||
GL_FUNC(glDepthMask, void, (GLboolean flag));
|
||||
void glDepthMask(GLboolean flag) {
|
||||
real_glDepthMask()(flag);
|
||||
}
|
||||
GL_FUNC(glHint, void, (GLenum target, GLenum mode));
|
||||
void glHint(GLenum target, GLenum mode) {
|
||||
if (target != GL_PERSPECTIVE_CORRECTION_HINT) {
|
||||
real_glHint()(target, mode);
|
||||
}
|
||||
}
|
||||
GL_FUNC(glDeleteBuffers, void, (GLsizei n, const GLuint *buffers));
|
||||
void glDeleteBuffers(GLsizei n, const GLuint *buffers) {
|
||||
real_glDeleteBuffers()(n, buffers);
|
||||
}
|
||||
GL_FUNC(glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha));
|
||||
void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
|
||||
real_glColorMask()(red, green, blue, alpha);
|
||||
}
|
||||
GL_FUNC(glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels));
|
||||
void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) {
|
||||
real_glTexSubImage2D()(target, level, xoffset, yoffset, width, height, format, type, pixels);
|
||||
}
|
||||
GL_FUNC(glGenTextures, void, (GLsizei n, GLuint *textures));
|
||||
void glGenTextures(GLsizei n, GLuint *textures) {
|
||||
real_glGenTextures()(n, textures);
|
||||
}
|
||||
GL_FUNC(glDeleteTextures, void, (GLsizei n, const GLuint *textures));
|
||||
void glDeleteTextures(GLsizei n, const GLuint *textures) {
|
||||
real_glDeleteTextures()(n, textures);
|
||||
}
|
||||
GL_FUNC(glBindTexture, void, (GLenum target, GLuint texture));
|
||||
void glBindTexture(GLenum target, GLuint texture) {
|
||||
real_glBindTexture()(target, texture);
|
||||
}
|
||||
GL_FUNC(glCullFace, void, (GLenum mode));
|
||||
void glCullFace(GLenum mode) {
|
||||
real_glCullFace()(mode);
|
||||
}
|
||||
GL_FUNC(glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height));
|
||||
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
real_glViewport()(x, y, width, height);
|
||||
}
|
||||
GL_FUNC(glIsEnabled, GLboolean, (GLenum cap));
|
||||
GLboolean glIsEnabled(GLenum cap) {
|
||||
return real_glIsEnabled()(cap);
|
||||
}
|
||||
GL_FUNC(glGetIntegerv, void, (GLenum pname, GLint *data));
|
||||
void glGetIntegerv(GLenum pname, GLint *data) {
|
||||
real_glGetIntegerv()(pname, data);
|
||||
}
|
||||
GL_FUNC(glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data));
|
||||
void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data) {
|
||||
real_glReadPixels()(x, y, width, height, format, type, data);
|
||||
}
|
||||
void glShadeModel(__attribute__((unused)) GLenum mode) {
|
||||
// Do Nothing
|
||||
}
|
||||
void glNormal3f(__attribute__((unused)) GLfloat nx, __attribute__((unused)) GLfloat ny, __attribute__((unused)) GLfloat nz) {
|
||||
// Do Nothing
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
// Load GL Function
|
||||
#define GL_FUNC(name, return_type, args) \
|
||||
typedef return_type (*real_##name##_t)args; \
|
||||
\
|
||||
__attribute__((__unused__)) static real_##name##_t real_##name() { \
|
||||
static real_##name##_t func = NULL; \
|
||||
if (!func) { \
|
||||
func = (real_##name##_t) glfwGetProcAddress(#name); \
|
||||
if (!func) { \
|
||||
ERR("Error Resolving GL Symbol: " #name ": %s", dlerror()); \
|
||||
} \
|
||||
} \
|
||||
return func; \
|
||||
}
|
@ -0,0 +1,178 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#include "state.h"
|
||||
#include "passthrough.h"
|
||||
|
||||
// GL State
|
||||
gl_state_t gl_state = {
|
||||
.color = {
|
||||
.red = 1,
|
||||
.green = 1,
|
||||
.blue = 1,
|
||||
.alpha = 1
|
||||
},
|
||||
.matrix_stacks = {
|
||||
.mode = GL_MODELVIEW
|
||||
},
|
||||
.alpha_test = 0,
|
||||
.texture_2d = 0,
|
||||
.fog = {
|
||||
.enabled = 0,
|
||||
.mode = GL_LINEAR,
|
||||
.color = {0, 0, 0, 0},
|
||||
.start = 0,
|
||||
.end = 1
|
||||
}
|
||||
};
|
||||
|
||||
// Change Color
|
||||
void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
|
||||
gl_state.color.red = red;
|
||||
gl_state.color.green = green;
|
||||
gl_state.color.blue = blue;
|
||||
gl_state.color.alpha = alpha;
|
||||
}
|
||||
|
||||
// Array Pointer Storage
|
||||
#define ARRAY_POINTER_FUNC(func, name) \
|
||||
void func(GLint size, GLenum type, GLsizei stride, const void *pointer) { \
|
||||
gl_state.array_pointers.name.size = size; \
|
||||
gl_state.array_pointers.name.type = type; \
|
||||
gl_state.array_pointers.name.stride = stride; \
|
||||
gl_state.array_pointers.name.pointer = pointer; \
|
||||
}
|
||||
ARRAY_POINTER_FUNC(glVertexPointer, vertex)
|
||||
ARRAY_POINTER_FUNC(glColorPointer, color)
|
||||
ARRAY_POINTER_FUNC(glTexCoordPointer, tex_coord)
|
||||
static array_pointer_t *get_array_pointer(GLenum array) {
|
||||
switch (array) {
|
||||
case GL_VERTEX_ARRAY: {
|
||||
return &gl_state.array_pointers.vertex;
|
||||
}
|
||||
case GL_COLOR_ARRAY: {
|
||||
return &gl_state.array_pointers.color;
|
||||
}
|
||||
case GL_TEXTURE_COORD_ARRAY: {
|
||||
return &gl_state.array_pointers.tex_coord;
|
||||
}
|
||||
default: {
|
||||
ERR("Unsupported Array Pointer: %i", array);
|
||||
}
|
||||
}
|
||||
}
|
||||
void glEnableClientState(GLenum array) {
|
||||
get_array_pointer(array)->enabled = 1;
|
||||
}
|
||||
void glDisableClientState(GLenum array) {
|
||||
get_array_pointer(array)->enabled = 0;
|
||||
}
|
||||
|
||||
// Enable/Disable State
|
||||
GL_FUNC(glEnable, void, (GLenum cap));
|
||||
void glEnable(GLenum cap) {
|
||||
switch (cap) {
|
||||
case GL_ALPHA_TEST: {
|
||||
gl_state.alpha_test = 1;
|
||||
break;
|
||||
}
|
||||
case GL_TEXTURE_2D: {
|
||||
gl_state.texture_2d = 1;
|
||||
break;
|
||||
}
|
||||
case GL_COLOR_MATERIAL: {
|
||||
// Ignore
|
||||
break;
|
||||
}
|
||||
case GL_FOG: {
|
||||
gl_state.fog.enabled = 1;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
real_glEnable()(cap);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
GL_FUNC(glDisable, void, (GLenum cap));
|
||||
void glDisable(GLenum cap) {
|
||||
switch (cap) {
|
||||
case GL_ALPHA_TEST: {
|
||||
gl_state.alpha_test = 0;
|
||||
break;
|
||||
}
|
||||
case GL_TEXTURE_2D: {
|
||||
gl_state.texture_2d = 0;
|
||||
break;
|
||||
}
|
||||
case GL_COLOR_MATERIAL: {
|
||||
// Ignore
|
||||
break;
|
||||
}
|
||||
case GL_FOG: |