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


以下教程仅适用于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的方式找到安装路径

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

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

#include <GLFW/glfw3.h>

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

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

链接后应该如下

点击那个“加号”添加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学习笔记(1)-环境配置(win+64bit+VS2013)

    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 学习笔记(001_环境配置)

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

  6. tensorflow学习笔记(1)-环境配置

    配置环境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.环境配置

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

随机推荐

  1. vs 2010 中类文文件模板的修改

    类模板 文件的修改,以前也修改过,这次有个同事问我,搞了有一会才搞定,这里还是记录分享下. 如果想在每次创建文件时,自动生成文档注释(注意是自动生成文档注释而不是帮助文档),如下面的代码,需要设置VS ...

  2. WPF_View中控件使用单例ViewModel

    一个View里面单独的一个控件需要一个ViewModel   这个ViewModel类 可以做成单例 public class VMTest:Ad.Core.ViewModel.ViewModel { ...

  3. 2. npm 的使用

    NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种: 允许用户从NPM服务器下载别人编写的第三方包到本地使用. 允许用户从NPM服务器下载并 ...

  4. C#中 导入和导出Excel的方法

    using System.Data; using System.Data.OleDb; /// <summary> /// Excel转为DataTable /// </summar ...

  5. ActiveReports 报表应用教程 (7)---交叉报表及数据透视图实现方案

    在 ActiveReports 中可以通过矩阵控件非常方便的实现交叉报表,同时还可以设置数据的分组.排序.过滤.小计.合计等操作,可以满足您报表的智能数据分析等需求.在矩阵控件中组的行数和列数由每个行 ...

  6. 【NOIP训练】【数论】超级计算机

    题目描述有以下几个问题:1 给定正整数  求方程  的最小非负整数解.2 给定正整数 求方程 的最小非负整数解.3 给定正整数 求方程  在模  意义下解的数量.4 给定正整数 求   的值.其中   ...

  7. iOS UITableview

    1. UITableView //去除tableviews的点击效果 cell.selectionStyle = UITableViewCellSelectionStyleNone;    //隐藏t ...

  8. miniSipServer简单而不简单,轻松落地,实现电脑对固话、手机通讯

    最近沉迷于SIP通讯,网内通讯全免费,落地也就几分钱,而且无漫游全国拨打,想想真是心动呢,只要有网落就ok!. 对于sipserver,现在的市场上软件很多,免费的.收费的应有尽有,这里不一一例举.综 ...

  9. 解决SharePoint 2013 designer workflow 在发布的报错“负载平衡没有设置”The workflow files were saved but cannot be run.

    原因是app management service没有设置好,在管理中心把他删掉,重新建一个就可以了 Provision App Management Service In SharePoint 20 ...

  10. How to Build Office Developer Tools Projects with TFS Team Build 2012

    Introduction Microsoft Visual Studio 2012 provides a new set of tools for developing apps for Office ...