花一天的时间初探了OpenGL。最终的目标是完全理解OpenGL操作GPU的原理,以及shader编程的熟练运用。并最终做出一个3d物品的的视角,以及光照等的高级效果。
// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>
using namespace std;
int main()
{
glewExperimental = GL_TRUE;
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
glfwWindowHint(GLFW_CENTER_CURSOR, GL_TRUE);
GLFWmonitor* currMonitor = glfwGetPrimaryMonitor();
const GLFWvidmode *mode = glfwGetVideoMode(currMonitor);
GLFWwindow* window = glfwCreateWindow(mode->width, mode->height, "LearnOpenGL2",nullptr, nullptr);
glfwMakeContextCurrent(window);
glewInit();
int width;
int height;
glfwGetFramebufferSize(window, &width, &height);
std::cout << width << std::endl;
std::cout << height << std::endl;
// GLFWwindow* window2 = glfwCreateWindow(mode->width, mode->height, "LearnOpenGL2", nullptr, nullptr);
// glfwMakeContextCurrent(window2);
if (window == nullptr)
{
//cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return -1;
}
const GLubyte* name = glGetString(GL_VENDOR); //返回负责当前OpenGL实现厂商的名字
const GLubyte* biaoshifu = glGetString(GL_RENDERER); //返回一个渲染器标识符,通常是个硬件平台
const GLubyte* OpenGLVersion = glGetString(GL_VERSION); //返回当前OpenGL实现的版本号
const GLubyte* gluVersion = glGetString(GLU_VERSION); //返回当前GLU工具库版本
printf("OpenGL实现厂商的名字:%s\n", name);
printf("渲染器标识符:%s\n", biaoshifu);
printf("OpenGL实现的版本号:%s\n", OpenGLVersion);
int x = 100;
int y = 200;
//窗口大小发生改变时的回调
glfwSetWindowSizeCallback(window, (GLFWwindowsizefun)[](GLFWwindow* window, int width, int height) { std::cout << width << std::endl;
std::cout << height << std::endl;
});
//设置关闭回调
glfwSetKeyCallback(window, [](GLFWwindow * window,int key,int scancode, int action, int mode) {
if (key == 299 && action == GLFW_PRESS) {
glfwSetWindowShouldClose(window, GL_TRUE);
}
});
std::cout << mode->blueBits << std::endl;
std::cout << mode->greenBits << std::endl;
std::cout << mode->redBits << std::endl;
//-----------------------------------------------------------------------顶点着色器
GLuint vertexShader; //创建顶点着色器对象变量
//顶点着色器源代码
static const char *vertextShaderSrc =
"#version 330\n"
"layout (location = 0) in vec3 position;\n"
"layout (location = 1) in vec3 vertex_colour;\n"
"out vec3 colour;\n"
"void main()\n"
"{\n"
"colour = vertex_colour;\n"
"gl_Position = vec4(position.x,position.y,position.z,1.0);\n"
"}\n";
vertexShader = glCreateShader(GL_VERTEX_SHADER);//创建并返回一个shader对象
glShaderSource(vertexShader,1,&vertextShaderSrc,NULL );//传入顶点着色器源代码与对象
glCompileShader(vertexShader);
//获取编译状态
GLint success;
GLchar infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
cout << "顶点着色器编译错误:" << infoLog << endl;
}
else {
cout << "顶点着色器编译成功" << endl;
}
//------------------------------------------------------------------end
//------------------------------------------------------------------片段着色器
GLuint fragmentShader;
static const char *fragmentShaderSrc =
"#version 330\n"
"in vec3 colour;\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(colour,1.0f);\n"
"}\n";
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSrc, NULL);
glCompileShader(fragmentShader);
GLint success2;
GLchar infoLogs2[512];
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success2);
if (!success2) {
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLogs2);
cout << "片段着色器编译错误:" << infoLogs2 << endl;
}
else
{
cout << "片段着色器编译成功" << endl;
}
//-------------------------------------------------------------------end
//-------------------------------------------------------------------着色器程序
GLuint shaderProgram;
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
//着色器编译成功后就可以将顶点和片段着色器对象删除
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
GLint success3;
GLchar infoLogs3[512];
glGetProgramiv(shaderProgram, GL_COMPILE_STATUS, &success3);
if (!success3) {
glGetProgramInfoLog(shaderProgram,512,NULL,infoLogs3);
cout << "着色器程序编译错误:" << infoLogs3 << endl;
}
else
{
cout << "着色器程序编译成功" << endl;
}
//-------------------------------------------------------------------end
//--------------------------------------------------------------------链接顶点属性
GLfloat vertex[] = {
-0.5f,-0.5f,0.0f,
0.5f,-0.5f,0.0f,
0.0f,0.5f,0.0f,
};
GLfloat vertex2[] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f,
};
GLfloat colours[] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f,
};
GLuint VAO;//顶点数组对象
glGenVertexArrays(1,&VAO);
glBindVertexArray(VAO);//后面的VBO操作会被记录到该顶点数组对象,后面能直接用
GLuint VBO;
glGenBuffers(1, &VBO);//创建顶点缓冲对象(空),创建显存空间
glBindBuffer(GL_ARRAY_BUFFER, VBO);//缓冲对象绑定到缓冲区,一个缓冲区只能有一个缓冲对象, 不然后面写入缓冲区不知道写入哪个对象,但是一个缓冲对象可以绑定多个缓冲区
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);//往缓冲区中的对象写入数据c
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);//设置顶点属性指针,使用的是此时绑定到GL_ARRAY_BUFFER的VBO顶点缓冲对象
glEnableVertexAttribArray(0);//启用顶点属性,参数是顶点属性的位置
GLuint VBO2;
glGenBuffers(1, &VBO2);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(colours), colours, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(1);
glBindVertexArray(0);
GLuint VAO2;
glGenVertexArrays(1,&VAO2);
glBindVertexArray(VAO2);
GLuint VBO3;
glGenBuffers(1, &VBO3);
glBindBuffer(GL_ARRAY_BUFFER, VBO3);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex2), vertex2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);//启用顶点属性,参数是顶点属性的位置 glBindVertexArray(0);
GLuint VBO4;
glGenBuffers(1, &VBO4);
glBindBuffer(GL_ARRAY_BUFFER, VBO4);
glBufferData(GL_ARRAY_BUFFER,sizeof(colours), colours, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(1);
glBindVertexArray(0);
// glEnable(GL_CULL_FACE);//剔除脸
// glCullFace(GL_BACK);//剔除背面
// glFrontFace(GL_CW); // GL_CCW为逆时针方向
//--------------------------------------------------------------------end
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgram);//使用之前编译好的着色器程序
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glBindVertexArray(VAO2);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
这是效果。