OpenGL 学习笔记 01
Posted prop_jeff
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenGL 学习笔记 01相关的知识,希望对你有一定的参考价值。
抱歉,本文写的很乱,建议跳过代码部分。
1 #include <cstdio> 2 #include <cstdlib> 3 4 #include <GL/glew.h> 5 6 #include <GLFW/glfw3.h> 7 8 #include <glm/glm.hpp> 9 #include <glm/gtc/matrix_transform.hpp> 10 using namespace glm; 11 using namespace std; 12 13 #include <shader.hpp> 14 #include <shader.cpp> 15 16 static const GLfloat g_vertex_buffer_data[] = { 17 -1.0f,-1.0f,-1.0f, // triangle 1 : begin 18 -1.0f,-1.0f, 1.0f, 19 -1.0f, 1.0f, 1.0f, // triangle 1 : end 20 1.0f, 1.0f,-1.0f, // triangle 2 : begin 21 -1.0f,-1.0f,-1.0f, 22 -1.0f, 1.0f,-1.0f, // triangle 2 : end 23 1.0f,-1.0f, 1.0f, 24 -1.0f,-1.0f,-1.0f, 25 1.0f,-1.0f,-1.0f, 26 1.0f, 1.0f,-1.0f, 27 1.0f,-1.0f,-1.0f, 28 -1.0f,-1.0f,-1.0f, 29 -1.0f,-1.0f,-1.0f, 30 -1.0f, 1.0f, 1.0f, 31 -1.0f, 1.0f,-1.0f, 32 1.0f,-1.0f, 1.0f, 33 -1.0f,-1.0f, 1.0f, 34 -1.0f,-1.0f,-1.0f, 35 -1.0f, 1.0f, 1.0f, 36 -1.0f,-1.0f, 1.0f, 37 1.0f,-1.0f, 1.0f, 38 1.0f, 1.0f, 1.0f, 39 1.0f,-1.0f,-1.0f, 40 1.0f, 1.0f,-1.0f, 41 1.0f,-1.0f,-1.0f, 42 1.0f, 1.0f, 1.0f, 43 1.0f,-1.0f, 1.0f, 44 1.0f, 1.0f, 1.0f, 45 1.0f, 1.0f,-1.0f, 46 -1.0f, 1.0f,-1.0f, 47 1.0f, 1.0f, 1.0f, 48 -1.0f, 1.0f,-1.0f, 49 -1.0f, 1.0f, 1.0f, 50 1.0f, 1.0f, 1.0f, 51 -1.0f, 1.0f, 1.0f, 52 1.0f,-1.0f, 1.0f 53 }; 54 55 //每个顶点一个颜色 56 static const GLfloat g_color_buffer_data[] = { 57 0.583f, 0.771f, 0.014f, 58 0.609f, 0.115f, 0.436f, 59 0.327f, 0.483f, 0.844f, 60 0.822f, 0.569f, 0.201f, 61 0.435f, 0.602f, 0.223f, 62 0.310f, 0.747f, 0.185f, 63 0.597f, 0.770f, 0.761f, 64 0.559f, 0.436f, 0.730f, 65 0.359f, 0.583f, 0.152f, 66 0.483f, 0.596f, 0.789f, 67 0.559f, 0.861f, 0.639f, 68 0.195f, 0.548f, 0.859f, 69 0.014f, 0.184f, 0.576f, 70 0.771f, 0.328f, 0.970f, 71 0.406f, 0.615f, 0.116f, 72 0.676f, 0.977f, 0.133f, 73 0.971f, 0.572f, 0.833f, 74 0.140f, 0.616f, 0.489f, 75 0.997f, 0.513f, 0.064f, 76 0.945f, 0.719f, 0.592f, 77 0.543f, 0.021f, 0.978f, 78 0.279f, 0.317f, 0.505f, 79 0.167f, 0.620f, 0.077f, 80 0.347f, 0.857f, 0.137f, 81 0.055f, 0.953f, 0.042f, 82 0.714f, 0.505f, 0.345f, 83 0.783f, 0.290f, 0.734f, 84 0.722f, 0.645f, 0.174f, 85 0.302f, 0.455f, 0.848f, 86 0.225f, 0.587f, 0.040f, 87 0.517f, 0.713f, 0.338f, 88 0.053f, 0.959f, 0.120f, 89 0.393f, 0.621f, 0.362f, 90 0.673f, 0.211f, 0.457f, 91 0.820f, 0.883f, 0.371f, 92 0.982f, 0.099f, 0.879f 93 }; 94 95 int main() { 96 if(!glfwInit()) { 97 fprintf(stderr, "Failed To init OpenGL\\n"); 98 } 99 100 // We want OpenGL 3.3 101 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 102 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 103 // To make MacOS happy; should not be needed 104 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 105 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don\'t want the old OpenGL 106 107 // Open a window and create its OpenGL context 108 // (In the accompanying source code, this variable is global) 109 GLFWwindow* window; 110 window = glfwCreateWindow(800, 600, "Tutorial 01", NULL, NULL); 111 if( window == NULL ){ 112 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" ); 113 glfwTerminate(); 114 return -1; 115 } 116 glfwMakeContextCurrent(window); // Initialize GLEW 117 glewExperimental = true; // Needed in core profile 118 119 //z-buffer 120 glEnable(GL_DEPTH_TEST); 121 glDepthFunc(GL_LEFT); 122 123 if (glewInit() != GLEW_OK) { 124 fprintf(stderr, "Failed to initialize GLEW\\n"); 125 return -1; 126 } 127 128 //背景颜色 129 glClearColor(0.0f, 0.0f, 0.4f, 0.0f); 130 131 //shader 132 GLuint programID = LoadShaders( "/Users/jeff/IDEProjects/xcode_projects/openGL/openGL/vertex.shader", "/Users/jeff/IDEProjects/xcode_projects/openGL/openGL/fragment.shader" ); 133 134 GLuint VertexArrayID; 135 glGenVertexArrays(1, &VertexArrayID); 136 glBindVertexArray(VertexArrayID); 137 138 //vertex buffer 139 GLuint vertexbuffer; 140 glGenBuffers(1, &vertexbuffer); 141 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 142 glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); 143 144 //color buffer 145 GLuint colorbuffer; 146 glGenBuffers(1, &colorbuffer); 147 glBindBuffer(GL_ARRAY_BUFFER, colorbuffer); 148 glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW); 149 150 mat4 Projection = perspective(radians(70.0f), (float)4/3, 0.1f, 1000.f); 151 152 mat4 View = lookAt(vec3(3, 4, -5), vec3(0,0,0), vec3(0,1,0)); 153 154 mat4 Model = mat4(1.0f); 155 156 //模型到投影转换 157 mat4 mvp = Projection * View * Model; 158 159 GLuint MatrixID = glGetUniformLocation(programID, "mvp"); 160 161 while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && !glfwWindowShouldClose(window)) { 162 //每次开始时清空画布 163 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 164 165 //使用shader 166 glUseProgram(programID); 167 168 //把变换矩阵送进shader 169 glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp[0][0]); 170 171 //画三角形 172 glEnableVertexAttribArray(0); 173 glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 174 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); 175 176 //三角形颜色 177 glEnableVertexAttribArray(1); 178 glBindBuffer(GL_ARRAY_BUFFER, colorbuffer); 179 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); 180 181 //draw call 182 glDrawArrays(GL_TRIANGLES, 0, 12 * 3); 183 184 glDisableVertexAttribArray(0); 185 glDisableVertexAttribArray(1); 186 187 glfwSwapBuffers(window); 188 glfwPollEvents(); 189 } 190 glfwTerminate(); 191 return 0; 192 }
首先是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
1 #include <stdio.h> 2 #include <string> 3 #include <vector> 4 #include <iostream> 5 #include <fstream> 6 #include <algorithm> 7 using namespace std; 8 9 #include <stdlib.h> 10 #include <string.h> 11 12 #include <GL/glew.h> 13 14 #include "shader.hpp" 15 16 GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){ 17 18 // Create the shaders 19 GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); 20 GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); 21 22 // Read the Vertex Shader code from the file 23 std::string VertexShaderCode; 24 std::ifstream VertexShaderStream(vertex_file_path, std::ios::in); 25 if(VertexShaderStream.is_open()){ 26 std::string Line = ""; 27 while(getline(VertexShaderStream, Line)) 28 VertexShaderCode += "\\n" + Line; 29 VertexShaderStream.close(); 30 }else{ 31 printf("Impossible to open %s. Are you in the right directory ? Don\'t forget to read the FAQ !\\n", vertex_file_path); 32 getchar(); 33 return 0; 34 } 35 36 // Read the Fragment Shader code from the file 37 std::string FragmentShaderCode; 38 std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in); 39 if(FragmentShaderStream.is_open()){ 40 std::string Line = ""; 41 while(getline(FragmentShaderStream, Line)) 42 FragmentShaderCode += "\\n" + Line; 43 FragmentShaderStream.close(); 44 } 45 46 GLint Result = GL_FALSE; 47 int InfoLogLength; 48 49 50 // Compile Vertex Shader 51 printf("Compiling shader : %s\\n", vertex_file_path); 52 char const * VertexSourcePointer = VertexShaderCode.c_str(); 53 glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL); 54 glCompileShader(VertexShaderID); 55 56 // Check Vertex Shader 57 glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); 58 glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); 59 if ( InfoLogLength > 0 ){ 60 std::vector<char> VertexShaderErrorMessage(InfoLogLength+1); 61 glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); 62 printf("%s\\n", &VertexShaderErrorMessage[0]); 63 } 64 65 66 67 // Compile Fragment Shader 68 printf("Compiling shader : %s\\n", fragment_file_path); 69 char const * FragmentSourcePointer = FragmentShaderCode.c_str(); 70 glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL); 71 glCompileShader(FragmentShaderID); 72 73 // Check Fragment Shader 74 glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); 75 glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); 76 if ( InfoLogLength > 0 ){ 77 std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1); 78 glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); 79 printf("%s\\n", &FragmentShaderErrorMessage[0]); 80 } 81 82 83 84 // Link the program 85 printf("Linking program\\n"); 86 GLuint ProgramID = glCreateProgram(); 87 glAttachShader(ProgramID, VertexShaderID); 88 glAttachShader(ProgramID, FragmentShaderID); 89 glLinkProgram(ProgramID); 90 91 // Check the program 92 glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); 93 glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); 94 if ( InfoLogLength > 0 ){ 95 std::vector<char> ProgramErrorMessage(InfoLogLength+1); 96 glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); 97 printf("%s\\n", &ProgramErrorMessage[0]); 98 } 99 100 101 glDetachShader(ProgramID, VertexShaderID); 102 glDetachShader(ProgramID, FragmentShaderID); 103 104 glDeleteShader(VertexShaderID); 105 glDeleteShader(FragmentShaderID); 106 107 return ProgramID; 108 }
别忘了#include <shader.hpp> 并把 shader.cpp 添加到项目的Compile Sources里
g_vertex_buffer_data 和 g_color_buffer_data 储存正方形的顶点位置信息和颜色信息
main 函数里:
1 if(!glfwInit()) { 2 fprintf(stderr, "Failed To init OpenGL\\n"); 3 } 4 5 // We want OpenGL 3.3 6 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 7 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 8 // To make MacOS happy; should not be needed 9 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 10 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don\'t want the old OpenGL 11 12 // Open a window and create its OpenGL context 13 // (In the accompanying source code, this variable is global) 14 GLFWwindow* window; 15 window = glfwCreateWindow(WIDTH, HEIGHT, "OpenGL Window", NULL, NULL); 16 if( window == NULL ){ 17 fprintf( stderr, "Failed to open GLFW window. If you have an In以上是关于OpenGL 学习笔记 01的主要内容,如果未能解决你的问题,请参考以下文章