opengl模板测试

编程入门 行业动态 更新时间:2024-10-14 06:23:37

opengl<a href=https://www.elefans.com/category/jswz/34/1770549.html style=模板测试"/>

opengl模板测试

  • 这里很多源码包括shader都要改变,所以直接用已有代码进行替换
  • 主函数也相应的需要修改类也发生改变了

修改

  • shader类封装着色器绑定函数
//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 = (2.0 * near * far) / (far + near - z * (far - near));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);//cout<<" x:"<<wolrdPostion.r<<" y:"<<wolrdPostion.g<<" z:"<<wolrdPostion.b<<" w:"<<w<<endl;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";//cout<<"没有点中模型...."<<endl;}}
}
  • main函数修改(绘画部分修改)
  • draw区分选中与不选中是不同结果的
        //ourModel.Draw(cubeShader);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(); //创建一个窗口指针,因为里边是一个空指针所有init函数必须改变类型//着色    Shader modelShader("cube.vert", "cube.frag");Shader stencilShader("cube.vert", "stencil.frag");//glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);   //防止窗口对鼠标进行拦截glfwSetScrollCallback(window, scroll_callback);glEnable(GL_DEPTH_TEST);    //打开深度缓存测试glEnable(GL_STENCIL_TEST);  //打开模板测试glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);  //使用执行函数:如果测试不通过就保留,深度测试不通过也保留,都通过就replace//使用model类生成model对象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;//设置颜色值和透明度,需要链接opengl32库才行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);  //透视投影:FOV,屏幕长宽比,近,远。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);//ourModel.Draw(cubeShader);for (_modelsIter = _models.begin(); _modelsIter != _models.end(); _modelsIter++){if (_modelsIter->first == modelSelected)//看是否选中{glStencilFunc(GL_ALWAYS, 1, 0xFF);//如果模型是选中状态的就都写成1(都可以通过)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);   //使用之前先关闭否则就原来的也给渲染了,如果=1就抛弃你的点glStencilMask(0x00);    //任何图形通过都会变成0,关闭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;
}

结果

更多推荐

opengl模板测试

本文发布于:2024-02-05 09:45:17,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1744794.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模板   测试   opengl

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!