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
相关文章:
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(p…...
【单片机开发】单片机常用开发工具
【前言】 在嵌入式系统领域,单片机(Microcontroller, MCU)作为核心组件,广泛应用于智能家居、工业控制、汽车电子等众多领域。而单片机开发工具,则是开发者们实现创意、解决问题的重要助手。本文主要讲述目前主流的单…...
一、计算机网络的体系结构
1.1 计算机网络的组成 1)从组成部分上分为:硬件、软件、协议。硬件是指主机、通信链路、交换设备和通信处理机组曾。软件包括各种实现资源共享的软件以及各种软件工具(如网络操作系统、邮件收发程序、FTP程序、聊天软件)。 2&…...
C语言补习课——文件篇
来源:黑马程序员 第157讲 C语言操作文件概述 读取文件:输入流 写文件:输出流 读写的方向判断取决与参照,一般我们站在程序的角度判断读写方向。 第158讲 路径 基本概念 路径就是指文件在电脑中的位置,eg…...
【可测试性实践】C++ 单元测试代码覆盖率统计入门
引言 最近在调研C工程怎么做单元测试和代码覆盖率统计,由于我们工程有使用Boost库,尝试使用Boost.Test来实现单元测试并通过Gcov和Lcov来生成代码覆盖率报告。本文记录完整的搭建测试Demo,希望能带来一定参考。 常用C单测框架对比 特性Goo…...
C++笔记---list
1. list的介绍 list其实就是就是我们所熟知的链表(双向循环带头结点),但其是作为STL中的一个类模板而存在。 也就是说,list是可以用来存储任意类型数据的顺序表,既可以是内置类型,也可以是自定义类型&…...
JavaWeb开发中为什么Controller里面的方法是@RequestMapping?
在Java Web开发中,尤其是在使用Spring MVC框架时,RequestMapping注解被广泛应用于Controller层的方法上,这是因为RequestMapping是Spring MVC提供的一个核心注解,用于将HTTP请求映射到相应的处理器类或处理器方法上。通过这种方式…...
若依移动版使用微信小程序打开失败
现象 解决办法:删掉自带的appid...
精准控图工具 Concept Sliders:超好用的 控制 Lora 适配器
Concept Sliders 你有没有遇到这样的情况?你花费大量时间制作提示和寻找种子,以使用文本到图像模型生成所需的图像。但是,你还需要对生成图像中的属性强度(如眼睛大小或照明)进行更细致、更精细的控制。修改提示会破坏…...
【EI会议征稿通知】第四届材料工程与应用力学国际学术会议(ICMEAAE 2025)
第四届材料工程与应用力学国际学术会议(ICMEAAE 2025) 2025 4th International Conference on Materials Engineering and Applied Mechanics 本次会议将重点讨论材料科学、应用力学等领域的最新研究进展与发展趋势。会议旨在为国内外从事这些领域研究…...
Hadoop安全之Knox
Apache Knox 是一个 REST API 网关,为 Hadoop 集群提供安全的访问方式。Knox 提供了一层保护,简化了对 Hadoop 生态系统(如 HDFS、YARN、Hive、HBase 等)中各个组件的访问,并通过单点登录 (SSO)、认证、授权和审计功能…...
SprinBoot+Vue应急信息管理系统的设计与实现
目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质…...
索尼研究的AI部门将与AI新加坡合作开发大型语言模型
索尼研究公司签署了一项合作协议,以帮助测试和优化东南亚语言一网通(SEA-LION)人工智能(AI)模型,重点关注印度语言。 索尼研究公司的AI部门将与负责开发AI新加坡(AISG)的公司合作&a…...
【OJ刷题】双指针问题
这里是阿川的博客,祝您变得更强 ✨ 个人主页:在线OJ的阿川 💖文章专栏:OJ刷题入门到进阶 🌏代码仓库: 写在开头 现在您看到的是我的结论或想法,但在这背后凝结了大量的思考、经验和讨论 目录 1…...
基于SpringBoot+Vue+MySQL的校园食堂订餐
系统展示 用户前台界面 管理员后台界面 系统背景 随着信息技术的飞速发展和互联网的普及,传统校园食堂的运作模式已难以满足现代学生日益增长的便捷性、个性化需求。学生们希望能够在忙碌的学习生活中,通过更加高效、便捷的方式完成就餐选择,…...
uniapp业务实现
uni.requset添加异常判断提示,以及加载动画 /*** 该函数用于发送网络请求获取数据* 请求失败时会弹出相应的错误提示* 请求成功时会检查返回的数据是否存在错误,并根据错误代码做出相应处理* 如果数据请求成功且无错误,则将返回的数据赋值给pets变量*/fu…...
Windows和Mac命令窗快速打开文件夹
Windows explorer . 和 macOS open . 命令详解 1. Windows explorer . explorer 是 Windows 上的文件资源管理器,用于通过命令行打开文件夹或文件。 常用命令格式: explorer [选项] [目标路径]. 表示当前目录,explorer . 打开当前工作目录…...
智能制造云平台---附源码79117
目 录 摘要 1 绪论 1.1 研究背景和意义 1.2开发技术 1.2.1 Flask框架 1.2.2 Python简介 1.2.3 MySQL数据库 1.3论文结构与章节安排 2系统分析 2.1 可行性分析 2.2总体设计原则 2.3 系统流程分析 2.3.1 用户登录流程 2.3.2 删除信息流程 2.4 系统角色分析 2.5 系…...
降本、创新、合作,谁才是连接器行业破除内卷的关键词?
如果用一个字来评价2024年的汽车行业,那就是「卷」。 ▲中国汽车保有量不断提升 图/Pixabay 长安汽车董事长朱华荣说:“汽车行业的卷,让中国品牌达到了新高度。” 吉利董事长李书福说:“中国汽车工业内卷程度全球第一,…...
可能一拆为二,英特尔为何走到今天这一步?
【科技明说 | 科技热点关注】 近来看到外媒消息说,英特尔迫于经营压力,也不得不铤而走险,欲将英特尔一分为二,即芯片制造与芯片设计分离开,互相剥离,独立发展。 于是乎,英特尔将分拆…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...
goreplay
1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具,可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长,测试它所需的工作量也会呈指数级增长。GoRepl…...
数据分析六部曲?
引言 上一章我们说到了数据分析六部曲,何谓六部曲呢? 其实啊,数据分析没那么难,只要掌握了下面这六个步骤,也就是数据分析六部曲,就算你是个啥都不懂的小白,也能慢慢上手做数据分析啦。 第一…...
拟合问题处理
在机器学习中,核心任务通常围绕模型训练和性能提升展开,但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正: 一、机器学习的核心任务框架 机…...
C# WPF 左右布局实现学习笔记(1)
开发流程视频: https://www.youtube.com/watch?vCkHyDYeImjY&ab_channelC%23DesignPro Git源码: GitHub - CSharpDesignPro/Page-Navigation-using-MVVM: WPF - Page Navigation using MVVM 1. 新建工程 新建WPF应用(.NET Framework) 2.…...
汇编语言学习(三)——DoxBox中debug的使用
目录 一、安装DoxBox,并下载汇编工具(MASM文件) 二、debug是什么 三、debug中的命令 一、安装DoxBox,并下载汇编工具(MASM文件) 链接: https://pan.baidu.com/s/1IbyJj-JIkl_oMOJmkKiaGQ?pw…...
C#学习12——预处理
一、预处理指令: 解释:是在编译前由预处理器执行的命令,用于控制编译过程。这些命令以 # 开头,每行只能有一个预处理指令,且不能包含在方法或类中。 个人理解:就是游戏里面的备战阶段(不同对局…...
