--- /dev/null
+#include"chess_gl.h"
+#include"pieces.h"
+
+const float G_PI = 3.1415926;
+
+const char* vertex_shader_board =
+ "#version 330 core\n"
+ "layout(location = 0) in vec4 position; \n"
+ "layout(location = 1) in vec2 a_texCoord; \n"
+ "out vec2 v_texCoord; \n"
+ "uniform mat4 mvp; \n"
+ "void main() { \n"
+ "gl_Position = mvp * position; \n"
+ "v_texCoord = a_texCoord; \n"
+ "} \n";
+
+const char* fragment_shader_board =
+ "#version 330 core\n"
+ "in vec2 v_texCoord; \n"
+ "out vec4 outputColor; \n"
+ "uniform sampler2D tex_y; \n"
+ "uniform sampler2D tex_u; \n"
+ "uniform sampler2D tex_v; \n"
+ "void main() { \n"
+ " vec2 xy = v_texCoord; \n"
+ " float y = texture2D(tex_y, xy).r; \n"
+ " float u = texture2D(tex_u, xy).r - 0.5; \n"
+ " float v = texture2D(tex_v, xy).r - 0.5; \n"
+ " float r = y + 1.4075 * v; \n"
+ " float g = y - 0.3455 * u - 0.7169 * v; \n"
+ " float b = y + 1.779 * u; \n"
+ " outputColor = vec4(r, g, b, 1.0f); \n"
+ "} \n";
+
+
+const GLfloat vert_array[] = {
+ -1.0f, -1.0f,
+ 1.0f, -1.0f,
+ -1.0f, 1.0f,
+ 1.0f, 1.0f
+};
+
+const GLfloat texture_array[] = {
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ 0.0f, 0.0f,
+ 1.0f, 0.0f,
+};
+
+static void init_buffers(simp_gl_t* gl)
+{
+ glGenBuffers (2, gl->buffers);
+ glBindBuffer (GL_ARRAY_BUFFER, gl->buffers[0]);
+ glBufferData (GL_ARRAY_BUFFER, sizeof(vert_array), vert_array, GL_STATIC_DRAW);
+ glBindBuffer (GL_ARRAY_BUFFER, gl->buffers[1]);
+ glBufferData (GL_ARRAY_BUFFER, sizeof(texture_array), texture_array, GL_STATIC_DRAW);
+
+ glGenVertexArrays (1, &gl->vao);
+ glBindVertexArray (gl->vao);
+
+ glBindBuffer (GL_ARRAY_BUFFER, gl->buffers[0]);
+ glEnableVertexAttribArray (0);
+ glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, 0, 0);
+
+ glBindBuffer (GL_ARRAY_BUFFER, gl->buffers[1]);
+ glEnableVertexAttribArray (1);
+ glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, 0);
+
+ glBindVertexArray (0);
+}
+
+void compute_mvp(float *res, float phi, float theta, float psi)
+{
+ float x = phi * (G_PI / 180.f);
+ float y = theta * (G_PI / 180.f);
+ float z = psi * (G_PI / 180.f);
+
+ float c1 = cosf(x);
+ float s1 = sinf(x);
+ float c2 = cosf(y);
+ float s2 = sinf(y);
+ float c3 = cosf(z);
+ float s3 = sinf(z);
+
+ float c3c2 = c3 * c2;
+ float s3c1 = s3 * c1;
+ float c3s2s1 = c3 * s2 * s1;
+ float s3s1 = s3 * s1;
+ float c3s2c1 = c3 * s2 * c1;
+ float s3c2 = s3 * c2;
+ float c3c1 = c3 * c1;
+ float s3s2s1 = s3 * s2 * s1;
+ float c3s1 = c3 * s1;
+ float s3s2c1 = s3 * s2 * c1;
+ float c2s1 = c2 * s1;
+ float c2c1 = c2 * c1;
+
+ /* initialize to the identity matrix */
+ res[0] = 1.f; res[4] = 0.f; res[8] = 0.f; res[12] = 0.f;
+ res[1] = 0.f; res[5] = 1.f; res[9] = 0.f; res[13] = 0.f;
+ res[2] = 0.f; res[6] = 0.f; res[10] = 1.f; res[14] = 0.f;
+ res[3] = 0.f; res[7] = 0.f; res[11] = 0.f; res[15] = 1.f;
+
+ /* apply all three rotations using the three matrices:
+ *
+ * ⎡ c3 s3 0 ⎤ ⎡ c2 0 -s2 ⎤ ⎡ 1 0 0 ⎤
+ * ⎢ -s3 c3 0 ⎥ ⎢ 0 1 0 ⎥ ⎢ 0 c1 s1 ⎥
+ * ⎣ 0 0 1 ⎦ ⎣ s2 0 c2 ⎦ ⎣ 0 -s1 c1 ⎦
+ */
+ res[0] = c3c2; res[4] = s3c1 + c3s2s1; res[8] = s3s1 - c3s2c1; res[12] = 0.f;
+ res[1] = -s3c2; res[5] = c3c1 - s3s2s1; res[9] = c3s1 + s3s2c1; res[13] = 0.f;
+ res[2] = s2; res[6] = -c2s1; res[10] = c2c1; res[14] = 0.f;
+ res[3] = 0.f; res[7] = 0.f; res[11] = 0.f; res[15] = 1.f;
+}
+
+static int init_texture(GLuint* ptex, GLenum format, int w, int h, uint8_t* data)
+{
+ GLuint tex;
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexImage2D (GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, data);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ *ptex = tex;
+ return 0;
+}
+
+int _gl_open(simp_avio_t* io, const char* in, const char* out);
+{
+ simp_gl_t* gl = calloc(1, sizeof(simp_gl_t));
+ if (!gl)
+ return -ENOMEM;
+
+ init_buffers(gl);
+
+ GLint status = 0;
+
+ GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
+
+ glShaderSource (vertex_shader, 1, &vertex_shader_board, NULL);
+ glCompileShader(vertex_shader);
+ glGetShaderiv (vertex_shader, GL_COMPILE_STATUS, &status);
+ printf("#0, status: %d\n", status);
+
+ GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
+
+ glShaderSource (fragment_shader, 1, &fragment_shader_board, NULL);
+ glCompileShader(fragment_shader);
+ glGetShaderiv (fragment_shader, GL_COMPILE_STATUS, &status);
+ printf("#1, status: %d\n", status);
+
+ program = glCreateProgram();
+ glAttachShader(program, vertex_shader);
+ glAttachShader(program, fragment_shader);
+ glLinkProgram (program);
+ glGetProgramiv(program, GL_LINK_STATUS, &status);
+ printf("#2, status: %d\n", status);
+
+ init_texture(&gl->texture_y, GL_RED, SIMP_GL_WIDTH, SIMP_GL_HEIGHT, gl->y);
+ init_texture(&gl->texture_u, GL_RED, SIMP_GL_WIDTH / 2, SIMP_GL_HEIGHT / 2, gl->u);
+ init_texture(&gl->texture_v, GL_RED, SIMP_GL_WIDTH / 2, SIMP_GL_HEIGHT / 2, gl->v);
+
+ io->priv = gl;
+ return 0;
+}
+
+int simp_gl_draw(simp_gl_t* gl)
+{
+ float mvp[16];
+
+ compute_mvp(mvp, 0, 0, 0);
+
+ glClearColor(1.0, 0.0, 1.0, 1.0);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glUseProgram(gl->program);
+
+ gl->uniform_y = glGetUniformLocation(gl->program, "tex_y");
+ gl->uniform_u = glGetUniformLocation(gl->program, "tex_u");
+ gl->uniform_v = glGetUniformLocation(gl->program, "tex_v");
+ gl->uniform_mvp = glGetUniformLocation(gl->program, "mvp");
+
+ glUniformMatrix4fv(gl->uniform_mvp, 1, GL_FALSE, &mvp[0]);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture (GL_TEXTURE_2D, gl->texture_y);
+ glUniform1i (gl->uniform_y, 0);
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture (GL_TEXTURE_2D, gl->texture_u);
+ glUniform1i (gl->uniform_u, 1);
+
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture (GL_TEXTURE_2D, gl->texture_v);
+ glUniform1i (gl->uniform_v, 2);
+
+ // draw
+ glBindVertexArray(gl->vao);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ glBindVertexArray(0);
+ glUseProgram(0);
+
+ return 0;
+}
+
+simp_avio_ops_t simp_avio_gl =
+{
+ .type = "gl",
+ .open = _gl_open,
+ .close = _gl_close,
+ .run = _gl_run,
+ .stop = _gl_stop,
+};