OpenGL进阶 | 绘制一个三角形

2023-05-16

一、准备绘图数据

  • VBO(Vertex Buffer Object)

        在opengl中,所有的数据都要放在显存中,通过VBO(Vertex Buffer Object)可将CPU数据传到GPU。

        VBO(Vertex Buffer Object)是OpenGL中的一种机制,用于将顶点数据存储在显存中,以便GPU可以快速访问和处理。VBO是一种缓冲对象,类似于CPU中的数组或列表,可以用来存储顶点的位置、颜色、纹理坐标等属性。使用VBO可以避免每次渲染时都需要从CPU到GPU之间复制顶点数据的过程,从而提高了渲染的效率。

GLuint vbo;
void Init()
{
    float data[] = {
        -0.2f,-0.2f,-0.6f,1.0f,
        0.2f,-0.2f,-0.6f,1.0f,
        -0.2f,0.2f,-0.6f,1.0f
    };
    glGenBuffers(1, &vbo);                                                   //需要1个VBO,把vbo写入到显卡进去,供后续操作
    glBindBuffer(GL_ARRAY_BUFFER, vbo);                                      //把vbo设置到卡槽上
    //glBufferData(GL_ARRAY_BUFFER,sizeof(float)*12, nullptr,GL_STATIC_DRAW);//只在GPU上开辟内存不传数据
    glBufferData(GL_ARRAY_BUFFER,sizeof(float)*12,data,GL_STATIC_DRAW);      //将数据从cpu传到Gpu,此后data数据可删除。
    glBindBuffer(GL_ARRAY_BUFFER, 0);                                        //卡槽重新绑定,防止误操作
}

二、编写Shader

1.顶点着色器

        vertex shader,test.vs文件如下:

attribute vec4 position;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;
void main()
{
	gl_Position=ProjectionMatrix*ViewMatrix*ModelMatrix*position;
}
  •  uniform和attribute

在OpenGL中,uniform和attribute是用于在着色器程序中传递数据的两种不同类型。

  1. Uniform变量: Uniform变量是一种全局变量,用于在不同的着色器阶段之间传递数据。它们在着色器程序中的任何地方都可以访问,不受顶点或片段的限制。Uniform变量通常用于传递全局数据,例如变换矩阵、光照参数、纹理等。在程序中,你可以使用glGetUniformLocation函数获取Uniform变量的位置(或插槽),然后使用glUniform函数将值传递给Uniform变量。

  2. Attribute变量: Attribute变量是一种顶点属性,用于在顶点着色器中接收每个顶点的输入数据。它们通常用于表示顶点的位置、颜色、法线等属性。Attribute变量只能在顶点着色器中使用,并且每个顶点都会有对应的属性值。在程序中,你可以使用glGetAttribLocation函数获取Attribute变量的位置(或插槽),然后使用glVertexAttribPointer函数设置属性数据的格式和位置。

        关于插槽(location)的分配,Uniform变量和Attribute变量都是从0开始分配的。可以使用glGetUniformLocation和glGetAttribLocation函数获取它们在着色器程序中的位置(或插槽)值。对于Uniform变量,可以使用glUniform函数将值传递给指定位置的Uniform变量。对于Attribute变量,可以使用glVertexAttribPointer函数将属性数据绑定到指定位置的Attribute变量。

        需要注意的是,Uniform变量和Attribute变量在不同的着色器阶段之间传递数据的方式和使用方法是不同的。Uniform变量用于在整个着色器程序中传递全局数据,而Attribute变量用于在顶点着色器中接收每个顶点的属性数据。

2.片段着色器

        fragment shader,test.fs文件如下:

#ifdef GL_ES
precision mediump float;
#endif
void main()
{
	gl_FragColor=vec4(1.0,1.0,1.0,1.0);
}

三、编译Shader

1.相关函数

  • glCreateShader

GLuint glCreateShader(GLenum shaderType);

        shaderType指示要创建的着色器的类型,支持两种类型的着色器:

  1.  GL_VERTEX_SHADER类型的着色器是一个用于在可编程顶点处理器上运行的着色器。
  2.  GL_FRAGMENT_SHADER类型的着色器是一个着色器,旨在在可编程片段处理器上运行。

        glCreateShader创建一个空的着色器对象,并返回一个可以引用的非零值(Shader ID)。着色器对象用于维护定义着色器的源代码字符串。

  • glShaderSource

        glShaderSource是OpenGL中用于设置着色器源代码的函数。它的作用是将字符串形式的着色器源代码加载到指定的着色器对象中,以便后续编译和链接。具体来说,glShaderSource函数有四个参数:

void glShaderSource(GLuint shader, GLsizei count, const GLchar **string, const GLint *length);
  1. shader:要设置源代码的着色器对象的ID。
  2. count:要设置的源代码字符串数量。
  3. string:源代码字符串数组的指针。
  4. length:源代码字符串数组中每个字符串的长度,如果为NULL,则默认使用字符串的长度。
  • glCompileShader

        glCompileShader是OpenGL中用于编译着色器对象的函数。它的作用是将glShaderSource函数加载的着色器源代码编译成可执行的着色器程序,供OpenGL渲染时使用。

具体来说,glCompileShader函数有一个参数:

void glCompileShader(GLuint shader);
  1. shader:要编译的着色器对象的ID。
  • glGetShaderiv

            glGetShaderiv是OpenGL中获取着色器对象参数的函数之一,它的作用是获取指定着色器对象的特定参数信息,例如编译状态、参数个数、参数类型等等。具体来说,glGetShaderiv函数有三个参数:

void glGetShaderiv(GLuint shader, GLenum pname, GLint *params);
  1. shader:要查询的着色器对象的ID。

  2. pname:要查询的参数名称,可选值包括:

    • GL_SHADER_TYPE:着色器类型,取值为GL_VERTEX_SHADER或GL_FRAGMENT_SHADER。
    • GL_DELETE_STATUS:着色器是否已被标记为删除。
    • GL_COMPILE_STATUS:着色器编译状态,取值为GL_TRUE或GL_FALSE。
    • GL_INFO_LOG_LENGTH:着色器信息日志的长度,以字符数为单位。
    • GL_SHADER_SOURCE_LENGTH:着色器源代码的长度,以字符数为单位。
    • GL_NUM_SHADER_BINARY_FORMATS:支持的着色器二进制格式数量。
    • GL_SHADER_BINARY_FORMATS:支持的着色器二进制格式列表。
    • 其他参数,例如GL_SHADER_IDENTITY_MATRIX等等。
  3. params:指向存储返回参数值的变量的指针。

  • glDeleteShader

        glDeleteShader是OpenGL中删除着色器对象的函数之一。它的作用是删除已经创建的着色器对象,释放显存中的资源。具体来说,glDeleteShader函数有一个参数:

void glDeleteShader(GLuint shader);
  1. shader:要删除的着色器对象的ID。

        需要注意的是,如果着色器对象已经被附加到程序对象中,那么在程序对象链接之前无法删除着色器对象。因此,通常建议在使用完着色器对象后立即删除它,以免占用过多的显存资源。

2.举个例子

GLuint CompileShader(GLenum shaderType, const char* shaderCode)
{
    GLuint shader = glCreateShader(shaderType);
    glShaderSource(shader, 1, &shaderCode, nullptr);
    glCompileShader(shader);
    GLint compileResult = GL_TRUE;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
    if (compileResult == GL_FALSE) {
        char szLog[1024] = { 0 };
        GLsizei logLen = 0;
        glGetShaderInfoLog(shader, 1024, &logLen, szLog);
        printf("Compile Shader fail error log : %s \nshader code :\n%s\n", szLog, shaderCode);
        glDeleteShader(shader);
        shader = 0;
    }
    return shader;
}

四、链接成程序

1.相关函数

  • glCreateProgram

        glCreateProgram是OpenGL中创建着色器程序对象的函数之一。它的作用是创建一个着色器程序对象并返回其ID,用于管理多个着色器对象的链接过程。具体来说,glCreateProgram函数没有参数,只返回一个GLuint类型的着色器程序对象ID:

GLuint glCreateProgram(void);
  • glAttachShader

        glAttachShader是OpenGL中将着色器对象附加到程序对象的函数之一。它的作用是将一个或多个着色器对象附加到一个程序对象上,为后续的链接操作做准备。具体来说,glAttachShader函数有两个参数:

void glAttachShader(GLuint program, GLuint shader);
  1. program:要附加到的程序对象的ID。
  2. shader:要附加的着色器对象的ID。
  • glLinkProgram

        glLinkProgram是OpenGL中链接着色器程序的函数之一,用于将一个程序对象中所有附加的着色器对象链接为一个可执行程序。在链接过程中,OpenGL会将不同着色器之间的变量名和类型进行匹配和连接,最终生成一个可供GPU执行的着色器程序。具体来说,glLinkProgram函数有一个参数:

void glLinkProgram(GLuint program);
  1. program:要链接的程序对象的ID。

        需要注意的是,glLinkProgram函数链接完成后会将链接日志存储在程序对象中,我们可以通过调用glGetProgramiv函数查询链接状态,或者通过调用glGetProgramInfoLog函数获取链接日志。另外,如果链接失败,程序对象的状态将会被标记为链接失败,并且该程序对象无法使用。

  • glDetachShader

        glDetachShader是OpenGL中将着色器对象从程序对象中分离的函数之一。它的作用是将一个着色器对象从一个程序对象中分离,使该着色器对象可以在其他程序对象中使用。具体来说,glDetachShader函数有两个参数:

void glDetachShader(GLuint program, GLuint shader);
  1. program:要分离着色器对象的程序对象的ID。
  2. shader:要分离的着色器对象的ID。
  • glGetProgramiv

        glGetProgramiv是OpenGL中获取着色器程序对象参数的函数之一。它的作用是获取指定着色器程序对象的特定参数信息,例如链接状态、参数个数、参数类型等等。具体来说,glGetProgramiv 函数有三个参数:

void glGetProgramiv(GLuint program, GLenum pname, GLint *params);
  1. program:要查询的着色器程序对象的ID。

  2. pname:要查询的参数名称,可选值包括:

    1. GL_DELETE_STATUS:程序是否已被标记为删除。
    2. GL_LINK_STATUS:程序链接状态,取值为GL_TRUE或GL_FALSE。
    3. GL_VALIDATE_STATUS:程序验证状态,取值为GL_TRUE或GL_FALSE。
    4. GL_INFO_LOG_LENGTH:链接或验证日志的长度,以字符数为单位。
    5. GL_ATTACHED_SHADERS:附加的着色器对象数量。
    6. GL_ACTIVE_ATTRIBUTES:激活的顶点属性数量。
    7. GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:激活的顶点属性名称的最大长度。
    8. GL_ACTIVE_UNIFORMS:激活的Uniform变量数量。
    9. GL_ACTIVE_UNIFORM_MAX_LENGTH:激活的Uniform变量名称的最大长度。
    10. 其他参数,例如GL_PROGRAM_BINARY_RETRIEVABLE_HINT等等。
  3. params:指向存储返回参数值的变量的指针。

  • glDeleteProgram

        glDeleteProgram是OpenGL中删除着色器程序对象的函数之一。它的作用是删除已经创建的着色器程序对象,释放显存中的资源。具体来说,glDeleteProgram函数有一个参数:

void glDeleteProgram(GLuint program);
  1. program:要删除的着色器程序对象的ID。

2.举个例子

GLuint CreateProgram(GLuint vsShader, GLuint fsShader) {
    GLuint program = glCreateProgram();
    glAttachShader(program, vsShader);
    glAttachShader(program, fsShader);
    glLinkProgram(program);
    glDetachShader(program, vsShader);
    glDetachShader(program, fsShader);
    GLint nResult;
    glGetProgramiv(program, GL_LINK_STATUS, &nResult);
    if (nResult == GL_FALSE) {
        char log[1024] = { 0 };
        GLsizei writed = 0;
        glGetProgramInfoLog(program, 1024, &writed, log);
        printf("create gpu program fail,link error : %s\n", log);
        glDeleteProgram(program);
        program = 0;
    }
    return program;
}

五、读取shader源码到GPU程序

GLuint program;
void Init()
{
    //...
    //准备绘图数据
    //...
    
    int fileSize = 0;
    unsigned char * shaderCode = LoadFileContent("Res/test.vs", fileSize);
    GLuint vsShader = CompileShader(GL_VERTEX_SHADER, (char*)shaderCode);
    delete shaderCode;
    shaderCode = LoadFileContent("Res/test.fs", fileSize);
    GLuint fsShader = CompileShader(GL_FRAGMENT_SHADER, (char*)shaderCode);
    delete shaderCode;
    program = CreateProgram(vsShader, fsShader);
    glDeleteShader(vsShader);
    glDeleteShader(fsShader);
}

六、读取shader中的变量

1.相关函数

  • glGetUniformLocation

        glGetUniformLocation是OpenGL中用于获取Uniform变量的位置(或插槽)的函数之一。它用于查询指定着色器程序对象中的Uniform变量的位置,以便后续对其进行赋值。具体来说,glGetUniformLocation函数有两个参数:

GLint glGetUniformLocation(GLuint program, const GLchar *name);
  1. program:要查询Uniform变量的着色器程序对象的ID。
  2. name:Uniform变量的名称。(Uniform变量的名称必须与着色器程序中定义的Uniform变量的名称完全匹配。)
  • glGetAttribLocation

        glGetAttribLocation是OpenGL中用于获取Attribute变量的位置(或插槽)的函数之一。它用于查询指定着色器程序对象中的Attribute变量的位置,以便后续绑定顶点数据。具体来说,glGetAttribLocation函数有两个参数:

GLint glGetAttribLocation(GLuint program, const GLchar *name);
  1. program:要查询Attribute变量的着色器程序对象的ID。
  2. name:Attribute变量的名称。(Attribute变量的名称必须与着色器程序中定义的Attribute变量的名称完全匹配。)

2.举个例子

GLint positionLocation,modelMatrixLocation,viewMatrixLocation,projectionMatrixLocation;
void Init()
{
    //...
    //准备绘图数据
    //...

    //...
    //读取shader源码到GPU程序
    //...

    positionLocation = glGetAttribLocation(program, "position");
    modelMatrixLocation = glGetUniformLocation(program, "ModelMatrix");
    viewMatrixLocation = glGetUniformLocation(program, "ViewMatrix");
    projectionMatrixLocation = glGetUniformLocation(program, "ProjectionMatrix");
}

七、设置MVP矩阵

1.MVP矩阵

        在OpenGL中设置MVP(Model-View-Projection)矩阵是用于进行物体的变换和投影的重要步骤之一。通常,Model矩阵表示物体的模型变换,View矩阵表示摄像机的观察变换,而Projection矩阵表示投影变换。

        对于Model矩阵和View矩阵,默认是单位矩阵,所以不需要显式设置它们,可以通过使用glm库中的glm::mat4的默认构造函数创建单位矩阵。

        对于Projection矩阵,可以使用glm库中的glm::perspective函数来设置。

glm::mat4 glm::perspective(float fov, float aspect, float near, float far);
  1. fov:视野角度(Field of View),以弧度为单位。
  2. aspect:视口的宽高比(宽度除以高度)。
  3. near:近平面距离摄像机的距离。
  4. far:远平面距离摄像机的距离。

        该函数将返回一个透视投影矩阵,所有在近平面和远平面内且处于平截头体内的顶点都会被渲染。可以将其应用于Projection矩阵。

2.设置MVP矩阵

glm::mat4 modelMatrix, viewMatrix, projectionMatrix;
void SetViewPortSize(float width, float height)
{
    projectionMatrix = glm::perspective(glm::radians(45.0f), width / height, 0.1f, 1000.0f);
}

八、设置Uniform变量

1.glUniformMatrix4fv

        glUniformMatrix4fv是OpenGL中用于将4x4矩阵数据传递给Uniform变量的函数之一。它用于将一个或多个4x4矩阵值传递给在着色器程序中定义的Matrix4类型的Uniform变量。

void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
  1. location:要传递数据的Uniform变量的位置(或插槽)。
  2. count:要传递的矩阵数量。如果你只传递一个矩阵,则count为1。
  3. transpose:指定是否应该在传递矩阵之前对其进行转置。通常情况下,你可以将其设置为GL_FALSE。
  4. value:指向包含要传递数据的GLfloat数组的指针。矩阵数据按列主序存储在数组中。

2.代码示例

void Draw()
{
    glUseProgram(program);//启用着色器程序
    glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, glm::value_ptr(modelMatrix));   //将模型矩阵传递给着色器程序中的模型矩阵Uniform变量modelMatrixLocation
    glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE, glm::value_ptr(viewMatrix));    //将视图矩阵传递给着色器程序中的视图矩阵Uniform变量viewMatrixLocation
    glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, glm::value_ptr(projectionMatrix));  //将投影矩阵传递给着色器程序中的投影矩阵Uniform变量projectionMatrixLocation
    glUseProgram(0);      //停用着色器程序
}

九、读取vbo数据,绘制三角形

1.相关函数

  • glVertexAttribPointer

        glVertexAttribPointer函数用于指定顶点属性的指针,并设置相关参数。

void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);

参数解释如下:

  1. index:顶点属性的索引,对应于着色器程序中的顶点属性变量。
  2. size:顶点属性的分量数量,例如3表示顶点属性由三个分量组成(如位置属性为x、y、z)。
  3. type:顶点属性的数据类型,例如GL_FLOAT表示浮点型数据。
  4. normalized:指定是否对非浮点型数据进行归一化处理,通常设置为GL_FALSE。
  5. stride:顶点属性之间的字节偏移量,用于在顶点数据中定位不同属性的数据。
  6. pointer:顶点属性数据的指针,指向顶点数据缓冲区中的起始位置。
  • glEnableVertexAttribArray

        glEnableVertexAttribArray函数用于启用指定索引的顶点属性数组。

void glEnableVertexAttribArray(GLuint index);

参数解释如下:

  1. index:顶点属性的索引,对应于着色器程序中的顶点属性变量。
  • glDrawArrays

        glDrawArrays函数用于执行基于顶点数组的图元绘制操作。

void glDrawArrays(GLenum mode, GLint first, GLsizei count);

参数解释如下:

  1. mode:指定绘制的图元类型,例如GL_POINTS表示绘制点,GL_TRIANGLES表示绘制三角形等。
  2. first:指定顶点数组中的起始索引,表示从哪个顶点开始绘制。
  3. count:指定要绘制的顶点数量。

2.代码示例

void Draw()
{
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //...
    //设置Uniform变量
    //...

    glBindBuffer(GL_ARRAY_BUFFER, vbo);  //将顶点缓冲对象绑定到OpenGL的顶点缓冲区(GL_ARRAY_BUFFER)
    glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, sizeof(float)*4, 0);   //定义位置属性
    glEnableVertexAttribArray(positionLocation);  //启用位置属性索引为positionLocation的顶点属性数组
    glDrawArrays(GL_TRIANGLES, 0, 3);    //执行绘制操作。该函数指定了绘制的模式、起始顶点索引和顶点数量。
    glBindBuffer(GL_ARRAY_BUFFER, 0);    //解绑顶点缓冲对象
}

十、补充说明

        shader通常称为着色器,作用是把CPU上的点渲染出来,shader在GPU上是并行执行的,比如三个顶点的数据,会在三个core上并行处理。

        比如我们绘制一个三角形,需要三个顶点数据。顶点着色器将会被执行三次,每次使用不同的顶点数据作为输入。(不需要为每个顶点创建一个单独的vertex shader文件,我们可以使用相同的vertex shader文件来处理所有三个顶点,只需要为每个顶点提供不同的位置属性作为输入),并使用统一变量mvpMatrix进行模型-视图-投影变换。(即:position不一样,m、v、p矩阵相同

  • 3*4个数据的顶点矩阵,三个顶点:
    float data[] = {
        -0.2f,-0.2f,-0.6f,1.0f,
        0.2f,-0.2f,-0.6f,1.0f,
        0.0f,0.2f,-0.6f,1.0f
    };
  • vertex shader文件: 
attribute vec4 position;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenGL进阶 | 绘制一个三角形 的相关文章

随机推荐

  • Windows的active工具

    链接 https pan baidu com s 1gjp 67E3y4Vj3a8s n8dOA 提取码 u4ny 软件解压 xff0c 右键管理员运行Activation cmd 确认是否永久active xff0c 可以在命令提示符执行
  • Bundle Adjustment简述

    转载https blog csdn net OptSolution article details 64442962 在SFM xff08 structure from motion xff09 的计算中BA xff08 Bundle Ad
  • 基于ROS平台的STM32小车-2-小车底盘控制

    本博文将介绍小车底盘控制的原理 xff0c 如PID控制 xff0c 控制程序的编写等 小车控制思想 控制电机转动 电机的控制我们分为两部分 xff0c 一部分为电机转动方向的控制 xff0c 另一个为电机转速的控制 电机转动的方向我们用两
  • Pangolin 安装及其使用

    Pangolin是对OpenGL进行封装的轻量级的OpenGL输入 输出和视频显示的库 可以用于3D视觉和3D导航的视觉图 xff0c 可以输入各种类型的视频 并且可以保留视频和输入数据用于debug 安装 安装的链接是Pangolin的地
  • KPI异常检测

    异常 xff1a 预期值与真实值有很大的差异 统计的方法 3 sigma 刻画异常的程度 xff0c 数据需要接近高斯分布 xff0c 如果不是可以通过高斯分布或者tan变换 可以先看一下数据分布图 xff0c 看一下数据的分布情况 box
  • 如何干掉那又丑又长的switch..case语句

    1 前言 在实际的编程中 xff0c 我们经常会使用到switch case语句 xff0c 这通常也是对一长串if else if语句的优化 对于一些简单的情况 xff08 只每个case代码中代码长度不会很长 xff0c 而且case分
  • 编译安装Openvins过程中遇到的问题

    openvins的编译是依赖opencv contrib库的 xff0c 需要重新下载编译安装opencv xff0c opencv和opencv contrib的版本要对应一致 遇到问题的解决方法参考如下链接 xff1a https bl
  • docker镜像启动后端口号是多少_RSS、智能家居、个人博客、维基百科……Docker 入门指南...

    如果你购买过 VPS 云主机 xff0c 那么或多或少 xff0c 你都可能听说过 Docker 如果你从未听说过 Docker xff0c 那么本文可能能够为你开启新世界 利用 Docker xff0c 你能够非常轻松地部署各类服务 xf
  • linux can接收数据出错,CAN为什么会发送失败

    CAN总线调试过程中出现报文发送失败 xff0c 很多工程师都对此只知其一不知其二 xff0c 这里就CAN报文发送失败的问题我们来做一次探讨 在了解CAN报文为什么会发送失败之前我们先看看一条正确的CAN报文到底应该是怎么样的 xff0c
  • Unity | 总结:OCR文字识别、公式识别

    一 功能简介 xff1a 最近在做一个项目 xff1a 运用OCR文字识别 公式识别 手写英文识别等AI技术 xff0c 当用户批量导入图片或者PDF文件时可快速识别为可编辑文本 xff0c 该项目主要功能有 xff1a 印刷体识别 手写英
  • Unity | 打开文件对话框批量选择文件

    之前在新浪博客写了一篇关于打开文件对话框批量选择文件的文章 xff0c 可惜新浪博客不能写代码 xff0c 奈何当时太年轻 xff0c 并不觉得不方便 xff0c 直到遇到CSDN emmm xff0c 不想将就了 xff0c 所以在这里更
  • C++ | boost库入门

    目录 一 boost库简介 二 boost库安装及编译 1 目录结构说明 2 编译静态库 3 构建工具b2 三 boost库的简单使用 一 boost库简介 Boost是一个功能强大 构造精良 跨越平台 代码开源 完全免费的 C 43 43
  • C++ | boost库之智能指针

    目录 一 RAII机制 二 智能指针 1 C 43 43 98下auto ptr 2 boost scoped ptr 3 boost shared ptr make shared shared ptr应用于标准容器 定制删除器 weak
  • CMake I execute_process命令详解(配置)

    execute process COMMAND lt cmd1 gt lt arguments gt COMMAND lt cmd2 gt lt arguments gt WORKING DIRECTORY lt directory gt
  • CMake I add_custom_command命令详解(构建)

    目录 一 add custom command 1 执行有输出文件的自定义操作 2 执行没有输出的自定义操作 二 应用 1 执行有输出文件的自定义操作 2 执行没有输出的自定义操作 CMake提供了三个选项来在构建时执行自定义命令 xff0
  • ECMAScript6学习笔记-数组扩展

    1 扩展运算符 扩展运算符是三个点 xff0c 将一个数组转为用逗号分割的参数序列 console log span class hljs keyword span span class hljs number 1 span span cl
  • Cmake | ExternalProject_Add函数详解(构建时)

    目录 一 目录选项 1 PREFIX 2 TMP DIR 3 STAMP DIR 4 LOG DIR 5 DOWNLOAD DIR 6 SOURCE DIR 7 BINARY DIR 8 INSTALL DIR 二 下载配置 1 URL 2
  • OpenGL | 入门-零碎总结

    1 powf 幂函数 Pow函数是一种可以快速计算非线性关系的数学函数 xff0c 它的特点是任意非负整数x的n次幂可以快速计算 Pow函数可以通过数学方式简单地计算一个数的平方根 xff0c 立方根或任意次根 它主要用于计算连续的 非线性
  • OpenGL进阶 | GLM数学库& Shader相关

    一 GLM数学库 OpenGL和DirextX不一样 xff0c 没有内置的数学库 xff0c 于是我们需要找一个第三方数学库来完成OpenGL相关的数学计算 GLM库是一个为OpenGL准备的数学库 xff0c 它提供了各种数学运算的函数
  • OpenGL进阶 | 绘制一个三角形

    一 准备绘图数据 VBO xff08 Vertex Buffer Object xff09 在opengl中 xff0c 所有的数据都要放在显存中 xff0c 通过VBO xff08 Vertex Buffer Object xff09 可