当前位置: 首页 > news >正文

OpengGL教程(三)---使用VAO和VBO方式绘制三角形

本章参考官方教程:learnopengl-cn

VertexShader.glsl

#version 330 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 color;
uniform mat4 projection; // 投影矩阵
out vec4 ourColor;	
void main()
{gl_Position = projection * vec4(position,1.0f);ourColor = vec4(color,1.0f);
}

FragmentShader.glsl

#version 330 core
in vec4 ourColor;
out vec4 FragColor;
void main()
{FragColor = ourColor;
}

GlslDealConfig.h

#pragma once#include <iostream>
#include <string>
#include <fstream>
#include <sstream>class GlslDealConfig
{public:GlslDealConfig() {}~GlslDealConfig() {}public:std::string ReadGlslFile(const std::string& filename);};

GlslDealConfig.cpp

#include "GlslDealConfig.h"std::string GlslDealConfig::ReadGlslFile(const std::string& filename)
{std::string data;std::ifstream ifs(filename,std::ios::in);if(!ifs.is_open()){printf("open %s failed",filename.c_str());return data;}std::ostringstream fs;fs << ifs.rdbuf();data = fs.str();return data;
}

main.cpp

#include <iostream>#include "glew.h"
#include "glfw3.h"#include "glm/glm.hpp"                  // GLM 的基本数学类型,例如 glm::mat4 和 glm::vec3
#include "glm/gtc/matrix_transform.hpp" // GLM 的矩阵变换函数,例如 glm::ortho
#include "glm/gtc/type_ptr.hpp"         // 用于 glm::value_ptr 函数#include "log.h"
#include "GlslDealConfig.h"GLfloat vertices_1[] = 
{0.0f, 0.0f, 0.0f,		// 上顶点700.0f, 0.0f, 0.0f,		// 左顶点700.0f, 700.0f, 0.0f,	// 右顶点};GLfloat vertices_2[] = 
{1.0f, 0.0f, 0.0f,		// 上顶点0.0f, 1.0f, 0.0f,		// 左顶点0.0f, 0.0f, 1.0f,		// 右顶点};int main()
{GlslDealConfig mdeal;int major = 0, minor = 0, rev = 0;glfwGetVersion(&major, &minor, &rev);LOGI("glfw version %d - %d - %d", major,minor,rev);if (glfwInit() == GLFW_FALSE){LOGE("glfwInit failed");return 0;}glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);GLFWwindow* window = glfwCreateWindow(700, 700, "Hello OpenGL", NULL, NULL);if (window == NULL){LOGE("glfwCreateWindow failed");return 0;}glfwMakeContextCurrent(window);GLenum err = glewInit();if (err != GLEW_OK){LOGE("glew init failed : %s", reinterpret_cast<const char*>(glewGetErrorString(err)));return 0;}glfwSwapInterval(1);std::string vertexShader = mdeal.ReadGlslFile("/home/ryan/zxp/Rendering/glsl/VaoAndVbo/VertexShader.glsl");std::string fragmentShader = mdeal.ReadGlslFile("/home/ryan/zxp/Rendering/glsl/VaoAndVbo/FragmentShader.glsl");const GLchar *vData = vertexShader.c_str();const GLchar *fData = fragmentShader.c_str();GLuint vShader = glCreateShader(GL_VERTEX_SHADER);GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(vShader, 1, &vData, NULL);glShaderSource(fShader, 1, &fData, NULL);glCompileShader(vShader);glCompileShader(fShader);GLuint progma = glCreateProgram();glAttachShader(progma, vShader);glAttachShader(progma, fShader);glLinkProgram(progma);glDeleteShader(vShader);glDeleteShader(fShader);GLuint VAO, VBO[2];glGenVertexArrays(1, &VAO);glGenBuffers(2, VBO);glBindVertexArray(VAO);// 绑定第一个 VBO 并设置顶点属性指针glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_1), vertices_1, GL_STATIC_DRAW);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);glEnableVertexAttribArray(0);// 绑定第二个 VBO 并设置顶点属性指针glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_2), vertices_2, GL_STATIC_DRAW);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);glEnableVertexAttribArray(1);// 解绑 VAOglBindVertexArray(0);glm::mat4 projection = glm::ortho(0.0f, 600.0f, 0.0f, 600.0f, -1.0f, 1.0f);glUseProgram(progma);GLuint projLoc = glGetUniformLocation(progma, "projection");glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));// 绘制循环while (!glfwWindowShouldClose(window)){glViewport(0, 0, 700, 700);glClearColor(0.0f, 0.0f, 0.0f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);glUseProgram(progma);glBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, 3);glBindVertexArray(0);glfwSwapBuffers(window);glfwPollEvents();}glDeleteVertexArrays(1, &VAO);glDeleteBuffers(2, VBO);glDeleteProgram(progma);glfwTerminate();return 0;
}

解释: 解释: 解释:

1、为什么要先绑定VAO在设置顶点属性然后解绑VAO?

在 OpenGL 中,使用顶点数组对象(VAO)可以方便地管理顶点属性的状态。绑定 VAO、设置顶点属性、然后解绑 VAO 的顺序是为了确保顶点属性的设置被正确地记录在 VAO 中,从而简化渲染代码并提高效率。

2、为什么有两次glUseProgram

设置Uniform变量之前必须使用正确的着色器程序
在调用 glUniformMatrix4fv 来设置 projection 矩阵之前,你必须激活(或使用)你要更新的着色器程序(progma)。glUniformMatrix4fv 更新的是当前使用的着色器程序中的 projection uniform 变量。
因此,如果你在设置 uniform 变量之前没有使用正确的着色器程序,那么 glUniformMatrix4fv 将无法正确更新 uniform 变量,这可能导致渲染结果不正确或无法渲染。

在 glUseProgram(progma); 调用之后,所有的着色器相关的操作(如设置 uniform 变量、绘制调用)都将作用于 progma。如果你在设置 uniform 变量之前没有调用 glUseProgram(progma);,那么 uniform 设置将不会生效,因为你没有切换到正确的着色器程序。

绘制循环中的 glUseProgram(progma); 确保在绘制操作时,使用的是正确的着色器程序。
如果这个调用被省略,绘制操作将不会使用你期望的着色器程序,可能导致渲染结果错误。

运行截图

在这里插入图片描述
感谢阅读^ _ ^
如有错误感谢指正。

联系我的方式
Q Q : 918619587 QQ : 918619587 QQ:918619587

http://www.lryc.cn/news/435269.html

相关文章:

  • 【单片机开发】单片机常用开发工具
  • 一、计算机网络的体系结构
  • C语言补习课——文件篇
  • 【可测试性实践】C++ 单元测试代码覆盖率统计入门
  • C++笔记---list
  • JavaWeb开发中为什么Controller里面的方法是@RequestMapping?
  • 若依移动版使用微信小程序打开失败
  • 精准控图工具 Concept Sliders:超好用的 控制 Lora 适配器
  • 【EI会议征稿通知】第四届材料工程与应用力学国际学术会议(ICMEAAE 2025)
  • Hadoop安全之Knox
  • SprinBoot+Vue应急信息管理系统的设计与实现
  • 索尼研究的AI部门将与AI新加坡合作开发大型语言模型
  • 【OJ刷题】双指针问题
  • 基于SpringBoot+Vue+MySQL的校园食堂订餐
  • uniapp业务实现
  • Windows和Mac命令窗快速打开文件夹
  • 智能制造云平台---附源码79117
  • 降本、创新、合作,谁才是连接器行业破除内卷的关键词?
  • 可能一拆为二,英特尔为何走到今天这一步?
  • 了解Redis集群概念,集群如何选举主节点
  • Ozon跨境商家提升销量的关键:测评补单策略与必备条件
  • 缺乏大模型经验,还有机会吗?
  • 如何阅读李冬梅老师《数据结构》
  • Python————正则表达式
  • 将你的github仓库设置为web代理
  • CTFHub技能树-Git泄漏-Index
  • vb.net发送邮件:如何高效地实现邮件发送?
  • mycat双主高可用架构部署-水评分表-范围分片配置
  • 开发模型例题
  • 一文搞懂 TS中 函数、枚举、别名 | TypeScript 入门指南 06