gl
authoryu.dongliang <18588496441@163.com>
Sat, 15 Apr 2023 12:01:21 +0000 (20:01 +0800)
committeryu.dongliang <18588496441@163.com>
Sat, 15 Apr 2023 12:01:21 +0000 (20:01 +0800)
simp.h
simp_gl.c [new file with mode: 0644]

diff --git a/simp.h b/simp.h
index ca7307987a3ce3d76e099ab9cfa47780fd8d5ce5..8cce555fed40b8aad04dec14a7cc3d81bd021914 100644 (file)
--- a/simp.h
+++ b/simp.h
@@ -79,6 +79,31 @@ typedef struct {
        int                  nb_samples;
 } simp_audio_t;
 
+#define  SIMP_GL_WIDTH   1920
+#define  SIMP_GL_HEIGHT  1080
+
+typedef struct {
+       GLuint               texture_y;
+       GLuint               texture_u;
+       GLuint               texture_v;
+
+       GLuint               program;
+       GLuint               uniform_mvp;
+       GLuint               uniform_y;
+       GLuint               uniform_u;
+       GLuint               uniform_v;
+
+       GLuint               vao;
+       GLuint               buffers[2];
+
+       int                  width;
+       int                  height;
+
+       uint8_t              y[SIMP_GL_WIDTH * SIMP_GL_HEIGHT];
+       uint8_t              u[SIMP_GL_WIDTH * SIMP_GL_HEIGHT / 4];
+       uint8_t              v[SIMP_GL_WIDTH * SIMP_GL_HEIGHT / 4];
+} simp_gl_t;
+
 struct  simp_avio_s
 {
        int                  refs;
diff --git a/simp_gl.c b/simp_gl.c
new file mode 100644 (file)
index 0000000..1021b27
--- /dev/null
+++ b/simp_gl.c
@@ -0,0 +1,223 @@
+#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,
+};