Opengl1——比较乱的笔记,稍后整理
Opengl:
glDrawArrays(GL_TRIANGLES,0,3);
OpenGL中通过缓冲区来绘制一个三角形的命令,在这之前要先定义好
如下:
1 | float positions[6] = |
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 | \#version 330 core |
码需要定义在使用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不变,具体的计算方法如下所示
常用的透视投影:
正交投影和透视投影,
正交投影通常用于2D渲染,记住是通常
透视投影通常用于3D渲染,但是也只是通常,该情况只根据实际需求而定
简而言之,正交矩阵中设置的是需要内容对照的新坐标系,二者相乘就会把内容的不规则坐标系转换为标准设备坐标系。
只是需要注意的是正交坐标系需要在前面,根据矩阵相乘的特性来看,交换位置,结果不一样
Mvp:保证的是模型的移动,在OpenGL中,三个矩阵的相乘顺序是反着来的,这是由OpenGL的规范决定的,OpenGL的矩阵是由列开始排序的。
P,v,m
批渲染
批渲染的两种实现方法:
第一种是利用统一变量,调用两次drawcall,这样的方法由一定的好处,虽然顶点缓冲区中的数据量没有增加,但是调用了两次drawcall,其中还有glcall的断言,当图像数量增加到一定程度时候,渲染就会变得很慢,图像出现掉帧
第二种是把顶点所有的顶点数据塞进一个顶点缓冲区内,一个drawcall就可以直接解决所有问题。
纹理:
这里有一个问题,把统一变量变成一个数组然后批渲染纹理的时候出现了问题。

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中还加入了只能指针来测试,所所以出现了问题,错误是如图最后一句。
前提是我用了断言