facecam2d/src/graphics.cpp

191 lines
5.1 KiB
C++
Raw Normal View History

2020-12-31 12:58:39 +00:00
#include <GL/glew.h>
2021-01-07 05:12:36 +00:00
#include <GL/freeglut.h>
2020-12-31 12:58:39 +00:00
#include <glm/mat4x4.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include <iostream>
#include <graphics.hpp>
2021-01-01 16:20:09 +00:00
#include <modelpart.hpp>
#include <model.hpp>
#include <paths.hpp>
#include <config.hpp>
#include <cv.hpp>
2021-02-06 04:12:37 +00:00
#include <args.hpp>
2020-12-31 12:58:39 +00:00
GLuint shader; //standard shader program used for all elements
GLuint transUniform; //location of the "transMatrix" transformation matrix uniform in the shader
2021-01-01 16:20:09 +00:00
//parts of the model (see modelpart.hpp)
Model* model;
2020-12-31 12:58:39 +00:00
void display () {
glClear(GL_COLOR_BUFFER_BIT);
model->draw();
2020-12-31 12:58:39 +00:00
glutSwapBuffers();
}
void initBuffers (GLuint* vaoNum) {
2020-12-31 12:58:39 +00:00
//TODO: put quad stuff in header file or something
GLfloat quad[] = {
//vertex UV/texcoord
0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 0.0f,
};
GLuint quadElements[] = {
0, 1, 2,
2, 3, 0
};
glGenVertexArrays(1, vaoNum);
glBindVertexArray(*vaoNum);
GLuint vbo; //vertex buffer
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//change to GL_DYNAMIC_DRAW when using deformable meshes
glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW);
GLuint ebo; //element buffer
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quadElements), quadElements, GL_STATIC_DRAW);
//tell OpenGL what to put in the input vars
GLuint posAttr = glGetAttribLocation(shader, "position");
glVertexAttribPointer(posAttr, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), 0);
glEnableVertexAttribArray(posAttr);
GLuint uvAttr = glGetAttribLocation(shader, "texcoord");
glVertexAttribPointer(uvAttr, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (void*)(2*sizeof(GLfloat)));
glEnableVertexAttribArray(uvAttr);
}
void initGraphics () {
int argc = 1;
char *argv[1] = {(char*)"fc2d"};
glutInit(&argc, argv);
glutCreateWindow(PROJECT_NAME);
glutInitWindowSize(512, 512);
glewExperimental = GL_TRUE;
glewInit();
initShader();
2021-02-06 04:12:37 +00:00
model = new Model(resolvePath(("models/"+optData.model+".fma").c_str()).c_str());
//enable blending for alpha textures
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//set background color
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
2021-01-01 16:20:09 +00:00
glutDisplayFunc(display);
std::cout << "graphics init complete" << std::endl;
}
void initTexture (GLuint* texNum, unsigned char* buffer, size_t bufferLength) {
glGenTextures(1, texNum);
glBindTexture(GL_TEXTURE_2D, *texNum);
int x, y, channels;
GLubyte* pixels = stbi_load_from_memory(buffer, bufferLength, &x, &y, &channels, 4);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void initShader() {
2020-12-31 12:58:39 +00:00
const char* vsSrc =
"#version 120\n"
"attribute vec2 position;"
"attribute vec2 texcoord;"
"varying vec2 uv;"
2020-12-31 12:58:39 +00:00
"uniform mat4 transMatrix;"
"void main () {"
"gl_Position = transMatrix * vec4(position, 0.0, 1.0);"
"uv = texcoord;"
"}";
const char* fsSrc =
"#version 120\n"
"varying vec2 uv;"
2020-12-31 12:58:39 +00:00
"uniform sampler2D tex;"
"void main () {"
"gl_FragColor = texture2D(tex, uv);"
2020-12-31 12:58:39 +00:00
"}";
//compile vert shader
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vsSrc, NULL);
glCompileShader(vs);
GLint status;
glGetShaderiv(vs, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) { std::cout << "vertex shader borked" << std::endl;
printShaderCompileLog(vs); }
//compile frag shader
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fsSrc, NULL);
glCompileShader(fs);
glGetShaderiv(fs, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) { std::cout << "fragment shader borked" << std::endl;
printShaderCompileLog(vs); }
//link shaders into a shader program
shader = glCreateProgram();
glAttachShader(shader, vs);
glAttachShader(shader, fs);
//glBindFragDataLocation(shader, 0, "color");
2020-12-31 12:58:39 +00:00
glLinkProgram(shader);
glUseProgram(shader);
//set an identity ("do nothing") transformation matrix as default
2020-12-31 12:58:39 +00:00
transUniform = glGetUniformLocation(shader, "transMatrix");
glUniformMatrix4fv(transUniform, 1, GL_FALSE, glm::value_ptr(glm::mat4(1.0f)));
}
void graphicsFrame () {
glutMainLoopEvent();
}
void printShaderCompileLog(GLuint shader) {
char logBuffer[1024];
glGetShaderInfoLog(shader, 1024, NULL, logBuffer);
std::cout << "Compile log for shader " << shader << std::endl;
std::cout << logBuffer << std::endl;
}
void updateModel(struct FaceData faceData) {
/*
//calculate transforms
2021-01-10 07:13:32 +00:00
parts[0].setTransform(headPos, rotation, scale);
parts[1].setTransform(facePos, rotation, scale);
parts[2].setTransform(facePos, rotation, scale);
//set mouth texture to open or closed
parts[2].selectTexture(mouthOpen ? 1 : 0);
*/
model->updateTransforms(faceData);
2020-12-31 12:58:39 +00:00
//tell FreeGLUT to schedule a screen update
2020-12-31 12:58:39 +00:00
glutPostRedisplay();
}