Opengl:
glDrawArrays(GL_TRIANGLES,0,3);

OpenGL中通过缓冲区来绘制一个三角形的命令,在这之前要先定义好

如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  float positions[6] =

{

-0.5f,-0.5f,

0.0f, 0.5f,

0.5f, -0.5f,



};



unsigned int buffer;

glGenBuffers(1,&buffer);

glBindBuffer(GL_ARRAY_BUFFER,buffer);

glBufferData(GL_ARRAY_BUFFER,6*sizeof(float),positions,GL_STATIC_DRAW);

positions数组是用来存储顶点位置的

1, 创建一个unsigned int

2, 创建缓冲区

3, 绑定缓冲区

4, 传递数据

顶点的概念:

​ 顶点不只是一个单纯的由xy坐标位置组成的数据,它包含的是图像在这个位置的所有信息

Shader :
static unsigned int CompileShader(unsigned int type,const string &scoure)

{

unsigned int id = glCreateShader(type);

const char* src = scoure.c_str();

glShaderSource(id,1,&src,NULL);

glCompileShader(id);

int result;

glGetShaderiv(id,GL_COMPILE_STATUS,&result);

if (result == GL_FALSE)

{

​ int length;

​ glGetShaderiv(id,GL_INFO_LOG_LENGTH,&length);

​ char* message = (char*)alloca(length * sizeof(char));

​ glGetShaderInfoLog(id,length,&length,message);

​ cout << “Failed to conpile” << “\t” << (type == GL_VERTEX_SHADER ? “vertext” : “fragment”) << endl;

​ cout << message << endl;

​ glDeleteShader(0);

​ return 0;

}

return id;

}

static unsigned int createShader(const string& vertexShader, const string& fragmentShader)

{

unsigned int program = glCreateProgram();

unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);

unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);

glAttachShader(program, vs);

glAttachShader(program, fs);

glLinkProgram(program);

glValidateProgram(program);

glDeleteShader(vs);

glDeleteShader(fs);

return program;

}

string vertexShader =

​ “#version 330 core\n”

​ “\n”

​ “layout(location = 0) in vec4 positions;\n”

​ “\n”

​ “void main()\n”

​ “\n”

​ “{\n”

​ “ gl_Position = positions;\n”

​ “}\n”;

string fragmentShader =

​ “#version 330 core\n”

​ “\n”

​ “layout(location = 0) out vec4 color;\n”

​ “\n”

​ “void main()\n”

​ “\n”

​ “{\n”

​ “ color = vec4(1.0,0.0,0.0,1.0);\n”

​ “}\n”;

画一个红色的三角形

Shader写进一个文件外挂处理

String::find()在找不到内容的情况下,会返回一个string::npos

整个缓冲区必须是由无符号整型构成

错误处理:
1,

断言,注意:
以前的版本可能需要在定义宏的x行的反斜杠后加上一个空格,但是现在已经不需要了

而且需要在本地计算机进行调试,反复几次才会出来结果

GlCall(glDrawElements(GL_TRIANGLES, 6, GL_INT, nullptr));

#define ASSERT(x) if(!(x)) __debugbreak();

#define GlCall(x) GLClearShader();\

​ x;\

​ ASSERT(GLLogCall())//声明

enum class ShaderType { NONE =-1, VERTEX =0, FRAGMENT= 1 };

static void GLClearShader()

{

while (glGetError()!=GLEW_NO_ERROR);

}

static bool GLLogCall()

{

while (GLenum error = glGetError())

{

​ cout << “[opengl error] “ << error << endl;

​ return false;

}

return true;

}

2,

统一变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
\#version 330 core 



layout(location = 0) out vec4 color;



uniform vec4 u_color;



void main()



{

color = u_color;

} ;

下面的代

码需要定义在使用shader后

int location = glGetUniformLocation(shader, “u_color”);

ASSERT(location != -1);

glUniform4f(location, 0.0, 1.0, 0.0, 1.0);

混合

GlCall(glEnable(GL_BLEND));

//混合函数:glDisable是禁用混合,上面的是启用混合,默认清空下禁用

GlCall(glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA));

//设置混合方法,该方法默认启用的是相加,里面的两个参数在计算过后相加

//案例:

如图所示是第二个方法的使用原理,默认情况下指定src不变,具体的计算方法如下所示

image-20240823201139791

image-20240823201146281

常用的透视投影:

​ 正交投影和透视投影,

正交投影通常用于2D渲染,记住是通常

透视投影通常用于3D渲染,但是也只是通常,该情况只根据实际需求而定

简而言之,正交矩阵中设置的是需要内容对照的新坐标系,二者相乘就会把内容的不规则坐标系转换为标准设备坐标系。

只是需要注意的是正交坐标系需要在前面,根据矩阵相乘的特性来看,交换位置,结果不一样

Mvp:保证的是模型的移动,在OpenGL中,三个矩阵的相乘顺序是反着来的,这是由OpenGL的规范决定的,OpenGL的矩阵是由列开始排序的。

P,v,m

批渲染

批渲染的两种实现方法:

​ 第一种是利用统一变量,调用两次drawcall,这样的方法由一定的好处,虽然顶点缓冲区中的数据量没有增加,但是调用了两次drawcall,其中还有glcall的断言,当图像数量增加到一定程度时候,渲染就会变得很慢,图像出现掉帧

​ 第二种是把顶点所有的顶点数据塞进一个顶点缓冲区内,一个drawcall就可以直接解决所有问题。

纹理:

这里有一个问题,把统一变量变成一个数组然后批渲染纹理的时候出现了问题。

image-20240823201050698

layout(location = 0) out vec4 mycolor;

in vec2 v_TexCoord;

in float v_Index;

uniform sampler2D u_Texture[2];

void main()

{

int index = (int)v_Index;

vec4 texColor = texture(u_Texture[index], v_TexCoord);

mycolor = texColor;;

};

解法

但是由于前面跟着视频,把texture封装到类中并且在texturetext中还加入了只能指针来测试,所所以出现了问题,错误是如图最后一句。

前提是我用了断言