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


以下教程仅适用于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. Winform里面的缓存使用

    缓存在很多情况下需要用到,合理利用缓存可以一方面可以提高程序的响应速度,同时可以减少对特定资源访问的压力.本文主要针对自己在Winform方面的缓存使用做一个引导性的介绍,希望大家能够从中了解一些缓存 ...

  2. 【C#进阶系列】04 类型基础

    关于System.Object 所有类型都从System.Object派生而来. System.Object的公共方法中ToString()一般是返回对象的类型的全名,只有Int32这些类型将其重写后 ...

  3. 返璞归真 asp.net mvc (13) - asp.net mvc 5.0 新特性

    [索引页][源码下载] 返璞归真 asp.net mvc (13) - asp.net mvc 5.0 新特性 作者:webabcd 介绍asp.net mvc 之 asp.net mvc 5.0 新 ...

  4. treap树---营业额统计

    台州学院  2924 描述 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况.Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额 ...

  5. ahjesus用forever管理nodejs服务

    全局安装forever npm install -g forever 查看帮助 forever -h 查看安装位置 whereis forever 编写自己的sh文件 forever -p web文件 ...

  6. [小北De编程手记] : Lesson 01 - Selenium For C# 之 环境搭建

    在我看来一个自动化测试平台的构建,是一种很好的了解开发语言,单元测试框架,自动化测试驱动,设计模式等等等的途径.因此,在下选择了自动化测试的这个话题来和大家分享一下本人关于软件开发和自动化测试的认识. ...

  7. Android 手机卫士14--Widget窗口小部件AppWidgetProvider

    1.AndroidManifest.xml根据窗体小部件广播接受者关键字android.appwidget.action.APPWIDGET_UPDATE 搜索android:resource=&qu ...

  8. 【译】Dependency Injection with Autofac

    先说下为什么翻译这篇文章,既定的方向是架构,然后为了学习架构就去学习一些架构模式.设计思想. 突然有一天发现依赖注入这种技能.为了使得架构可测试.易维护.可扩展,需要架构设计为松耦合类型,简单的说也就 ...

  9. 本地Git服务器的搭建及使用

    本地Git服务器的搭建及使用 Git本地服务器环境搭建 搭建好的本地git服务器的局域网ip是192.168.1.188,用户名是RSCSVN 教程链接:http://blog.csdn.net/cc ...

  10. Step by step configuration of Outgoing Emails from SharePoint to Microsoft Online

    First of all your SharePoint server should be added to Microsoft online safe sender list, so that Sh ...