- 这里很多源码包括shader都要改变,所以直接用已有代码进行替换
- 主函数也相应的需要修改类也发生改变了
修改
void Shader::setMat4(const std::string& name, const glm::mat4& mat) const
{
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
void Shader::setBool(const std::string& name, bool value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
}
void Shader::setInt(const std::string& name, int value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::setFloat(const std::string& name, float value) const
{
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::setVec2(const std::string& name, const glm::vec2& value) const
{
glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void Shader::setVec2(const std::string& name, float x, float y) const
{
glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);
}
void Shader::setVec3(const std::string& name, const glm::vec3& value) const
{
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void Shader::setVec3(const std::string& name, float x, float y, float z) const
{
glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
}
void Shader::setVec4(const std::string& name, const glm::vec4& value) const
{
glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void Shader::setVec4(const std::string& name, float x, float y, float z, float w)
{
glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
}
void Shader::setMat2(const std::string& name, const glm::mat2& mat) const
{
glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
void Shader::setMat3(const std::string& name, const glm::mat3& mat) const
{
glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
modelShader.useShader();
modelShader.setMat4("projection",projection);
modelShader.setMat4("view",view);
modelShader.setVec4("lightPos",cubePositions[1].r,cubePositions[1].g,cubePositions[1].b,1);
modelShader.setVec3("viewPos",camera.Position.r,camera.Position.g,camera.Position.b);
modelShader.setVec3("front",camera.Front.r,camera.Front.g,camera.Front.b);
modelShader.setVec3("lightColor",1.0f,1.0f,1.0f);
stencilShader.useShader();
stencilShader.setMat4("projection",projection);
stencilShader.setMat4("view",view);
- 封装点击函数(这里要将用到的map等变成修改全局变量)
void modelPicking()
{
if (pickingModelWorldPosition == true)
{
glReadPixels((int)winX, 600 - (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
float x = (2.0f * winX) / 800.0f - 1.0f;
float y = 1.0f - (2.0f * winY) / 600.0f;
float z = winZ * 2.0 - 1.0f;
pickingModelWorldPosition = false;
if (winZ < 1.0f)
{
float w = near * far / (near * winZ - far * winZ + far);
glm::vec4 wolrdPostion = glm::inverse(view) * glm::inverse(projection) * w * glm::vec4(x, y, z, 1);
for (_modelsIter = _models.begin(); _modelsIter != _models.end(); _modelsIter++)
{
float _distance = glm::distance(_modelsIter->second.first + glm::vec3(0, 7.5, 0), glm::vec3(wolrdPostion));
if (_distance < 7.5)
{
modelSelected = _modelsIter->first;
cout << _modelsIter->first << "模型被选中..." << endl;
}
}
}
else
{
modelSelected = "NULL";
}
}
}
- main函数修改(绘画部分修改)
- draw区分选中与不选中是不同结果的
for (_modelsIter = _models.begin(); _modelsIter != _models.end(); _modelsIter++)
{
if (_modelsIter->first == modelSelected)
{
glStencilFunc(GL_ALWAYS, 1, 0xFF);
model = glm::translate(trans, _modelsIter->second.first);
model = glm::rotate(model, (float)glfwGetTime(), glm::vec3(0.0f, 1.0f, 0.0f));
modelShader.useShader();
modelShader.setMat4("model", model);
_modelsIter->second.second.Draw(modelShader);
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
glStencilMask(0x00);
float scale = 1.02;
model = glm::translate(model, glm::vec3(0.0f, 7.5f, 0.0f));
model = glm::scale(model, scale * glm::vec3(1, 1, 1));
model = glm::translate(model, glm::vec3(0.0f, -7.5f, 0.0f));
stencilShader.useShader();
stencilShader.setMat4("model", model);
_modelsIter->second.second.Draw(stencilShader);
glStencilMask(0xFF);
}
else {
glStencilFunc(GL_ALWAYS, 1, 0xFF);
model = glm::translate(trans, _modelsIter->second.first);
model = glm::rotate(model, (float)glfwGetTime(), glm::vec3(0.0f, 1.0f, 0.0f));
modelShader.useShader();
modelShader.setMat4("model", model);
_modelsIter->second.second.Draw(modelShader);
}
}
- 整体,注意也要添加上清除模板的缓存
- 注意打开和关闭木板的位置(选中之前打开用完就关闭)
int main() {
GLFWwindow* window = init();
Shader modelShader("cube.vert", "cube.frag");
Shader stencilShader("cube.vert", "stencil.frag");
glfwSetScrollCallback(window, scroll_callback);
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
Model ourModel("D:/openGLResource/bin/nanosuit/nanosuit.obj");
_models.insert(pair<string, pair<glm::vec3, Model>>("Zhang3", pair<glm::vec3, Model>(cubePositions[0], ourModel)));
_models["Li4"] = pair<glm::vec3, Model>(cubePositions[2], ourModel);
while (!glfwWindowShouldClose(window)) {
currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
processInput(window);
float radius = 10.0f;
float camX = sin(glfwGetTime()) * radius;
float camZ = cos(glfwGetTime()) * radius;
glClearColor(0.2f, 0.3f, 0.3f, 0.1f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glm::mat4 trans = glm::mat4(1.0f);
model = glm::mat4(1.0f);
view = camera.GetViewMatrix();
projection = glm::mat4(1.0f);
projection = glm::perspective(glm::radians(camera.fov), 800.0f / 600.0f, near,far);
modelShader.useShader();
modelShader.setMat4("projection", projection);
modelShader.setMat4("view", view);
modelShader.setVec4("lightPos", cubePositions[1].r, cubePositions[1].g, cubePositions[1].b, 1);
modelShader.setVec3("viewPos", camera.Position.r, camera.Position.g, camera.Position.b);
modelShader.setVec3("front", camera.Front.r, camera.Front.g, camera.Front.b);
modelShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
stencilShader.useShader();
stencilShader.setMat4("projection", projection);
stencilShader.setMat4("view", view);
for (_modelsIter = _models.begin(); _modelsIter != _models.end(); _modelsIter++)
{
if (_modelsIter->first == modelSelected)
{
glStencilFunc(GL_ALWAYS, 1, 0xFF);
model = glm::translate(trans, _modelsIter->second.first);
model = glm::rotate(model, (float)glfwGetTime(), glm::vec3(0.0f, 1.0f, 0.0f));
modelShader.useShader();
modelShader.setMat4("model", model);
_modelsIter->second.second.Draw(modelShader);
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
glStencilMask(0x00);
float scale = 1.02;
model = glm::translate(model, glm::vec3(0.0f, 7.5f, 0.0f));
model = glm::scale(model, scale * glm::vec3(1, 1, 1));
model = glm::translate(model, glm::vec3(0.0f, -7.5f, 0.0f));
stencilShader.useShader();
stencilShader.setMat4("model", model);
_modelsIter->second.second.Draw(stencilShader);
glStencilMask(0xFF);
}
else {
glStencilFunc(GL_ALWAYS, 1, 0xFF);
model = glm::translate(trans, _modelsIter->second.first);
model = glm::rotate(model, (float)glfwGetTime(), glm::vec3(0.0f, 1.0f, 0.0f));
modelShader.useShader();
modelShader.setMat4("model", model);
_modelsIter->second.second.Draw(modelShader);
}
}
glfwPollEvents();
glfwSwapBuffers(window);
modelPicking();
}
glfwTerminate();
return 0;
}
结果