add support for multiple textures in one part

Also added open/closed states for mouth
This commit is contained in:
Epicalert 2021-01-02 02:55:12 +08:00
parent f1b6f5b80a
commit 72fc3d5e2c
No known key found for this signature in database
GPG key ID: CAA46F858D0979BD
11 changed files with 42 additions and 10 deletions

BIN
face-eyes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

BIN
face.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

BIN
face.xcf Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

View file

@ -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();

View file

@ -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

View file

@ -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 ();

View file

@ -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;
} }

View file

@ -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