使用WSAD控制,运行效果和代码如下:
#include<glad/glad.h>
#include<GLFW/glfw3.h>
#include<iostream>
using namespace std;
//顶点着色器
const char *vertexShaderSource =
"#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec3 aColor;\n"
"out vec3 ourColor;\n"
"uniform vec2 pos;\n"
"void main(){\n"
" gl_Position = vec4(aPos.x+pos.x,aPos.y+pos.y,aPos.z,1.0);\n"
" ourColor=aColor;\n"
"\n}";
//片段着色器
const char *fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"in vec3 ourColor;\n"
"void main(){\n"
" FragColor = vec4(ourColor,0.8f);"
"}\n";
//顶点和颜色数据
float vertices[] = {
// 位置 // 颜色
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 右下
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 左下
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, // 顶部
0.5f, -0.5f, 0.0f, 0.5f, 0.5f, 0.5f // 顶部
};
//索引
unsigned int indices[] = { // 注意索引从0开始!
0, 1, 3, // 第一个三角形
1, 2, 3 // 第二个三角形
};
//矩形平面坐标
float x=0,y=0,speed=0.02f;
//编译着色器
int CompileShader(const char* source,int type)
{
int shader=glCreateShader(type);
glShaderSource(shader,1,&source,nullptr);
glCompileShader(shader);
int ret=0;
char log[512]={0};
glGetShaderiv(shader,GL_COMPILE_STATUS,&ret);
if(!ret){
glGetShaderInfoLog(shader,512,nullptr,log);
cout<<"着色器编译失败:"<<log<<endl;
return 0;
}
return shader;
}
//窗口大小变动的回调函数
void framebuffer_size_callback(GLFWwindow* window,int width,int height)
{
glViewport(0,0,width,height);
}
//如果ESC键按下,则关闭窗口
void processInput(GLFWwindow *window)
{
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS){
glfwSetWindowShouldClose(window, true);
}
if(glfwGetKey(window,GLFW_KEY_D) == GLFW_PRESS){
x>=0.5f ? x=0.5f : x+=speed;
}
if(glfwGetKey(window,GLFW_KEY_A) == GLFW_PRESS){
x<=-0.5f ? x=-0.5f : x-=speed;
}
if(glfwGetKey(window,GLFW_KEY_W) == GLFW_PRESS){
y>=0.5f ? y=0.5f : y+=speed;
}
if(glfwGetKey(window,GLFW_KEY_S) == GLFW_PRESS){
y<=-0.5f ? y = -0.5f : y-=speed;
}
}
int main()
{
glfwInit();//初始化
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3); //主版本号
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);//次版本号
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);//采用核心模式
//参数:窗口宽,窗口高,窗口标题,暂时忽略,暂时忽略
GLFWwindow* window = glfwCreateWindow(800,600,"这是窗口标题",nullptr,nullptr);
if(!window)
{
cout<<"创建窗口失败!"<<endl;
glfwTerminate();//释放内存
return -1;
}
glfwMakeContextCurrent(window);
//初始化GLAD,GLAD用于管理函数指针
if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
cout<<"初始化GLAD失败"<<endl;
return -1;
}
//设置视口,OpenGL幕后的坐标转窗口坐标将以此为参考
//OpenGL的坐标最大最小值为1和-1
//如下x轴-1~1对应窗口坐标0~800,y轴-1~1对应窗口坐标0~600
//如OpenGL坐标(0,0)对应窗口坐标(400,300),(-0.5,0.5)对应(200,450)
glViewport(0,0,800,600);
//编译着色器
int vertexShader=CompileShader(vertexShaderSource, GL_VERTEX_SHADER);
if(!vertexShader) return -1;
int fragmentShader=CompileShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
if(!fragmentShader) return -1;
//链接着色器程序
int shaderProgram=glCreateProgram();
glAttachShader(shaderProgram,vertexShader);
glAttachShader(shaderProgram,fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
//创建VAO
GLuint VAO=0;
glGenVertexArrays(1,&VAO);
glBindVertexArray(VAO);
//创建VBO
GLuint VBO=0;
glGenBuffers(1,&VBO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);
//创建EBO
GLuint EBO=0;
glGenBuffers(1,&EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);
//顶点数据 从偏移0 * 6*sizeof(float)处开始拿3个float
//之后再从偏移1 * 6*sizeof(float)处开始拿3个float 直到拿完
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,6*sizeof(float),(void*)0);
glEnableVertexAttribArray(0);
//颜色数据同上 不过偏移是从3*sizeof(float)开始,不是从0
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,6*sizeof(float),(void*)(3*sizeof(float)));
glEnableVertexAttribArray(1);
int index=glGetUniformLocation(shaderProgram,"pos");
//注册窗口大小变化回调函数
glfwSetFramebufferSizeCallback(window,framebuffer_size_callback);
//窗口循环 如果窗口被关闭,则退出循环
while(!glfwWindowShouldClose(window))
{
//监视键盘输入
processInput(window);
//清除颜色缓冲
glClearColor(0.2f,0.3f,0.3f,0.8f);
//GL_COLOR_BUFFER_BIT 颜色缓冲
//GL_DEPTH_BUFFER_BIT 深度缓冲
//GL_STENCIL+BUFFER_BIT 模板缓冲
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glUniform2f(index,x,y);
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
//交换颜色缓冲,OpenGL绘图的时候,前缓冲用于显示,后缓冲就在渲染
//当后缓冲渲染完毕,前缓冲和后缓冲互换,后缓冲变前缓冲,前缓冲变后缓冲
glfwSwapBuffers(window);
//消息分发函数 检测有没有触发窗口消息,然后调用对应回调函数
glfwPollEvents();
}
glDeleteVertexArrays(1,&VAO);
glDeleteBuffers(1,&VBO);
glDeleteBuffers(1,&EBO);
glfwTerminate();
return 0;
}