OpenGL学习笔记(三)应用前两篇所学,画一个能控制移动的彩色矩形

使用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;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吾无法无天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值