OpenGL自制游戏引擎-着色器

2019-07-09  本文已影响0人  祝你万事顺利

典型的着色器:

着色器的开头总是要声明版本,接着是输入和输出变量、uniform和main函数。着色器入口是main函数。顶点着色器输入变量也叫顶点属性(Vertex Attribute),OpenGL保证至少16个4分量定点可用

#version version_number
in type in_variable_name;
in type in_variable_name;

out type out_variable_name;

uniform type uniform_name;

int main()
{
  // 处理输入并进行一些图形操作
  ...
  // 输出处理过的结果到输出变量
  out_variable_name = weird_stuff_we_processed;
}

重组

vec2 someVec;
vec4 differentVec = someVec.xyxx;
vec3 anotherVec = differentVec.zyw;
vec4 otherVec = someVec.xxxx + anotherVec.yxzy;

输入输出

使用location元数据指定输入变量,layout (location = 0),顶点着色器提供一个额外的layout标识。也可以忽略这个标识符,在OpenGL中使用glGetAttribLocation查询属性位置值。
片段着色器将一个输出一个vec4颜色,

Uniform

Vertex Shader可以接受VAO的数据,也可以接收来自CPU的Uniform的数据。
Uniform是一种从CPU的应用向GPU中的着色器发送数据的方式,uniform是全局的,uniform可以被着色器的任意阶段访问。
在fragmentShader中添加一个uniform类型的数据。

const char* fragmentShaderSource =
"#version 330 core                               \n"
"in vec4 vertexColor; \n"
"uniform vec4 ourColor; \n"
"out vec4 FragColor;                             \n"
"void main(){                                    \n"
"    FragColor =ourColor;}  \n";

glGetUniformLocation获得shaderProgram下某个名称的uniform的location,再使用glUniform4f将目标的localtion的Uniform进行赋值。更新uniform之前必须使用程序(调用glUseProgram),因为他是在当前激活着色器程序中设置uniform的。

        float timeValue = glfwGetTime();
        float greenValue = (sin(timeValue) / 2.0f) + 0.5f;
        int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor"); 
        

        //glBindVertexArray(VAO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
        glUseProgram(shaderProgram);

        glUniform4f(vertexColorLocation, 0, greenValue, 0, 1.0f);
        //glDrawArrays(GL_TRIANGLES, 0, 6);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
上一篇 下一篇

猜你喜欢

热点阅读