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.rhkb.cn/news/423604.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Probabilistic Embeddings for Cross-Modal Retrieval 论文阅读

Probabilistic Embeddings for Cross-Modal Retrieval 论文阅读 Abstract1. Introduction2. Related work3. Method3.1. Building blocks for PCME3.1.1 Joint visual-textual embeddings3.1.2 Probabilistic embeddings for a single modality 3.2. Probabilistic cross-modal…

Xcode 16 RC (16A242) 发布下载,正式版下周公布

Xcode 16 RC (16A242) - Apple 平台 IDE IDE for iOS/iPadOS/macOS/watchOS/tvOS/visonOS 请访问原文链接&#xff1a;https://sysin.org/blog/apple-xcode-16/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Xcode 16 的新功…

开源项目低代码表单FormCreate中通过接口加载远程数据选项

在开源项目低代码表单 FormCreate 中&#xff0c;fetch 属性提供了强大的功能&#xff0c;允许从远程 API 加载数据并将其应用到表单组件中。通过灵活的配置&#xff0c;fetch 可以在多种场景下发挥作用&#xff0c;从简单的选项加载到复杂的动态数据处理。 源码地址: Github …

软考中项(第三版) 项目成本管理总结

前言 系统集成项目管理工程师考试&#xff08;简称软考中项&#xff09;&#xff0c;其中案例分析也是很大一部分考试内容&#xff0c;目前正在学习中&#xff0c;现总结一些可能会考到的知识点供大家参考。 1.1、项目成本管理总线索 1、项目成本失控的原因 &#xff08;1&a…

每日处理250亿个事件,Canva如何应对数据洪流

在这个数据被称为“新石油”的时代&#xff0c;如何有效地处理海量信息流显得尤为重要。作为广受欢迎的设计平台&#xff0c;Canva不仅因其用户友好的界面而备受关注&#xff0c;还因其高效利用Amazon Kinesis管理每日高达250亿个事件而成为热议焦点。让我们深入探讨Canva是如何…

Java 算法:随机抽题

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 ✨特色专栏&#xff1a…

W外链怎么做微信推广链接?

"W外链"通常指的是一种可以创建短链接或者特殊功能的链接服务&#xff0c;这些链接可以用来在微信等社交平台上进行推广。由于微信对直接链接分享有一定的限制&#xff0c;使用这类服务可以帮助绕过这些限制&#xff0c;从而实现更有效的推广。 以下是使用W外链创建微…

Mysql JSON结果不能IN

开发中遇到这样一种场景&#xff0c;举例说音乐的专辑包含歌曲&#xff0c;假设歌曲放在music表&#xff0c;专辑放在album表&#xff0c;而专辑与歌曲的绑定关系&#xff0c;要么就存一个关联表music_ablum&#xff0c;要么就存一个json字段(music_list)在album表。 存一个关…

【Unity踩坑】使用Input System后UI EventSystem的冲突

在项目中使用Input System&#xff0c;在UI中添加了元素后&#xff0c;再次运行出现下面的错误&#xff1a; InvalidOperationException: You are trying to read Input using the UnityEngine.Input class, but you have switched active Input handling to Input System pac…

关于 vue/cli 脚手架实现项目编译运行的源码解析

1.vue项目运行命令解析 在日常开发中&#xff0c;vue 项目通过vue-cli-service脚手架包将项目运行起来&#xff0c;常用的命令例如&#xff1a; npm run serve npm run build 上述执行命令实际一般对应为项目中 package.json 文件的 scripts属性中编写的脚本命令&#xff0c;在…

亚马逊、沃尔玛、敦煌网、Target塔吉特、Temu环境搭建测评技术!

海外跨境电商各大主要平台正不断力推半托管模式&#xff0c;不断对商家开出众多吸引和扶持政策。全托管是指电商平台全面负责店铺的运营&#xff0c;包括仓储、配送、售后等&#xff0c;而商家主要负责提供货品。半托管模式则基本由商家自主经营&#xff0c;平台只负责仓配物流…

延迟退休,如何影响程序员?

随着人们对长寿的期待增加&#xff0c;延迟退休的趋势逐渐成为了现实。而对于已经面临35岁危机的程序员们来说&#xff0c;延迟退休可能是一个更常见的问题。 可以对照速查一下&#xff0c;延迟法定退休年龄时间表公布&#xff0c;你什么时候能退休&#xff1f; 对照速查&…

单机快速部署开源、免费的分布式任务调度系统——Apache DolphinScheduler

本文主要为大家介绍Apache DolphinScheduler的单机部署方式&#xff0c;方便大家快速体验。 环境准备 需要Java环境&#xff0c;这是一个老生常谈的问题&#xff0c;关于Java环境的安装与配置期望大家都可以熟练掌握。 验证java环境 java -version 下载安装包并解压 使用wg…

SRT3D: A Sparse Region-Based 3D Object Tracking Approach for the Real World

基于区域的方法在基于模型的单目3D跟踪无纹理物体的复杂场景中变得越来越流行。然而&#xff0c;尽管它们能够实现最先进的结果&#xff0c;大多数方法的计算开销很大&#xff0c;需要大量资源来实时运行。在下文中&#xff0c;我们基于之前的工作&#xff0c;开发了SRT3D&…

低空经济火爆:先考个无人机飞行执照傍身

随着低空经济的火爆&#xff0c;考取无人机飞行执照成为了越来越多人的选择。这不仅是对自身技能的提升&#xff0c;更是对未来职业发展的有力支撑。以下是对考取无人机飞行执照相关信息的详细解析&#xff1a; 一、低空经济与无人机飞行执照的关联性 低空经济作为战略性新兴…

Apache DolphinScheduler 跨工作流复杂依赖功能详解

大家好&#xff0c;我叫高楚枫&#xff0c;来自阿里云 EMR 团队的开发工程师&#xff0c;同时也是 Apache DolphinScheduler 的 PMC 成员之一。 今天非常高兴能在这里和大家分享关于跨工作流复杂依赖的功能详解。 引言 在现代的数据处理和调度过程中&#xff0c;工作流的依赖…

城市治理如何提升效率?推荐搭建城市综合治理平台!

随着城市化的快速发展&#xff0c;城市治理面临着前所未有的挑战。交通拥堵、环境污染、公共安全等问题日益凸显&#xff0c;传统的治理模式已难以满足现代城市的需求。在这样的背景下&#xff0c;提升城市治理效率成为了一个亟待解决的问题。本文将探讨如何通过搭建城市综合治…

Linux下如何使用CMake实现动态库的封装与调用

一、动态库的封装 1.创建工程 首先创建一个qt工程&#xff08;这里我采用的是ui工程&#xff09; 这里选择Widget工程 名字取一个和动态库相关的即可&#xff0c;我这里取的UIDLL 这里选择CMake 这里我选择命名为Dynamic kits采用Qt 5.14.2 GCC 64bit&#xff0c;之后直接下一…

智慧人居视音频解决方案探究和技术实现

智慧人居技术背景 智慧人居是一种利用先进技术和智能化系统&#xff0c;旨在提升居住环境的舒适性、便捷性和安全性的新型居住模式。随着物联网、大数据、人工智能等技术的不断发展&#xff0c;智慧人居正朝着更加智能化、个性化、集成化的方向发展。 智慧人居通过集成各种智…

c/c++ *和后置++的优先级

有时不记得c/c里运算符的优先级&#xff0c;最简单的办法就是写一个测试程序&#xff0c;这样更能直接地了解&#xff0c;如下面这个简单的代码&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h>int main(int argc, char *argv[]) …