opengl之如何在一个窗口中绘制多个角色/物体 您所在的位置:网站首页 opengl画圆锥 opengl之如何在一个窗口中绘制多个角色/物体

opengl之如何在一个窗口中绘制多个角色/物体

2023-09-05 22:33| 来源: 网络整理| 查看: 265

自学opengl,真tm的难啊!在看完著名的learnopengl.org网站的教程之后自以为入门了,但真实情况确实不看教程画个三角形都够呛!难顶啊!!!(关于以下代码的环境配置可去这个网站:https://learnopengl-cn.github.io/) 废话不多说了,下面我将记录如何在opengl中绘制不同的物体,先贴上绘制一个物体的流程图: 在这里插入图片描述 对应上图的最后步骤就是渲染循环了;

#include #include #include #include #include #include void framebuffer_size_callback(GLFWwindow* window, int width, int height); void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); void processInput(GLFWwindow* window); // 窗口的宽 const unsigned int SCREEN_WIDTH = 800; // 窗口的高 const unsigned int SCREEN_HEIGHT = 600; //顶点着色器的源码 const char* vertexShaderSource = "#version 330 core\n" "layout(location=0) in vec3 aPos;\n" "void main()\n" "{\n" " gl_Position=vec4(aPos.x,aPos.y,aPos.z,1.0);\n" "}\0"; //第一个片元着色器的源代码 const char* fstexShaderSource = "#version 330 core\n" "out vec4 FragColor;\n" "void main()\n" "{" "FragColor=vec4(1.0f,0.5f,0.2f,1.0f);\n" "}\0"; //第二个片元着色器的源代码,使用两个片元着色器的原因是为了给两个物体使用不同的颜 //色,方便区分 const char* fstexShaderSource2 ="#version 330 core\n" "out vec4 FragColor;\n" "void main()\n" "{\n" " FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n" "}\n\0"; int main(int argc, char *argv[]) { //01从这里到 glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #ifdef __APPLE__ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); #endif glfwWindowHint(GLFW_RESIZABLE, false); //01这里:对应上图的创建opengl上下文 //02:从这里到 GLFWwindow* window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Breakout", nullptr, nullptr); glfwMakeContextCurrent(window); //02:这里对应创建窗口 //03:从这里到 if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); std::cout glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); std::cout 0.5f, 0.5f, 0.0f, // top right 0.5f, -0.5f, 0.0f, // bottom right -0.5f, -0.5f, 0.0f, // bottom left -0.5f, 0.5f, 0.0f // top left }; float vertices2[] = { 0.5f, 0.5f, 0.0f, // top right 0.5f, -0.5f, 0.0f, // bottom right -0.5f, -0.5f, 0.0f, // bottom left }; unsigned int indices[] = { // 注意索引从0开始! 0, 1, 3, // 第一个三角形 1, 2, 3 // 第二个三角形 }; //创建顶点数组对象VBO以及顶点缓冲数组对象VA0 unsigned int EBO,VBO[2], VAO[2]; glGenVertexArrays(2, VAO); glGenBuffers(2, VBO); glGenBuffers(1, &EBO); //首先绑定顶点数组对象,然后绑定并设置顶点缓冲区,然后配置顶点属性。 glBindVertexArray(VAO[0]); glBindBuffer(GL_ARRAY_BUFFER, VBO[0]); //注意此处我们使用了顶点索引 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); //启用或则禁用顶点属性数组,参数为要启用或则禁用的常规顶点的属性的索引 glEnableVertexAttribArray(0); /***绑定第二个对象***/ //在绘制第二个物体时没有使用顶点索引 glBindVertexArray(VAO[1]); glBindBuffer(GL_ARRAY_BUFFER, VBO[1]); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2,GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float) , (void*)0); glEnableVertexAttribArray(0); /***开始渲染循环***/ while (!glfwWindowShouldClose(window)) { //判断是否关闭窗口 processInput(window); //使用特定的颜色清屏 glClearColor(0.2f, 0.3f, 0.3f, 1.0f); //这个函数的功能很多,有兴趣的可以研究下 glClear(GL_COLOR_BUFFER_BIT); //绘制第一个物体 glUseProgram(shaderProgram); //绑定相对应的顶点数据 glBindVertexArray(VAO[0]); //因为第一个物体我们使用了顶点索引EBO,所以此处我们调用的函数是 //glDrawElements glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); /***绘制第二个物体***/ glUseProgram(shaderProgram2); glBindVertexArray(VAO[1]); //第二个物体只使用了VBO和VAO,所以此处调用了glDrawArrays glDrawArrays(GL_TRIANGLES, 0, 3); //使用离屏绘制,交换缓冲 glfwSwapBuffers(window); //函数检查有没有触发什么事件(比如键盘输入、鼠标移动等)、更新窗口状 //态, //并调用对应的回调函数(可以通过回调方法手动设置)。 glfwPollEvents(); } //渲染循环结束,释放资源 glDeleteVertexArrays(2, VAO); glDeleteBuffers(2, VBO); glDeleteBuffers(1, &EBO); //释放所有分配的资源 glfwTerminate(); return 0; } //处理键盘事件 void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, true); if (key >= 0 && key glViewport(0, 0, width, height); } //窗口管理 void processInput(GLFWwindow* window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); }

实现效果:一个四边形和一个三角形(四边形被挡住了一半) 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有