OPENGL Class5 着色器

今天是第五节课,讲着色器,今天课程有点长,课程主要分两部分,阐述什么是着色器,以及在代码实现着色器。

上节课我们使用opengl提供的默认着色器去展示三角形,但你会发现有些电脑显示不了,或者像我这样,显示报错,这都是根据自己显卡过来的。

不要紧,我们不要用默认的着色器,我们今天手写一个着色器。一个着色器就是一个运行在你的显卡上的一个程序(代码)。我们其实使用字符串方式编写代码。然后我们发送到显卡,编译链接并运行。 我们为什么要编写显卡的程序,因为我们希望告诉显卡做什么事情,这样就需要编程,因为编程更自由发挥。图像显示明明可以在cpu运行,但显卡速度要快一些。比如说,通过本节课,我们需要告诉显卡我们要在哪里绘制三角形,三角形的颜色如何。没有着色器的编程,很难实现这样的逻辑。再比如3D空间,我们的光源是如何运行。这就需要编程告诉显卡。我们有基本的顶点着色器和片段着色器。片段着色器就是绘制像素,当然还有很多着色器,几何着色器等。在90%的编程都是使用顶点着色器和片段着色器。

注意:OpenGL非常脆弱,你稍微犯一点小错误,他都是黑屏,显示不出来。我们下面使用代码说明

glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
//我们绑定posion索引0为顶点位置
glClear(GL_COLOR_BUFFER_BIT);
// 表示清除屏幕
// 画出当前绑定缓冲区,还记得我们上次提到Photoshop选中图层,然后对图层操作。
glDrawArrays(GL_TRIANGLES,0,3);
// 交换缓冲区
glfwSwapBuffers(window);
// 回顾上几节课内容,我们是怎么生成缓冲区
// 生成缓冲区 获取id
glGenBuffers(1, &buffer);// 这表明buffer是显卡生成缓冲区id
//绑定缓冲区id
glBindBuffer(GL_ARRAY_BUFFER, buffer);// 相当于告诉显卡,buffer是顶点数组
/**
使用着色器流程如下:
1、创建程序 glCreateProgram --- A program object is an object to which shader
objects can be attached.
2、创建着色器对象(顶点着色器和片段着色器)(相当于c++两个cpp文件)
2.1、创建特定类型的着色器id glCreateShader
2.2、加载着色器源码 glShaderSource
2.3、编译指定着色器 glCompileShader
2.4、处理编译失败原因分析(例如源码少了分号)glGetShaderiv
3、添加着色器对象到着色器程序 glAttachShader
4、链接着色器程序 glLinkProgram
5、验证程序 glValidateProgram
6、删除着色器对象中间编译文件(就像删除c++的obj文件,因为我们已经得到可运行的程序)
glDeleteShader
7、编写着色器代码 (创建字符串 vertexShader,fragmentShader)
8、把着色器代码传入创建着色器程序里面 unsigned int shader =
CreateShader(vertexShader,fragmentShader);
9、使用着色器 glUseProgram(shader);
**/
// 2.2 函数
void glShaderSource( GLuint shader,
GLsizei count,
const GLchar **string,
const GLint *length);
Parameters
shader
Specifies the handle of the shader object whose source code is to be replaced.
count
Specifies the number of elements in the string and length arrays.
string
Specifies an array of pointers to strings containing the source code to be
loaded into the shader.
length
Specifies an array of string lengths.
Description
glShaderSource sets the source code in shader to the source code in the array of
strings specified by string. Any source code previously stored in the shader
object is completely replaced. The number of strings in the array is specified
by count.
// If length is NULL, each string is assumed to be null terminated.如果长度为
NULL,则假定每个字符串以NULL结尾
If length is a value other than NULL, it points to an array containing a string
length for each of the corresponding elements of string. Each element in the
length array may contain the length of the corresponding string (the null
character is not counted as part of the string length) or a value less than 0 to
indicate that the string is null terminated. The source code strings are not
scanned or parsed at this time; they are simply copied into the specified shader
object.
static int CompileShader(const std::string& source,unsigned int type)
{
unsigned int id = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(id,1,&src,nullptr);
glCompileShader(id);
// TODO: Error handling
int result = 0;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
调用着色器
if (result == GL_FALSE)
{
int len;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &len);
char* msg = (char*)alloca(len * sizeof(char));
glGetShaderInfoLog(id, len, &len, msg);
std::cout << "Failed compile shader " <<
(type == GL_VERTEX_SHADER ? "vertex" : "fragment" )
<< std::endl;
std::cout << msg << std::endl;
glDeleteShader(id);
return 0;
}
return id;
}
static unsigned int CreateShader(const std::string& vertexShader, const
std::string& framentShader)
{
unsigned int program = glCreateProgram();
// 编译
unsigned int vs = CompileShader(vertexShader,GL_VERTEX_SHADER);
unsigned int fs = CompileShader(framentShader,GL_FRAGMENT_SHADER);
// 链接
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
// 删除中间文件,类似于c++的obj文件
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}

调用着色器

// 着色器代码
std::string vertexShader =
"#version 330 core\n"//DLSL版本
"\n"
"layout(location = 0) in vec4 position;\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = position;\n"
"}\n"
;
std::string fragmentShader =
"#version 330 core\n"//DLSL版本
"\n"
"layout(location = 0) out vec4 color;\n"
"\n"
"void main()\n"
错误示范:
好了,但我们今天讲了着色器这一个知识,不想一个视频占用太多时间,我们下节课再做分享。谢
谢!!!
"{\n"
" color = vec4(1.0,0.0,0.0,1.0);\n"// RGBA
"}\n"
;
unsigned int shader = CreateShader(vertexShader,fragmentShader);
glUseProgram(shader);

错误示范:

std::string vertexShader =
"#version 330 core\n"//DLSL版本
"\n"
"layout(location = 0) in vec4 position;\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = position\n"
"}\n"
;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值