add support for multiple textures in one part
Also added open/closed states for mouth
This commit is contained in:
parent
f1b6f5b80a
commit
72fc3d5e2c
BIN
face-eyes.png
Normal file
BIN
face-eyes.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.8 KiB |
BIN
face-mouth-closed.png
Normal file
BIN
face-mouth-closed.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
BIN
face-mouth-open.png
Normal file
BIN
face-mouth-open.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.9 KiB |
BIN
head-face.png
BIN
head-face.png
Binary file not shown.
Before Width: | Height: | Size: 9.5 KiB |
|
@ -16,7 +16,7 @@ GLuint shader; //standard shader program used for all elements
|
||||||
GLuint transUniform; //location of the "transMatrix" transformation matrix uniform in the shader
|
GLuint transUniform; //location of the "transMatrix" transformation matrix uniform in the shader
|
||||||
|
|
||||||
//parts of the model (see modelpart.hpp)
|
//parts of the model (see modelpart.hpp)
|
||||||
ModelPart parts[2];
|
ModelPart parts[3];
|
||||||
|
|
||||||
void display () {
|
void display () {
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
@ -78,7 +78,9 @@ void initGraphics () {
|
||||||
initShader();
|
initShader();
|
||||||
|
|
||||||
parts[0] = ModelPart("head-base.png", transUniform);
|
parts[0] = ModelPart("head-base.png", transUniform);
|
||||||
parts[1] = ModelPart("head-face.png", transUniform);
|
parts[1] = ModelPart("face-eyes.png", transUniform);
|
||||||
|
parts[2] = ModelPart("face-mouth-closed.png", transUniform);
|
||||||
|
parts[2].addTexture("face-mouth-open.png", 1);
|
||||||
|
|
||||||
//enable blending for alpha textures
|
//enable blending for alpha textures
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
@ -173,10 +175,14 @@ void initModel () {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateModel(glm::vec2 headPos, glm::vec2 facePos) {
|
void updateModel(glm::vec2 headPos, glm::vec2 facePos, bool mouthOpen) {
|
||||||
//calculate transforms
|
//calculate transforms
|
||||||
parts[0].setPosition(headPos);
|
parts[0].setPosition(headPos);
|
||||||
parts[1].setPosition(facePos);
|
parts[1].setPosition(facePos);
|
||||||
|
parts[2].setPosition(facePos);
|
||||||
|
|
||||||
|
//set mouth texture to open or closed
|
||||||
|
parts[2].selectTexture(mouthOpen ? 1 : 0);
|
||||||
|
|
||||||
//tell FreeGLUT to schedule a screen update
|
//tell FreeGLUT to schedule a screen update
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
|
|
|
@ -16,6 +16,6 @@ void initShader();
|
||||||
|
|
||||||
void printShaderCompileLog(GLuint shader);
|
void printShaderCompileLog(GLuint shader);
|
||||||
|
|
||||||
void updateModel(glm::vec2 headPos, glm::vec2 facePos);
|
void updateModel(glm::vec2 headPos, glm::vec2 facePos, bool mouthOpen);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,10 +3,12 @@
|
||||||
|
|
||||||
#include <graphics.hpp>
|
#include <graphics.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
int main () {
|
int main () {
|
||||||
initGraphics();
|
initGraphics();
|
||||||
|
|
||||||
cv::CascadeClassifier faceDetector ("haarcascade_frontalface_alt2.xml");
|
cv::CascadeClassifier faceDetector ("lbpcascade_frontalface_improved.xml");
|
||||||
|
|
||||||
cv::Ptr<cv::face::Facemark> facemark = cv::face::FacemarkLBF::create();
|
cv::Ptr<cv::face::Facemark> facemark = cv::face::FacemarkLBF::create();
|
||||||
facemark->loadModel ("lbfmodel.yaml");
|
facemark->loadModel ("lbfmodel.yaml");
|
||||||
|
@ -51,6 +53,8 @@ int main () {
|
||||||
(landmarks[biggestFace][2].y + landmarks[biggestFace][14].y) / 2
|
(landmarks[biggestFace][2].y + landmarks[biggestFace][14].y) / 2
|
||||||
), 6, cv::Scalar(0, 0, 255));
|
), 6, cv::Scalar(0, 0, 255));
|
||||||
cv::circle (frame, landmarks[biggestFace][30], 6, cv::Scalar (0, 255, 255));
|
cv::circle (frame, landmarks[biggestFace][30], 6, cv::Scalar (0, 255, 255));
|
||||||
|
cv::circle (frame, landmarks[biggestFace][66], 3, cv::Scalar (0, 255, 0));
|
||||||
|
cv::circle (frame, landmarks[biggestFace][62], 3, cv::Scalar (0, 255, 0));
|
||||||
|
|
||||||
//send control information to graphics
|
//send control information to graphics
|
||||||
updateModel(glm::vec2(
|
updateModel(glm::vec2(
|
||||||
|
@ -62,7 +66,8 @@ int main () {
|
||||||
glm::vec2(
|
glm::vec2(
|
||||||
landmarks[biggestFace][30].x * 2 / (float)frame.cols - 1,
|
landmarks[biggestFace][30].x * 2 / (float)frame.cols - 1,
|
||||||
landmarks[biggestFace][30].y * 2 / (float)frame.rows - 1
|
landmarks[biggestFace][30].y * 2 / (float)frame.rows - 1
|
||||||
));
|
),
|
||||||
|
landmarks[biggestFace][66].y - landmarks[biggestFace][62].y > 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
graphicsFrame ();
|
graphicsFrame ();
|
||||||
|
|
|
@ -14,18 +14,29 @@ ModelPart::ModelPart(const char* texPath, GLuint transUniformNum) {
|
||||||
//create vbo, ebo, vao
|
//create vbo, ebo, vao
|
||||||
initBuffers(&vao);
|
initBuffers(&vao);
|
||||||
//create texture
|
//create texture
|
||||||
initTexture(&tex, texPath);
|
initTexture(&tex[0], texPath);
|
||||||
|
|
||||||
transUniform = transUniformNum;
|
transUniform = transUniformNum;
|
||||||
|
|
||||||
|
empty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelPart::bindAndDraw() {
|
void ModelPart::bindAndDraw() {
|
||||||
|
if (empty) { return; }
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
glBindTexture(GL_TEXTURE_2D, tex[texSelection]);
|
||||||
glUniformMatrix4fv(transUniform, 1, GL_FALSE, glm::value_ptr(transMatrix));
|
glUniformMatrix4fv(transUniform, 1, GL_FALSE, glm::value_ptr(transMatrix));
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelPart::setPosition(glm::vec2 position) {
|
void ModelPart::setPosition(glm::vec2 position) {
|
||||||
transMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(position.x, position.y, 0.0f));
|
transMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(position.x, -position.y, 0.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelPart::addTexture(const char* texPath, size_t slot) {
|
||||||
|
initTexture(&tex[slot], texPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelPart::selectTexture(size_t slot) {
|
||||||
|
texSelection = slot;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,14 @@
|
||||||
#include <glm/ext/matrix_transform.hpp>
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
|
|
||||||
class ModelPart {
|
class ModelPart {
|
||||||
GLuint vao, tex, transUniform;
|
GLuint vao, transUniform;
|
||||||
|
|
||||||
|
GLuint tex[16]; //support 16 textures to switch between
|
||||||
|
size_t texSelection = 0;
|
||||||
|
|
||||||
glm::mat4 transMatrix = glm::mat4(1.0f);
|
glm::mat4 transMatrix = glm::mat4(1.0f);
|
||||||
|
|
||||||
|
bool empty = true;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModelPart();
|
ModelPart();
|
||||||
|
@ -15,6 +21,10 @@ class ModelPart {
|
||||||
void bindAndDraw();
|
void bindAndDraw();
|
||||||
|
|
||||||
void setPosition(glm::vec2 position);
|
void setPosition(glm::vec2 position);
|
||||||
|
|
||||||
|
void addTexture(const char* texPath, size_t slot);
|
||||||
|
|
||||||
|
void selectTexture(size_t slot);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue