#创建三角形
#include <iostream>
//GLEW
#define GLEW_STATIC
#include <GL/glew.h>
//GLFW
#include <GLFW/glfw3.h>
using namespace std;
//创建一个窗口,定义窗口的宽高常亮
const GLint WIDTH = 800, HEIGHT = 600;
//着色器语言,一长串字符串
//顶点着色器,小程序运行在GPU里
//着色器语言用的是330版本
const GLchar *vertexShaderSource = "#version 330 core\n"
"layout(location=0) in vec3 position;\n"//location is 位置,in是输入,输入3维向量vec3,起名叫position
"void main()\n"
"{\n"
"gl_Position=vec4(position.x,position.y,position.z,1.0f);\n"//glposition是着色器内部保留的变量不需声明,vec4是四维向量,齐次坐标系(x,y,z,1),最后的1必须是1
//最后不是1,需做额外的处理
"}";
//片源着色器
//与顶点着色器版本一直
const GLchar *fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"//输出Out一个4维颜色变量
"void main()\n"
"{\n"
"color=vec4(1.0f,0.5f,0.2f,1.0f);\n"
"}";
int main()
{
//初始化GLFW
glfwInit();
//设置窗口
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//设置OpenGL主版本3.3之后的版本都兼容
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//设置OPenGL此版本
//使用OPENGL核心模式
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//core profile即glew
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT,GL_TRUE);mac系统
//不可改变窗口大小
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
//自动填充,tab跳下一个参数
GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "B17040506", nullptr, nullptr);//生成窗口,窗口大小,窗口名,是否设置全屏,基本不用
//分辨率即像素的个数,操作系统显示一个像素用更多的像素内存,需要知道真缓存大小(在显卡里),真缓存包含颜色缓存Colar,深度缓存
//Depth,模板缓存(画阴影)
int screenWidth, screenHeight;
glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
//判断窗口是否新建成功
if (nullptr == window)
{
cout << "fail" << endl;
glfwTerminate();//关闭
return -1;
}
//指定当前窗口
glfwMakeContextCurrent(window);
//启动OPENGL
glewExperimental = GL_TRUE;
//检查是否启动成功
if (GLEW_OK != glewInit())
{
cout << "fail" << endl;
glfwTerminate();
return -1;
}
//使用OPENGL,viewport是将真缓存显存中一致的数据映射到屏幕上的过程
glViewport(0, 0, screenWidth, screenHeight);
//开始画图,屏幕一秒钟闪许多次(60HZ),要刷新很多次
//欧洲标准一秒钟刷新30帧,美25帧
//import and compile shader,编译
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);//创建顶点着色器对象
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);//传递字符串
glCompileShader(vertexShader);//编译,检查语法错误
GLint success;//整型代表是否编译成功
GLchar infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);//i代表整型,v是否正确,获取是否成功
//失败
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);//512代表最多获取的反馈
cout << "ERROR:SHADER::VERTEX<<COMPILATION_FAILED\n" << infoLog << endl;//顶点着色器的错误
}
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);//创建片段着色器对象
glShaderSource(fragmentShader, 1, &fragmentShaderSource,NULL);//传递字符串
glCompileShader(fragmentShader);//编译,检查语法错误
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);//i代表整型,v是否正确,获取是否成功
//失败
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);//512代表最多获取的反馈
cout << "ERROR:SHADER::FRAGMENT<<COMPILATION_FAILED\n" << infoLog << endl;//片段着色器的错误
}
//链接
GLuint shaderProgram = glCreateProgram();//创建一个程序对象
glAttachShader(shaderProgram, vertexShader);//将之前编译的着色器附加到程序对象上
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);//用glLinkProgram链接他们
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
//检验链接着色器程序是否成功
if (!success)
{
glGetProgramInfoLog(shaderProgram, 512, NULL,infoLog);
cout << "ERROR_SHADER::PROGRAM_LINKING_FAILED\n" << infoLog << endl;
}//渲染管线完成
//删除着色器对象
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
//顶点信息,-1~1,
GLfloat vertices[] =
{
-0.5f,-0.5f,0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f//没有逗号
};
//数据从内存进入cache,从cache进入显卡,对着色器程序进行解释映射到变量上
GLuint VAO, VBO;//创建两个对象,VAO解释VVBO,VAO与VBO一一敌营
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);//将VAO与VBO绑定
glBindBuffer(GL_ARRAY_BUFFER, VBO);//告诉系统VBO存储GL_ARRAY_BUFFER类型的数据(顶点信息位置,颜色)
//讲所有数据存入显存
//sizeof是指需要多大的显卡存储,第一个指传入顶点信息,最后一个指存入显卡内存里读取快但不能修改数据(不需快速写入)的地方
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//解析顶点信息VAO,一下是GlvertexattribPointer六个参数分别代表的意思
//顶点位置值location设为0,顶点position变量是一个 三维数组vec3,顶点position参数类型是浮点
//数据是否被标准化,每隔三个浮点数就获得一个poosition,位置数据在缓冲中起始位置的偏移量
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat),(GLvoid*)0);
glEnableVertexAttribArray(0);
//解除绑定,即绑定到0上
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while (!glfwWindowShouldClose(window))//点红茶关闭窗口,值为真;不点一直执行这部分循环
{
//满足glfw
glfwPollEvents();//监听鼠标键盘,调出来与键盘啊进行交互
//人眼对绿色不敏感
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//用颜色进行清除屏幕,RGBA,0-256个层次,用浮点数进行表示,A是指透明度0指全透明
glClear(GL_COLOR_BUFFER_BIT);//
glUseProgram(shaderProgram);//使用shaderprogram渲染管线
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);//
glBindVertexArray(0);
glfwSwapBuffers(window);//真缓存在显卡里,显卡将真缓存映射到屏幕上需要时间,在这段时间里,同时开启另一个真缓存,即双缓存模式
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return 0;
}