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

news2024/11/25 0:42:09

本章参考官方教程: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);

    // 解绑 VAO
    glBindVertexArray(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.coloradmin.cn/o/2125220.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

信息安全管理工程师

信息安全管理工程师是专门从事信息安全领域的专业人员&#xff0c;主要负责维护计算机系统、网络和数据的安全&#xff0c;以抵御潜在威胁和攻击。 随着信息技术迅猛发展&#xff0c;对此类专业人才的需求持续上升。 如何能够成为一名卓越的信息安全管理工程师呢&#xff1f;…

springboot对数据库进行备份+对一个文件夹内的文件按时间排序,只保留最近的8个文件

首先&#xff0c;对数据库进行备份&#xff0c;用到的命令&#xff1a; mysqldump --opt -h 192.168.1.200 --userroot --passwordxxx --result-fileE://data//20240911141400.sql --default-character-setutf8 xxx&#xff08;数据库名&#xff09; 直接上代码 配置文件部分…

Android 语言国际化三步

1.罗列: 可以多罗列几个 不需要全部实现 res下创建这个文件:locale-config <locale-config xmlns:android"http://schemas.android.com/apk/res/android"><locale android:name"zh" /> <!--中文 --><locale android:name"e…

优化 TCP 以提高网络性能

本页面简要介绍了计算正确设置的方法&#xff0c;以缩短 Google Cloud 和混合场景中 TCP 连接的延迟时间。本页面还可帮助您了解如何缩短 Google Cloud 中流程之间的连接延迟时间。 现代微服务架构主张&#xff0c;开发者应该构建处理单一任务的小型服务。服务应根据系统的可靠…

Open CASCADE学习|通过指定点的曲线

在OpenCASCADE中&#xff0c;如果你想通过一系列指定的点来创建一条曲线&#xff0c;你可以使用Geom2dAPI_Interpolate类来实现二维曲线的插值&#xff0c;或者使用GeomAPI_Interpolate类来实现三维曲线的插值。这些类允许你定义一条B样条曲线&#xff0c;这条曲线将精确地通过…

内网安全:反弹shell

目录 一.Netcat反弹Shell 二.PowerCat反弹Shell PowerCat和nc正向连接 PowerCat和nc反向连接 PowerCat和PowerCat反向连接 三.Bash反弹shell 四.Python 反弹Shell 一.Netcat反弹Shell 在Windows容易被杀 介绍&#xff1a; Netcat简称NC,是一个简单、可靠的网络工具,被…

0V企业级别通配符证书

OV企业级别通配符证书&#xff0c;支持顶级域名下面的所有二级子域名&#xff0c;不限制二级子域名个数&#xff0c;证书显示单位实名名称。 加密算法支持2048bits&#xff1b;签名算法支持SHA256withRSA。 可提供各种服务器的证书文件安装格式。 加密支持协议&#xff1a;T…

微信如何转发群消息给其他群或其他好友?

使用微加机器人将群消息转发到其他群或好友 工具选择&#xff1a; 近期想做一个从某个微信群将消息自动转发到另一个微信群的效果&#xff08;一些课程群和线报群只有付费才能进&#xff09; 试了市面上很多免费的转发软件&#xff0c;发现免费还是很难有好东西&#xff0c;…

Nature Communications 可远程操控食欲的口服软体机器人

肥胖对人群的的影响是深远的&#xff0c;它不仅关系到个人的健康&#xff0c;还与全球公共卫生挑战密切相关。据世界卫生组织的数据&#xff0c;全球每8人中就有1人患有肥胖症。肥胖增加了患2型糖尿病、心血管疾病、某些癌症等多种健康问题的风险&#xff0c;并对社会经济产生重…

公开课 | 金九银十,测试开发面试秘籍大公开!

随着金九银十的求职旺季悄然来临&#xff0c;你是否已经摩拳擦掌&#xff0c;准备在职场上大展拳脚了呢&#xff1f;但面对激烈的竞争和复杂的面试环节&#xff0c;你是否也曾感到过迷茫和不安&#xff1f;别担心&#xff0c;我们懂你&#xff01; 本周四&#xff0c;我们特别…

Oracle与AWS和解! Oracle市场破历史新高 4350亿美金

数据库去o风风火火&#xff0c;然而似乎对甲骨文来讲并没有丝毫影响。很多人曾经都在嘲笑Oracle在云上发力的太晚太晚&#xff0c;错过了公有云的历史发展机遇。 今天看到群里有人分享一个消息说甲骨文老板想通了&#xff0c;跟三大云厂商合作了&#xff0c;看来是真的。 我们…

通过XMLHttpRequest和window.open在浏览器中打开文件流pdf以及下载pdf

1、浏览器预览pdf&#xff1a; 首先通过接口获取文件流数据 下发是源码 var xhr new XMLHttpRequest(); xhr.open("GET", http://www.baidut.com/downloadFile); xhr.responseType "blob"; xhr.onload function(){ if(this.status 200){ var blob…

全视通医院智慧后勤全场景管理+一体化解决方案,让医院管理提质增效

在 “十四五” 时期&#xff0c;公立智慧医院建设正如火如荼地进行着。2021年&#xff0c;国家卫生健康委医政医管局发布《医院智慧管理分级评估标准体系&#xff08;试行&#xff09;》&#xff0c;从政策层面给出了推进面向医务人员的“智慧医疗”、面向患者的“智慧服务”、…

Cadenza 项目:机器学习如何改善听力受损人士的音乐聆听体验

音乐&#xff0c;作为全人类共享的文化瑰宝&#xff0c;具有强大的凝聚力&#xff0c;它不仅塑造了我们的社会风貌&#xff0c;更为我们的身心健康带来诸多益处。然而&#xff0c;听力损失却无情地削弱了这份美妙的体验。据世界卫生组织预测&#xff0c;到2050年&#xff0c;全…

大模型技术场景与商业应用(2024):赋能千行百业产业链升级

大模型技术场景与商业应用&#xff08;2024&#xff09;&#xff1a;赋能千行百业产业链升级 引言 随着人工智能技术的飞速发展&#xff0c;大模型&#xff08;Large Language Models, LLMs&#xff09;已成为推动各行业数字化转型的关键驱动力。从2023年的ChatGPT大模型爆火至…

低代码平台与统一待办:提升工作效率的新趋势

什么是低代码平台&#xff1f; 低代码平台是一种允许用户通过图形化界面和简单的拖放操作创建应用程序的开发工具。它极大地简化了应用程序的开发过程&#xff0c;使得非技术背景的用户也能够参与到应用开发中来。低代码平台通常包括预建的组件、模板和集成功能&#xff0c;大…

【论文阅读】视觉分割新SOTA: Segment Anything(SAM)

导言 随着基于对比文本—图像对的预训练&#xff08;CLIP&#xff09;方法或者模型、聊天生成预训练转换器&#xff08;ChatGPT&#xff09;、生成预训练转换器-4&#xff08;GPT-4&#xff09;等基础大模型的出现&#xff0c;通用人工智能&#xff08; AGI&#xff09;的研究…

web项目如何部署到服务器上呢?——麻烦的方法

只需关注web项目如何部署到服务器上&#xff0c;因为服务器运行时就可以访问web项目了。 一、麻烦的方法 1、首先启动服务器 &#xff08;1&#xff09;找到bin文件夹 &#xff08;2&#xff09;双击运行startup.bat文件 &#xff08;3&#xff09;运行之后的界面如下&#…

MongoDB日志级别

日志 查看当前的日志级别 根据你提供的 MongoDB 命令结果&#xff0c;命令 db.adminCommand({ getParameter: "logComponentVerbosity" }) 返回了 "ok" : 0&#xff0c;这意味着命令执行失败&#xff0c;没有成功获取到日志级别的配置信息。错误信息 &quo…

simulink基础-代码生成

模型相关设置 求解器设置 求解器选择设置为&#xff1a;定步长 离散 求解器详细设置为&#xff1a;0.01 (task1s&#xff0c;需要计数器100次) 保证仿真结果&#xff0c;在代码中无体现 代码生成设置 系统目标文件 grt.tlc 用于HIL或RCP 无法进行精确的调度要求 嵌入式选择…