From: Fl_GUI Date: Sun, 8 Jun 2025 15:11:35 +0000 (+0200) Subject: gummi X-Git-Url: https://git.openfl.eu/?a=commitdiff_plain;h=5e4315df22acaccc74b41465f617f3222ca3e8a9;p=gummi.git gummi --- diff --git a/meson.build b/meson.build index 3c7f545..438ac2e 100644 --- a/meson.build +++ b/meson.build @@ -5,9 +5,9 @@ src = 'src' subdir(src / 'glad') deps = [dependency('glfw3'), glad_dep] -srcs = [src/'main.cc'] +srcs = [src/'main.cc', src/'eye.cc', src/'log.cc', src/'mouth.cc'] executable('gummi', sources: srcs, dependencies: deps, - include_directories: glad_inc) + include_directories: [glad_inc]) diff --git a/src/eye.cc b/src/eye.cc new file mode 100644 index 0000000..368f88d --- /dev/null +++ b/src/eye.cc @@ -0,0 +1,171 @@ +#include "eye.h" + +#include +#include + +#include "log.h" + +const char* eye_vertex_shader = +"#version 120\n" +"attribute vec3 aPos;\n" +"uniform int eyeflipped;\n" +"void main() {\n" +" // scale pixel position to +-1;\n" +" gl_Position = vec4(eyeflipped * (aPos.x/400 -1), aPos.y/240 -1, aPos.z, 1.0);\n" +"};"; + +const char* eye_fragment_shader = +"#version 120\n" +"void main() {" +" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);" +"};"; + +const char* eye_pupil_fragment_shader = +"#version 120\n" +"void main() {" +" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);" +"};"; + +float eyeline[] { + 150, 130, 0, + 150, 190, 0, + + 150, 220, 0, + 150, 280, 0, + + 150, 310, 0, + 150, 370, 0, + + 160, 380, 0, + 240, 380, 0, + + 260, 370, 0, + 310, 310, 0, + + 320, 280, 0, + 320, 220, 0, + + 320, 190, 0, + 320, 130, 0, + + 330, 110, 0, + 250, 110, 0, + + 230, 110, 0, + 140, 110, 0, +}; + +float eyePos[] { + 270, 280, 0, +}; + +GLuint eyeShaderProgram; +GLuint eyeFlipLocation; +GLuint pupilShaderProgram; + +eye_t eyes[2]; + +void setEyeShaderProgram() { + GLint status; + + auto eyeVertShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(eyeVertShader, 1, &eye_vertex_shader, NULL); + glCompileShader(eyeVertShader); + glGetShaderiv(eyeVertShader, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) { + logShaderOopsie(eyeVertShader); + return; + } + + auto eyeFragShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(eyeFragShader, 1, &eye_fragment_shader, NULL); + glCompileShader(eyeFragShader); + glGetShaderiv(eyeFragShader, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) { + logShaderOopsie(eyeFragShader); + return; + } + + auto pupilFragShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(pupilFragShader, 1, &eye_fragment_shader, NULL); + glCompileShader(pupilFragShader); + glGetShaderiv(pupilFragShader, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) { + logShaderOopsie(pupilFragShader); + return; + } + + eyeShaderProgram = glCreateProgram(); + glAttachShader(eyeShaderProgram, eyeVertShader); + glAttachShader(eyeShaderProgram, eyeFragShader); + glLinkProgram(eyeShaderProgram); + glGetProgramiv(eyeShaderProgram, GL_LINK_STATUS, (int *)&status); + if (status == GL_FALSE) { + printf("uhoh program\n"); + } + + pupilShaderProgram = glCreateProgram(); + glAttachShader(pupilShaderProgram, eyeVertShader); + glAttachShader(pupilShaderProgram, pupilFragShader); + glLinkProgram(pupilShaderProgram); + glGetProgramiv(pupilShaderProgram, GL_LINK_STATUS, (int *)&status); + if (status == GL_FALSE) { + printf("uhoh program\n"); + } + + glDeleteShader(eyeVertShader); + glDeleteShader(eyeFragShader); + glDeleteShader(eyeFragShader); + glDeleteShader(pupilFragShader); + + eyeFlipLocation = glGetUniformLocation(eyeShaderProgram, "eyeflipped"); + auto err = glGetError(); + if (err) { + printf("uhoh uniform location error: %d\n", err); + } +} + +void initEye(eye_t *eye) { + glGenBuffers(1, &eye->eyeVBO); + glBindBuffer(GL_ARRAY_BUFFER, eye->eyeVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(eyeline), eyeline, GL_STATIC_DRAW); + + glGenBuffers(1, &eye->pupilVBO); + glBindBuffer(GL_ARRAY_BUFFER, eye->pupilVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(eyePos), eyePos, GL_STATIC_DRAW); +} + +void initEyes() { + auto eye = &eyes[0]; + eye->left = 1; + initEye(eye); + + eye = &eyes[1]; + eye->left = -1; + initEye(eye); + + setEyeShaderProgram(); +} + +void drawEye(eye_t *eye) { + glUniform1i(eyeFlipLocation, eye->left); + glBindBuffer(GL_ARRAY_BUFFER, eye->eyeVBO); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); + glDrawArrays(GL_LINES, 0, 18); +} + +void drawPupil(eye_t *eye) { + glUniform1i(eyeFlipLocation, eye->left); + glBindBuffer(GL_ARRAY_BUFFER, eye->pupilVBO); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); + glDrawArrays(GL_POINTS, 0, 1); +} + +void drawEyes() { + glUseProgram(eyeShaderProgram); + drawEye(&eyes[0]); + drawEye(&eyes[1]); + glUseProgram(pupilShaderProgram); + drawPupil(&eyes[0]); + drawPupil(&eyes[1]); +} diff --git a/src/eye.h b/src/eye.h new file mode 100644 index 0000000..fbe4888 --- /dev/null +++ b/src/eye.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +typedef struct eye { + // eye state + GLint left; + // index to buffer object + GLuint eyeVBO; + GLuint pupilVBO; +} eye_t; + +extern eye_t eyes[2]; + +void initEyes(); + +void drawEyes(); + diff --git a/src/log.cc b/src/log.cc new file mode 100644 index 0000000..9381735 --- /dev/null +++ b/src/log.cc @@ -0,0 +1,12 @@ +#include "log.h" + +extern void logShaderOopsie(GLuint shader) { + GLint logLength; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); + if (!logLength) + return; + std::vector shaderLog(logLength); + glGetShaderInfoLog(shader, logLength, &logLength, &shaderLog[0]); + printf("shader log: %s", &shaderLog[0]); +} + diff --git a/src/log.h b/src/log.h new file mode 100644 index 0000000..1f71f60 --- /dev/null +++ b/src/log.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include +#include + +void logShaderOopsie(GLuint shader); diff --git a/src/main.cc b/src/main.cc index 00ee7d2..630e68d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -3,6 +3,10 @@ #include #include +#include "log.h" +#include "eye.h" +#include "mouth.h" + float triangles[] = { -0.5,0.5,0, -0.2,-0.5,0, @@ -23,14 +27,6 @@ const char* fragment_shader = " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);" "};"; -void logShaderOopsie(GLuint shader) { - GLint logLength; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); - std::vector shaderLog(logLength); - glGetShaderInfoLog(shader, logLength, &logLength, &shaderLog[0]); - printf("shader log: %s", &shaderLog[0]); -} - GLuint useShaders() { GLint status; @@ -121,9 +117,10 @@ int main() { glfwGetFramebufferSize(window, &width, &height); glViewport(0, 0, width, height); - GLuint shaderProgram = useShaders(); + useShaders(); - GLint flippedLoc = glGetUniformLocation(shaderProgram, "flipped"); + initEyes(); + initMouth(); GLuint VBOS[2]; glGenBuffers(2, (GLuint*) &VBOS); @@ -140,15 +137,8 @@ int main() { glClearColor(.0f, .0f, .0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); - glUniform1i(flippedLoc, 1); - glBindBuffer(GL_ARRAY_BUFFER, VBOS[0]); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); - glDrawArrays(GL_LINE_LOOP, 0, 3); - - glUniform1i(flippedLoc, -1); - glBindBuffer(GL_ARRAY_BUFFER, VBOS[1]); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); - glDrawArrays(GL_LINE_LOOP, 0, 3); + drawEyes(); + drawMouth(); glfwSwapBuffers(window); glfwPollEvents(); diff --git a/src/mouth.cc b/src/mouth.cc new file mode 100644 index 0000000..2d63921 --- /dev/null +++ b/src/mouth.cc @@ -0,0 +1,80 @@ +#include "mouth.h" + +#include + +#include "log.h" + +const char* mouth_vertex_shader = +"#version 120\n" +"attribute vec3 aPos;\n" +"uniform int flipped;\n" +"void main() {\n" +" // scale pixel position to +-1;\n" +" gl_Position = vec4(aPos.x/400 -1, aPos.y/240 -1, aPos.z, 1.0);\n" +"};"; + +const char* mouth_fragment_shader = +"#version 120\n" +"void main() {" +" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);" +"};"; + +float mouthLines[] { + 360, 120, 0, + 400, 90, 0, + 440, 120, 0 +}; + +GLuint mouthShaderProgram; + +mouth_t mouth; + +void setMouthShader() { + GLint status; + + auto vShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vShader, 1, &mouth_vertex_shader, NULL); + glCompileShader(vShader); + glGetShaderiv(vShader, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) { + logShaderOopsie(vShader); + return; + } + + auto fShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fShader, 1, &mouth_fragment_shader, NULL); + glCompileShader(fShader); + glGetShaderiv(fShader, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) { + logShaderOopsie(vShader); + return; + } + + mouthShaderProgram = glCreateProgram(); + glAttachShader(mouthShaderProgram, vShader); + glAttachShader(mouthShaderProgram, fShader); + glLinkProgram(mouthShaderProgram); + glGetProgramiv(mouthShaderProgram, GL_LINK_STATUS, (int *)&status); + if (status == GL_FALSE) { + printf("uhoh program\n"); + } + + glDeleteShader(vShader); + glDeleteShader(fShader); +} + +void initMouth() { + setMouthShader(); + + glGenBuffers(1, &mouth.vertexBufferObject); + glBindBuffer(GL_ARRAY_BUFFER, mouth.vertexBufferObject); + glBufferData(GL_ARRAY_BUFFER, sizeof(mouthLines), mouthLines, GL_STATIC_DRAW); +} + +void drawMouth() { + glUseProgram(mouthShaderProgram); + + glBindBuffer(GL_ARRAY_BUFFER, mouth.vertexBufferObject); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); + glDrawArrays(GL_LINE_STRIP, 0, 3); +} diff --git a/src/mouth.h b/src/mouth.h new file mode 100644 index 0000000..0972fa0 --- /dev/null +++ b/src/mouth.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +typedef struct mouth { + // mouth state + // index to buffer object + GLuint vertexBufferObject; +} mouth_t; + +extern mouth_t mouth; + +void initMouth(); + +void drawMouth();