OpenGL | 让一个三角形转起来

OpenGL | 让一个三角形转起来

基本思路:
直接利用传给GPU的数据并行计算旋转后三角形的参数,而不需要bande passante entre CPU et GPU。
Sol: 利用uniform参数调节shaders,可以将其视为在CPU上运行的代码可以传递给图形卡着色器的变量,对于一个形状顶点的uniforms参数是常熟。
利用glUniformX函数进行改变。

二维旋转用到的矩阵:
在这里插入图片描述
主要修改的部分:
Shader: 增加一个4维旋转矩阵R并作用于position,这个是对所有的物体作用的,即大家一起一个方向旋转。

#version 330 core
layout (location = 0) in vec4 position;
uniform mat4 R;
void main()
{
    gl_Position = R*position;
}

旋转控制:

	// ******************************** //
    // Setup animation data
    // ******************************** //
    const float t = counter_drawing_loop/100.0f;

    // create rotation matrix
    const std::array<GLfloat,16> R = {
        std::cos(t),-std::sin(t),0,0,
        std::sin(t), std::cos(t),0,0,
                  0,           0,1,0,
                  0,           0,0,1
    };


    // ******************************** //
    // Clear screen
    // ******************************** //
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);


    // ******************************** //
    // Draw data
    // ******************************** //
    glUseProgram(shader_program);
    glBindVertexArray(vao);

    // Rotation
    const GLint R_loc = glGetUniformLocation(shader_program, "R"); // Locate R uniform variable in the shader,因为shader中uniform变量名字为R
    glUniformMatrix4fv(R_loc, 1, GL_TRUE, &R[0]); // Send rotation matrix R as uniform parameter R_loc
	
	// Draw call
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glDrawArrays(GL_TRIANGLES, 3, 3);

    glBindVertexArray(0);
    glUseProgram(0);
	

如果不使用glClear(GL_COLOR_BUFFER_BIT);清屏的后果
在这里插入图片描述
在具体画之前,需要调用glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)

  • location: Localisation de la variable uniform renvoyée par la fonction glGetUniformLocation,如我们之前用的是const GLint R_loc = glGetUniformLocation(shader, "R");
  • count: Nombre de paramètre uniforms à envoyer par cet appel. 我们这里只需要传递时间参数 t t t.
  • transpose: Indique si la matrice doit être transposée une fois passée au shader. GLSL utilise une représentation par colonne, qui est la version transposée de la représentation implicitement utilisée lors de la définition de la matrice dans le programme principal. Nous plaçons ainsi ce paramètre à true. [因为默认是要转置,所以要设置为GL_True]
  • value: Adresse du premier élément des données (rem. la matrice doit nécessairement être stockée sous la forme d’une suite de valeurs contigües en mémoire). Uniform真实数据来源

总结:

  1. vertex_shader.glsl:用于控制位置,图形大小
#version 330 core
layout (location = 0) in vec4 position;
uniform mat4 R;
void main()
{
    gl_Position = R*position;
}

  1. fragment_shader.glsl:用于控制图形的颜色
#version 330 core

out vec4 FragColor;
uniform vec4 color;

void main()
{
    FragColor = color;
//    FragColor = vec4(1.0, 1.0, 0.0, 1.0);
}

  1. uniform变量的使用:
    首先需要在shader中定义,并取一个变量名varName
    然后在主要函数main中可以定义一个函数用于将数据传给shader中的varName,常用std::array<GLfloat,16>std::vector<GLfloat>定义具体的值在变量realVar等,最后利用下面的代码将realVarvarName联系在一起,颜色设置默认对下一个物体有效。
// Locate R uniform variable in the shader
const GLint R_loc = glGetUniformLocation(shader_program, "R");     
glUniformMatrix4fv(R_loc, 1, GL_TRUE, &R[0]); // Send rotation matrix as uniform parameter

// Color
const GLint color1_loc = glGetUniformLocation(shader_program, "color");
glUniform4fv(color1_loc, 1, &color1[0]);

部分代码:

int main()
{
    std::cout<<"*** Init GLFW ***"<<std::endl;
    glfw_init();

    std::cout<<"*** Create window ***"<<std::endl;
    auto window = glfw_create_window(500,500,"My Window");
    glfwMakeContextCurrent(window);

    std::cout<<"*** Init GLAD ***"<<std::endl;
    glad_init();


    print_opengl_information();

    std::cout<<"*** Setup Data ***"<<std::endl;
    load_data();

    std::cout<<"*** Compile Shader ***"<<std::endl;
    shader_program = create_shader_program("shaders/vertex_shader.glsl","shaders/fragment_shader.glsl");

    std::cout<<"*** Start GLFW loop ***"<<std::endl;
    while( !glfwWindowShouldClose(window) ) {

        draw_data();

        ++counter_drawing_loop;  // 在这里设置类似一个时间,用于更新R中的参数。
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    std::cout<<"*** Terminate GLFW loop ***"<<std::endl;

}

void draw_data()
{

    // ******************************** //
    // Setup animation data
    // ******************************** //
    const float t = counter_drawing_loop/100.0f;

    // create rotation matrix
    const std::array<GLfloat,16> R = {
        std::cos(t),-std::sin(t),0,0,
        std::sin(t), std::cos(t),0,0,
                  0,           0,1,0,
                  0,           0,0,1
    };

    const std::vector<GLfloat> color1 = {1.0f,0.0f,0.0f,0.0f};
    const std::vector<GLfloat> color2 = {0.0f,1.0f,0.0f,0.0f};


    // ******************************** //
    // Clear screen
    // ******************************** //
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);


    // ******************************** //
    // Draw data
    // ******************************** //
    glUseProgram(shader_program);
    glBindVertexArray(vao);

    // Rotation
    const GLint R_loc = glGetUniformLocation(shader_program, "R"); // Locate R uniform variable in the shader
    glUniformMatrix4fv(R_loc, 1, GL_TRUE, &R[0]); // Send rotation matrix as uniform parameter

    // Color
    const GLint color1_loc = glGetUniformLocation(shader_program, "color");
    glUniform4fv(color1_loc, 1, &color1[0]);

    // Draw call
    glDrawArrays(GL_TRIANGLES, 0, 3);

    const GLint color2_loc = glGetUniformLocation(shader_program, "color");
    glUniform4fv(color2_loc, 1, &color2[0]);
    glDrawArrays(GL_TRIANGLES, 3, 3);

    glBindVertexArray(0);
    glUseProgram(0);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值