vs c++ opengl渲染

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "linmath.h"
#include <stdlib.h>
#include <stdio.h>
static const struct
{
    float x, y;
    float r, g, b;
} vertices[3] =
{
    { -0.6f, -0.4f, 1.f, 0.f, 0.f },
{ 0.6f, -0.4f, 0.f, 1.f, 0.f },
{ 0.f,  0.6f, 0.f, 0.f, 1.f }
};

static const char* vertex_shader_text =
"uniform mat4 MVP;\n"
"attribute vec3 vCol;\n"
"attribute vec2 vPos;\n"
"varying vec3 color;\n"
"void main()\n"
"{\n"
"    gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n"
"    color = vCol;\n"
"}\n";

static const char* fragment_shader_text =
"varying vec3 color;\n"
"void main()\n"
"{\n"
"    gl_FragColor = vec4(color, 1.0);\n"
"}\n";
static void error_callback(int error, const char* description)
{
    fprintf(stderr, "Error: %s\n", description);
}
当用户按下esc,我们就把windowShouldClose设置为ture,关闭应用
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GLFW_TRUE);
}
int main(void)
{
    GLFWwindow* window;
    GLuint vertex_buffer, vertex_shader, fragment_shader, program;
    GLint mvp_location, vpos_location, vcol_location;
    glfwSetErrorCallback(error_callback);
    if (!glfwInit())
        exit(EXIT_FAILURE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
    //glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }
    glfwSetKeyCallback(window, key_callback);
    glfwMakeContextCurrent(window);//告诉GLFW创建窗口环境,这个环境是当前线程的主环境
    gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
    glfwSwapInterval(1);//可以将该间隔设为1,即每帧更新一次。 它可以设置为更高的值,但这可能导致输入延迟

    // NOTE: OpenGL error checks have been omitted for brevity
    glGenBuffers(1, &vertex_buffer);// //VBO(顶点缓冲对象)这个缓冲有一个独一无二的ID,所以我们可以使用glGenBuffer函数生成一个缓冲ID
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);// 我们可以使用glBinBuffer函数把创建的缓冲帮点到GL_ARRAY_BUFFER上
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// Give our vertices to OpenGL.// 然后我们可以调用glBUffweData函数它会把之前定义的顶点数据复制到缓冲的内存中
    
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
    glCompileShader(vertex_shader);//编译着色器
    GLint success;
    GLchar infoLog[512];
    glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
    /*
    首先我们定义一个整型来表示是否成功编译,还需要一个储存错误消息的容器(如果有的话)。然后我们用glGetShaderiv检查是否编译成功了。
    如果编译失败,我们应该用glGetShaderInfoLog获取错误消息,然后打印它
    */
    if (!success)
    {
        glGetShaderInfoLog(vertex_shader, 512, NULL, infoLog);
        printf("info glshaderinfolog %s\n", infoLog);
        //std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
    }

    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
    glCompileShader(fragment_shader);

    program = glCreateProgram();
    glAttachShader(program, vertex_shader);
    glAttachShader(program, fragment_shader);
    glLinkProgram(program);

    //设置完上面后我们可以调用glUseProgram函数,用新创建的程序对象作为参数,这样就能激活程序对象
    //把着色器对象链接到程序对象后,不要忘记删除着色器对象
    glDeleteShader(vertex_shader);
    glDeleteShader(fragment_shader);

    mvp_location = glGetUniformLocation(program, "MVP");
    vpos_location = glGetAttribLocation(program, "vPos");
    vcol_location = glGetAttribLocation(program, "vCol");

    //告诉OpenGL如何解释顶点数据(每一个顶点的属性)
    glEnableVertexAttribArray(vpos_location); //开启
    glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
        sizeof(float) * 5, (void*)0);//使用glVertexAttribPointer的顶点属性配置。
    glEnableVertexAttribArray(vcol_location);
    glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE,
        sizeof(float) * 5, (void*)(sizeof(float) * 2));

    //glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered(注册) VBO as the currently bound vertex buffer object so afterwards we can safely unbind(解绑)

    //glBindVertexArray(0); // 解绑定
    while (!glfwWindowShouldClose(window))//数从开始便检验每一次循环迭代中gLFW是否已经得到关闭指示
    {
        float ratio;
        int width, height;
        mat4x4 m, p, mvp;
        glfwGetFramebufferSize(window, &width, &height);
        ratio = width / (float)height;
        glViewport(0, 0, width, height);//设置渲染窗口
        glClear(GL_COLOR_BUFFER_BIT);

        // 开始绘制物体
        mat4x4_identity(m);
        mat4x4_rotate_Z(m, m, (float)glfwGetTime());
        mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f);
        mat4x4_mul(mvp, p, m);

        glUseProgram(program);//调用渲染程序
        glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*)mvp);
        //glDrawArrays函数第一个参数是我们打算绘制的OpenGL基本图形的类型。由于我们在一开始时说过,
        //我们希望绘制三角形,我们传递GL_TRIANGLES给它。第二个参数定义了我们打算绘制的那个顶点数组的起始位置的索引;我们这里填0。
        //最后一个参数指定我们打算绘制多少个顶点,这里是3(我们只从我们的数据渲染一个三角形,它只有3个顶点)。
        glDrawArrays(GL_TRIANGLES, 0, 3);

        glfwSwapBuffers(window);//函数会交换颜色缓冲(颜色缓冲是一个GLFW窗口为每一个像素存储的颜色数值的最大缓冲)
        检验是否有任务被触发了,(比如鼠标移动和键盘的输入事件),接着...调用相关的回调函数
        glfwPollEvents();//当你制作游戏或是动画时,尽量使用轮询。 如果相反,你需要在产生事件后才渲染,可是通过等待来处理事件,即glfwWaitEvent
    }

    glfwDestroyWindow(window);
    glfwTerminate();释放所有的资源
    exit(EXIT_SUCCESS);
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值