从编译OpenGL库到我的第一个颜色变化的三角形-Shader

2024-03-01 08:08

本文主要是介绍从编译OpenGL库到我的第一个颜色变化的三角形-Shader,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大学开始就在接触OpenGL,但是都是“见缝插针”式的学习,一直想着有机会走一遍OpenGL该有的学习过程。前段时间终于鼓起勇气,踏出这个久违的第一步。此前一直觉得CMake编译会很难,但是真的实践下来,发现其实也不是很难。

第一步:下载相关的材料,编译OpenGL库,并测试。

1.下载glfw包,git形式:http://192.168.1.108/svn/webgl/client/branch/1.0.3  网址:http://www.glfw.org/

2.下载CMake安装包,网址:https://cmake.org/

3.下载glew包,git形式: https://github.com/nigels-com/glew.git glew 网址:http://glew.sourceforge.net/

注:这个网址下的glew包的对应VS版本:VC6、VC10、VC12、VC14、VC15,如果是更高的VS版本,这需要另外找glew包,建议是到官网下。

 

(1)首先安装CMake软件。

(2)在电脑里任意目录下新建一个文件专门安放OpenGL相关库,例如文件夹名“OpenGL”,子目录有“include”和“libs”。

(3)由于glew不需要经过Cmake,可直接使用VS打开下载的glew>build目录下的对应VS版本的工程项目,进行编译。编译成功之后,打开glew目录下的lib->Debug->Win32,

将glew32d.lib和glew32sd.lib文件拷贝到上述的“libs”目录下;glew目录下的include目录下的整个“GL”文件夹拷贝到上述的“include”目录下。

(4)在glfw目录下新建一个“build”文件夹,打开CMake软件(点击运行cmake-gui.exe程序),在<where to the source code>处选择你的glfw所在的目录,在<where to build the binaries> 处选择刚刚新建的“build”文件夹所在的目录,如图:

然后点击<Configure> 选择你的VS版本,其他选项默认,之后点击“Finish”,等待几秒最后点击“Generate”按钮。之后就可以关闭CMake了。

在刚刚新建的“build”目录中,会增加一些文件,双击GLFW.sln,启动VS,按F7键等待工程生成完毕,在刚新建的build目录,build->src->Debug目录下会有一个glfw3.lib,这是我们所需要的,将glfw3.lib拷贝到上述的“OpenGL”->“libs”目录下。在glfw->include目录下会生成“GLFW”,将其整个拷贝到上述的“OpenGL”->“include”目录下。

到此,OpenGL库生成完毕。

(5)项目测试。

打开VS软件,新建一个空的C++工程项目,在项目属性中<配置属性>-><VC++目录>-><包含目录>添加上述“OpenGL”->“include”所在的目录,在<库目录>中添加上述“OpenGL”->“libs”所在的目录,在<链接器>-><输入>-><附加依赖项>中添加文件:glfw3.lib   glew32sd.lib   opengl32.lib,其中opengl32.lib是安装VS的时候直接就包含了。

新建一个.cpp文件,复制下面的代码:

 

 
#include <iostream> // GLEW #define GLEW_STATIC #include <GL/glew.h> // GLFW #include <GLFW/glfw3.h> // Window dimensions const GLuint WIDTH = 800, HEIGHT = 600; // The MAIN function, from here we start the application and run the game loop int main() { std::cout << "Starting GLFW context, OpenGL 3.3" << std::endl; // Init GLFW glfwInit(); // Set all the required options for GLFW glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Create a GLFWwindow object that we can use for GLFW's functions GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); if (window == nullptr) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions glewExperimental = GL_TRUE; // Initialize GLEW to setup the OpenGL Function pointers if (glewInit() != GLEW_OK) { std::cout << "Failed to initialize GLEW" << std::endl; return -1; } // Define the viewport dimensions int width, height; glfwGetFramebufferSize(window, &width, &height); glViewport(0, 0, width, height); // Game loop while (!glfwWindowShouldClose(window)) { // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); // Swap the screen buffers glfwSwapBuffers(window); } // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate(); return 0; }

然后进行编译即可。
第二步:创建我的变化三角形-着色器
同样新建一个C++空工程项目,使用着色器来显示绘制的三角形。关于着色器,这里说的很详细。完整的代码可参见下面。

#include <iostream>
#include <cmath>// GLEW
#define GLEW_STATIC
#include <GL/glew.h>// GLFW
#include <GLFW/glfw3.h>// Function prototypes
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 600;// Shaders
const GLchar* vertexShaderSource = "#version 330 core\n""layout (location = 0) in vec3 position;\n""layout (location = 1) in vec3 color;\n""out vec3 ourColor;\n""void main()\n""{\n""gl_Position = vec4(position, 1.0);\n""ourColor = color;\n""}\0";
const GLchar* fragmentShaderSource = "#version 330 core\n""out vec4 color;\n""uniform vec4 ourColor;\n""void main()\n""{\n""color = ourColor;\n""}\n\0";// The MAIN function, from here we start the application and run the game loop
int main()
{// Init GLFWglfwInit();// Set all the required options for GLFWglfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);// Create a GLFWwindow object that we can use for GLFW's functionsGLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);glfwMakeContextCurrent(window);// Set the required callback functionsglfwSetKeyCallback(window, key_callback);// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensionsglewExperimental = GL_TRUE;// Initialize GLEW to setup the OpenGL Function pointersglewInit();// Define the viewport dimensionsglViewport(0, 0, WIDTH, HEIGHT);// Build and compile our shader program// Vertex shaderGLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);glCompileShader(vertexShader);// Check for compile time errorsGLint success;GLchar infoLog[512];glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;}// Fragment shaderGLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);glCompileShader(fragmentShader);// Check for compile time errorsglGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;}// Link shadersGLuint shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);// Check for linking errorsglGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);// Set up vertex data (and buffer(s)) and attribute pointersGLfloat vertices[] = {// Positions        0.5f, -0.5f, 0.0f,  // Bottom Right-0.5f, -0.5f, 0.0f,  // Bottom Left0.0f,  0.5f, 0.0f   // Top };GLuint VBO, VAO;glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// Position attributeglVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);glEnableVertexAttribArray(0);glBindVertexArray(0); // Unbind VAO// Game loopwhile (!glfwWindowShouldClose(window)){// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functionsglfwPollEvents();// Render// Clear the colorbufferglClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);// Be sure to activate the shaderglUseProgram(shaderProgram);// Update the uniform colorGLfloat timeValue = glfwGetTime();GLfloat greenValue = (sin(timeValue) / 2) + 0.5;GLint vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);// Draw the triangleglBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, 3);glBindVertexArray(0);// Swap the screen buffersglfwSwapBuffers(window);}// Properly de-allocate all resources once they've outlived their purposeglDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);// Terminate GLFW, clearing any resources allocated by GLFW.glfwTerminate();return 0;
}// Is called whenever a key is pressed/released via GLFW
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)glfwSetWindowShouldClose(window, GL_TRUE);
}

最后的显示效果如图:




 

 

 

 

 

 

 

这篇关于从编译OpenGL库到我的第一个颜色变化的三角形-Shader的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/761744

相关文章

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时

你的华为手机升级了吗? 鸿蒙NEXT多连推5.0.123版本变化颇多

《你的华为手机升级了吗?鸿蒙NEXT多连推5.0.123版本变化颇多》现在的手机系统更新可不仅仅是修修补补那么简单了,华为手机的鸿蒙系统最近可是动作频频,给用户们带来了不少惊喜... 为了让用户的使用体验变得很好,华为手机不仅发布了一系列给力的新机,还在操作系统方面进行了疯狂的发力。尤其是近期,不仅鸿蒙O

如何评价Ubuntu 24.04 LTS? Ubuntu 24.04 LTS新功能亮点和重要变化

《如何评价Ubuntu24.04LTS?Ubuntu24.04LTS新功能亮点和重要变化》Ubuntu24.04LTS即将发布,带来一系列提升用户体验的显著功能,本文深入探讨了该版本的亮... Ubuntu 24.04 LTS,代号 Noble NumBAT,正式发布下载!如果你在使用 Ubuntu 23.

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

【WebGPU Unleashed】1.1 绘制三角形

一部2024新的WebGPU教程,作者Shi Yan。内容很好,翻译过来与大家共享,内容上会有改动,加上自己的理解。更多精彩内容尽在 dt.sim3d.cn ,关注公众号【sky的数孪技术】,技术交流、源码下载请添加微信号:digital_twin123 在 3D 渲染领域,三角形是最基本的绘制元素。在这里,我们将学习如何绘制单个三角形。接下来我们将制作一个简单的着色器来定义三角形内的像素

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO

Spring Roo 实站( 一 )部署安装 第一个示例程序

转自:http://blog.csdn.net/jun55xiu/article/details/9380213 一:安装 注:可以参与官网spring-roo: static.springsource.org/spring-roo/reference/html/intro.html#intro-exploring-sampleROO_OPTS http://stati

Windows环境利用VS2022编译 libvpx 源码教程

libvpx libvpx 是一个开源的视频编码库,由 WebM 项目开发和维护,专门用于 VP8 和 VP9 视频编码格式的编解码处理。它支持高质量的视频压缩,广泛应用于视频会议、在线教育、视频直播服务等多种场景中。libvpx 的特点包括跨平台兼容性、硬件加速支持以及灵活的接口设计,使其可以轻松集成到各种应用程序中。 libvpx 的安装和配置过程相对简单,用户可以从官方网站下载源代码