OpenGL 学习笔记 01 环境配置

时间:2022-09-21 23:15:08

抱歉,本文写的很乱,建议跳过代码部分。


以下教程仅适用于Mac下的Xcode编程环境!其他的我也不会搞。
推荐教程:opengl-tutorial 
本项目Github网址
 
 
 
OpenGL太可怕了。。。必需得把学的记下来,不然绝壁忘。
 
首先贴出代码,然后分析创建一个OpenGL程序都需要什么
 #include <cstdio>
#include <cstdlib> #include <GL/glew.h> #include <GLFW/glfw3.h> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
using namespace std; #include <shader.hpp>
#include <shader.cpp> static const GLfloat g_vertex_buffer_data[] = {
-1.0f,-1.0f,-1.0f, // triangle 1 : begin
-1.0f,-1.0f, 1.0f,
-1.0f, 1.0f, 1.0f, // triangle 1 : end
1.0f, 1.0f,-1.0f, // triangle 2 : begin
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f,-1.0f, // triangle 2 : end
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f
}; //每个顶点一个颜色
static const GLfloat g_color_buffer_data[] = {
0.583f, 0.771f, 0.014f,
0.609f, 0.115f, 0.436f,
0.327f, 0.483f, 0.844f,
0.822f, 0.569f, 0.201f,
0.435f, 0.602f, 0.223f,
0.310f, 0.747f, 0.185f,
0.597f, 0.770f, 0.761f,
0.559f, 0.436f, 0.730f,
0.359f, 0.583f, 0.152f,
0.483f, 0.596f, 0.789f,
0.559f, 0.861f, 0.639f,
0.195f, 0.548f, 0.859f,
0.014f, 0.184f, 0.576f,
0.771f, 0.328f, 0.970f,
0.406f, 0.615f, 0.116f,
0.676f, 0.977f, 0.133f,
0.971f, 0.572f, 0.833f,
0.140f, 0.616f, 0.489f,
0.997f, 0.513f, 0.064f,
0.945f, 0.719f, 0.592f,
0.543f, 0.021f, 0.978f,
0.279f, 0.317f, 0.505f,
0.167f, 0.620f, 0.077f,
0.347f, 0.857f, 0.137f,
0.055f, 0.953f, 0.042f,
0.714f, 0.505f, 0.345f,
0.783f, 0.290f, 0.734f,
0.722f, 0.645f, 0.174f,
0.302f, 0.455f, 0.848f,
0.225f, 0.587f, 0.040f,
0.517f, 0.713f, 0.338f,
0.053f, 0.959f, 0.120f,
0.393f, 0.621f, 0.362f,
0.673f, 0.211f, 0.457f,
0.820f, 0.883f, 0.371f,
0.982f, 0.099f, 0.879f
}; int main() {
if(!glfwInit()) {
fprintf(stderr, "Failed To init OpenGL\n");
} // We want OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, );
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, );
// To make MacOS happy; should not be needed
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don't want the old OpenGL // Open a window and create its OpenGL context
// (In the accompanying source code, this variable is global)
GLFWwindow* window;
window = glfwCreateWindow(, , "Tutorial 01", NULL, NULL);
if( window == NULL ){
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
glfwTerminate();
return -;
}
glfwMakeContextCurrent(window); // Initialize GLEW
glewExperimental = true; // Needed in core profile //z-buffer
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEFT); if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -;
} //背景颜色
glClearColor(0.0f, 0.0f, 0.4f, 0.0f); //shader
GLuint programID = LoadShaders( "/Users/jeff/IDEProjects/xcode_projects/openGL/openGL/vertex.shader", "/Users/jeff/IDEProjects/xcode_projects/openGL/openGL/fragment.shader" ); GLuint VertexArrayID;
glGenVertexArrays(, &VertexArrayID);
glBindVertexArray(VertexArrayID); //vertex buffer
GLuint vertexbuffer;
glGenBuffers(, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); //color buffer
GLuint colorbuffer;
glGenBuffers(, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW); mat4 Projection = perspective(radians(70.0f), (float)/, 0.1f, .f); mat4 View = lookAt(vec3(, , -), vec3(,,), vec3(,,)); mat4 Model = mat4(1.0f); //模型到投影转换
mat4 mvp = Projection * View * Model; GLuint MatrixID = glGetUniformLocation(programID, "mvp"); while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && !glfwWindowShouldClose(window)) {
//每次开始时清空画布
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //使用shader
glUseProgram(programID); //把变换矩阵送进shader
glUniformMatrix4fv(MatrixID, , GL_FALSE, &mvp[][]); //画三角形
glEnableVertexAttribArray();
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, , (void*)); //三角形颜色
glEnableVertexAttribArray();
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, , (void*)); //draw call
glDrawArrays(GL_TRIANGLES, , * ); glDisableVertexAttribArray();
glDisableVertexAttribArray(); glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return ;
}

Code

首先是OpenGL的文件

对于OS X的用户来说,只要安装了Xcode,OpenGL也就被安装了(因为OS X用的就是这个。。)

但是还需要其他几个库,用于处理平台相关的事情或者方便我们编程,他们分别是GLFW,GLEW,GLM

在OS X上,用brew可以很方便的安装以上几个库,安装后进入下一步。

一、配置项目文件

打开Xcode,创建项目。

在如所示的的地方配置以上3个库的头文件位置。如果不知道库安装在哪了,可以用brew info glew的方式找到安装路径

OpenGL 学习笔记 01 环境配置

配置结果如下,Libraray Search Path 不用管,后面会说

OpenGL 学习笔记 01 环境配置

现在可以在项目的代码中正确的调用各个库的头文件了,比如

#include <GLFW/glfw3.h>

但是这样是无法编译通过的,因为lib文件还没有被链接进来,编译器会找不到头文件里面函数的定义之类的。

所以需要链接所有必要的lib文件。

链接后应该如下

OpenGL 学习笔记 01 环境配置

点击那个“加号”添加lib

其中,4个framework直接搜就可以找到。

另外两个lib分别在GLEW和GLFW的安装目录下,比如我的路径如下:

[brew安装路径]/glew/1.13.0/lib/libGLEW.a

另一个同理,在安装目录的lib文件夹下面找得到。

glm库不用添加lib

至此所有的OpenGL代码应该就可以正常编译了,不过我上面贴的那段不行,因为我没贴全。。。

二、OpenGL程序的基本结构

首先需要按照以下顺序include一些头文件,这是魔法。

#include <GL/glew.h>
#include <GLFW/glfw3.h>

以上是最主要的头文件了,当然我们还需要不少辅助的东西,全部的include如下

#include <GL/glew.h>

#include <GLFW/glfw3.h>

#include <glm/glm.hpp>

#include <glm/gtc/matrix_transform.hpp>

using namespace glm;

#include <cstdio>

#include <cstdlib>

using namespace std;

OpenGL 3.0以后使用了可编程渲染管线,我们需要自己编写shader并编译

这里有个现成的编译shader的函数,拿来用就好

#ifndef SHADER_HPP
#define SHADER_HPP GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path); #endif

shader.hpp

 #include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std; #include <stdlib.h>
#include <string.h> #include <GL/glew.h> #include "shader.hpp" GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){ // Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); // Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
if(VertexShaderStream.is_open()){
std::string Line = "";
while(getline(VertexShaderStream, Line))
VertexShaderCode += "\n" + Line;
VertexShaderStream.close();
}else{
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
getchar();
return ;
} // Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if(FragmentShaderStream.is_open()){
std::string Line = "";
while(getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
} GLint Result = GL_FALSE;
int InfoLogLength; // Compile Vertex Shader
printf("Compiling shader : %s\n", vertex_file_path);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, , &VertexSourcePointer , NULL);
glCompileShader(VertexShaderID); // Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > ){
std::vector<char> VertexShaderErrorMessage(InfoLogLength+);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[]);
printf("%s\n", &VertexShaderErrorMessage[]);
} // Compile Fragment Shader
printf("Compiling shader : %s\n", fragment_file_path);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, , &FragmentSourcePointer , NULL);
glCompileShader(FragmentShaderID); // Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > ){
std::vector<char> FragmentShaderErrorMessage(InfoLogLength+);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[]);
printf("%s\n", &FragmentShaderErrorMessage[]);
} // Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID); // Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > ){
std::vector<char> ProgramErrorMessage(InfoLogLength+);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[]);
printf("%s\n", &ProgramErrorMessage[]);
} glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID); glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID); return ProgramID;
}

shader.cpp

别忘了#include <shader.hpp> 并把 shader.cpp 添加到项目的Compile Sources里

g_vertex_buffer_data 和 g_color_buffer_data 储存正方形的顶点位置信息和颜色信息

main 函数里:

 if(!glfwInit()) {
fprintf(stderr, "Failed To init OpenGL\n");
} // We want OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, );
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, );
// To make MacOS happy; should not be needed
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don't want the old OpenGL // Open a window and create its OpenGL context
// (In the accompanying source code, this variable is global)
GLFWwindow* window;
window = glfwCreateWindow(WIDTH, HEIGHT, "OpenGL Window", NULL, NULL);
if( window == NULL ){
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
glfwTerminate();
return -;
}
glfwMakeContextCurrent(window); // Initialize GLEW
glewExperimental = true; // Needed in core profile if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -;
}

init 操作

启用z-buffer

glEnable(GL_DEPTH_TEST);

glDepthFunc(GL_LESS);

我感觉注释说的够清楚了。。。直接看代码吧

 //背景颜色
glClearColor(0.0f, 0.0f, 0.4f, 0.0f); //载入并编译shader
GLuint programID = LoadShaders( "/Users/jeff/IDEProjects/xcode_projects/openGL/openGL/vertex.shader", "/Users/jeff/IDEProjects/xcode_projects/openGL/openGL/fragment.shader" ); //VAO
//加速存储效率,储存VBO
//Veretx Array Object
GLuint VertexArrayID;
//创建
glGenVertexArrays(, &VertexArrayID);
//绑定
glBindVertexArray(VertexArrayID); //以下创建两个VBO
//Vertex Buffer Object
//用于将数据储存到显存中 //第一个VBO
//储存顶点数据
GLuint vertexbuffer;
//创建
glGenBuffers(, &vertexbuffer);
//绑定
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
//储存数据
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); //第二个VBO
//储存颜色信息
//操作原理同上
GLuint colorbuffer;
glGenBuffers(, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW); //创建坐标变换矩阵
//本地 -> 世界 -> 视口 -> 齐次剪裁空间 空间变换流程
// Model View Projection 对应需要的矩阵
//透视变换
mat4 Projection = perspective(radians(70.0f), (float)WIDTH / HEIGHT, 0.1f, .f);
//视口变换
mat4 View = lookAt(vec3(, , ), vec3(,,), vec3(,,));
//本地变换
mat4 Model = mat4(1.0f); //集成本地到齐次剪裁空间的转换
mat4 MVP = Projection * View * Model; //从shader中取出mvp (不是上面的MVP,特地用大小写区分了)
//方便等会传入数据
GLuint MatrixID = glGetUniformLocation(programID, "mvp"); while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && !glfwWindowShouldClose(window)) {
//每次开始时清空画布
//同时清空z-buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //使用shader
glUseProgram(programID); //把变换矩阵送进shader
glUniformMatrix4fv(MatrixID, , GL_FALSE, &MVP[][]); //把顶点信息送入shader
//数字0对应vertex shader中的 location = 0
glEnableVertexAttribArray();
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, , (void*)); //把三角形颜色送入shader
//数字0对应vertex shader中的 location = 1
glEnableVertexAttribArray();
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, , (void*)); //draw call
glDrawArrays(GL_TRIANGLES, , * ); //一定要在draw call之后关闭
glDisableVertexAttribArray();
glDisableVertexAttribArray(); //切换前后缓存,将渲染好的显示出来
glfwSwapBuffers(window);
glfwPollEvents();
}

main

vertex shader:

 #version  core
layout(location = ) in vec3 vertexPosition_modelspace;
layout(location = ) in vec3 vertexColor; uniform mat4 mvp;
out vec3 fragmentColor; void main() {
gl_Position = mvp * vec4(vertexPosition_modelspace, );
fragmentColor = vertexColor;
}

fragment shader:

 #version  core

 out vec3 color;
in vec3 fragmentColor; void main() {
color = fragmentColor;
}

至于这两个shader干嘛的。。。我先学习学习

OpenGL 学习笔记 01 环境配置的更多相关文章

  1. Qt5学习笔记&lpar;1&rpar;-环境配置&lpar;win&plus;64bit&plus;VS2013&rpar;

    Qt5学习笔记(1)-环境配置 工欲善其事必先-不装-所以装软件 久不露面,赶紧打下酱油. 下载 地址:http://download.qt.io/ 这个小网页就可以下载到跟Qt有关的几乎所有大部分东 ...

  2. 【lua学习笔记】——环境配置

    1 开发平台 windows7 64位 2 下载链接 http://www.lua.org/download.html 3 安装完成-环境配置 4  运行 WIN+R 运行 cmd 运行lua,显示配 ...

  3. 学习笔记-ionic3 环境配置搭建到打包

    折腾了两周总算理清楚了,参考的链接如下: https://blog.csdn.net/zeternityyt/article/details/79655150  环境配置 https://segmen ...

  4. Maven 学习笔记——Maven环境配置(1)

    在学习Selenium的过程中,接触到了Maven(项目管理工具),不至于学一路忘一路,左耳朵进右耳多出,还是决定边学边记录,毕竟听的不如 看的,看的不如写的吗.首先学一样东西,肯定得明确学的是什么, ...

  5. WP8 学习笔记&lpar;001&lowbar;环境配置&rpar;

    Step 1  WP8 的开发要求64位操作系统,Windows 8及以上版本,需要激活版,建议网上买一个注册码.详见安装双系统. Step 2 安装好系统并已经激活之后,需要安装Windows Ph ...

  6. tensorflow学习笔记&lpar;1&rpar;-环境配置

    配置环境anaconda3+windows10+pycharm+python==3.5.2+tensorflow==1.1.4+cuda10.0+cudnn7 https://www.anaconda ...

  7. 【OpenGL 学习笔记01】HelloWorld演示样例

    <<OpenGL Programming Guide>>这本书是看了忘,忘了又看,赶脚还是把笔记做一做心里比較踏实,哈哈. 我的主题是,好记性不如烂笔头. ========== ...

  8. 学习笔记----php环境配置

    Php开发环境自定义搭建 (万事开头难) 第一步:Apache安装(httpd-2.4.37-win64-VC15.zip) 下载已编译apache安装包:Apachelounge官方下载地址:htt ...

  9. 《基于Nginx的中间件架构》学习笔记---1&period;环境配置

    一.环境调试确认 (四项确认) 1.确认系统网络 ping www.baidu.com 2.确认yum可用 yum list|grep gcc 3.确认关闭iptables规则 iptables -L ...

随机推荐

  1. rename

    重命名文件名: # rename hosts.conf.正式配值文件 hosts.conf.正式配置文件 hosts.conf.正式配值文件 [root@monitor- vhost]# ls hos ...

  2. 关于Android程序设计—有道词典demo转移至coding的公告

    有道词典的demo以及解析已转移至Coding https://coding.net/u/monsterLin/p/WebView_YouDao/git

  3. JavaScript设计模式 - 单例模式

    单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 一.实现一个标准的单例模式,用一个变量来标志当前是否已经为某个类创建过对象, 如果是,则在下一次获取该对象实例时,直接返回之前创建的对 ...

  4. 【转】Linux写时拷贝技术&lpar;copy-on-write&rpar;

    http://www.cnblogs.com/biyeymyhjob/archive/2012/07/20/2601655.html 源于网上资料 COW技术初窥: 在Linux程序中,fork()会 ...

  5. Android窗口管理服务WindowManagerService切换Activity窗口(App Transition)的过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8596449 在Android系统中,同一时刻只 ...

  6. javascript高级知识点——闭包

    代码信息来自于http://ejohn.org/apps/learn/. 先给出一个权威的定义,函数对象可以通过作用域相互关联起来,函数体内的变量可以保存在函数的作用域内,这种特性称为闭包. 在闭包内 ...

  7. (转)迎接 Entity Framework 7

    对实体框架的下一版本的开发正在顺利进行中.我在 2014 年度北美 TechEd 上第一次了解 EF 团队的工作内容,当时项目经理 Rowan Miller 讨论了 Entity Framework ...

  8. 锐动视频SDK在金融业务加密双录管理系统通用解决方案

    为了更好地保障消费者的合法权益,银监会和保监会提出了要求,在银行.保险从业人员销售理财产品或代理其他机构销售产品时,同期进行录音录像,确保销售人员按程序.按规定介绍产品,以便购买者更清楚地了解产品的性 ...

  9. 剑指Offer-按之字形顺序打印二叉树

    package Tree; import java.util.ArrayList; import java.util.LinkedList; import java.util.Queue; /** * ...

  10. property装饰器

    # 需要了解的property的用法 class People: def __init__(self,name): self.__name=name @property def name(self): ...