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


以下教程仅适用于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. 配置了<mvc:resources> 导致以前的controller 无法访问。

    解决方案: <mvc:annotation-driven/>

  2. 《JAVA与模式》之组合模式

    定义(GoF<设计模式>): 将对象组合成树形结构以表示“部分整体”的层次结构.组合模式使得用户对单个对象和使用具有一致性. 及角色: 1.Component 是组合中的对象声明接口,在适 ...

  3. jquery 下拉选择框/复选框常用操作

    通常 1.我们需要获取select中选中的值,可以使用: $("#selectID").find("option:selected").val();  --一般 ...

  4. 西邮Linux兴趣小组2016免试题

    4.28的宣讲会圆满结束(就在写这段话之前不久),对于西邮Linux兴趣小组这一次纳新,身为局外人表示:还是有历史,还是会玩,还是厉害哈. 华丽的分割线里面是自己之前的攻关战略,最后补充了宣讲会上学长 ...

  5. Dom4j 锁竞争性能低下解决

    在最近的项目中使用 Dom4j 解析 xml 发现性能低下,有锁竞争的情况,解决如下: SAXParserFactory factory = new org.apache.xerces.jaxp.SA ...

  6. java微信开发

    所谓的微信开发就是在微信开发模式之下,对微信进行公众号和企业号的扩展开发.     如果要让你的微信公众号有更多的功能,比如菜单支持,自动的信息服务,查询,消息推送等,就必须开启微信的开发模式.进入微 ...

  7. oGrid 初探

    oGrid 是个还蛮有趣的 pure JavaScript grid 控件 code 并不多而且是纯 JavaScript 写成,一条小龙觉得还算蛮好理解,不像其他几乎都是用 Jquery 为 bas ...

  8. Egret Engine(白鹭引擎)介绍及windows下安装

    Egret Engine简要介绍----- Egret Engine(白鹭引擎)[Egret Engine官网:http://www.egret-labs.org/]是一款使用TypeScript语言 ...

  9. ABAP Performance Examples

    *modifying a set of lines directly(批量修改内表数据) *使用"LOOP ... ASSIGNING ..."可以直接修改内表中的数据,而不需要先 ...

  10. ExtJs中xtype与组件类的对应表

    from:http://blog.163.com/jx_dream/blog/static/117056627201223091021410/ 核心提示:我们在使用 ExtJs 创建组件时最容易理解的 ...