From: yu.dongliang <18588496441@163.com> Date: Sat, 15 Apr 2023 12:01:21 +0000 (+0800) Subject: gl X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=f37175a0bf3026a4ea82b634ebbfa42c5b764bc3;p=simplay.git gl --- diff --git a/simp.h b/simp.h index ca73079..8cce555 100644 --- 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 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, +};