1
0
mirror of https://github.com/LearnOpenGL-CN/LearnOpenGL-CN.git synced 2025-08-23 20:55:27 +08:00

-第一版翻译完成

This commit is contained in:
wuweizhou
2015-06-23 19:56:27 +08:00
parent 0f9ab0b747
commit 8872b252ea

View File

@@ -162,3 +162,139 @@ GLSL跟一般的编程语言一样定义了一些常用的数据类型
如果运行正常的话我们能看到一个绿色到黑色黑色到绿色变化的三角形 如果运行正常的话我们能看到一个绿色到黑色黑色到绿色变化的三角形
可以查看完整的代码[实例](http://learnopengl.com/code_viewer.php?code=getting-started/shaders-interpolated) 可以查看完整的代码[实例](http://learnopengl.com/code_viewer.php?code=getting-started/shaders-interpolated)
**着色器程序管理程序**
编写编译和管理着色器程序是非常繁重的工作为了减轻这个工作量我们自己定义一个着色器程序管理器负责读取着色器程序文件然后编译他们链接并检查着色器程序有无错误发生这也可以让我们把已经学到的知识封装到抽象的对象里
我们首先顶一个着色器程序的头文件如下
#ifndef SHADER_H
#define SHADER_H
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;
#include <GL/glew.h>; // Include glew to get all the required
OpenGL headers
class Shader
{
public:
// The program ID
GLuint Program;
// Constructor reads and builds the shader
Shader(const GLchar* vertexSourcePath, const GLchar*fragmentSourcePath);
// Use the program
void Use();
};
#endif
着色器程序类包含一个着色器程序ID有一个接受顶点和片段程序的接口这个两个路径就是普通的文本文件就可以了。
Use函数是一个工具属性的函数主要是控制当前着色器程序是否激活。
读取着色器程序文件
Shader(const GLchar* vertexPath, const GLchar* fragmentPath)
{
// 1. Retrieve the vertex/fragment source code from
filePath
std::string vertexCode;
std::string fragmentCode;
try
{
// Open files
std::ifstream vShaderFile(vertexPath);
std::ifstream fShaderFile(fragmentPath);
std::stringstream vShaderStream, fShaderStream;
// Read files buffer contents into streams
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf();
// close file handlers
vShaderFile.close();
fShaderFile.close();
// Convert stream into GLchar array
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
}
catch(std::exception e)
{
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" <<
std::endl;
}
接下来编译和链接这些程序同时收集一些编译和链接的错误来帮助我们调试
// 2. Compile shaders
GLuint vertex, fragment;
GLint success;
GLchar infoLog[512];
// Vertex Shader
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
// Print compile errors if any
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
if(!success)
{
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n"
<< infoLog << std::endl;
};
// Similiar for Fragment Shader
[...]
// Shader Program
this->Program = glCreateProgram();
glAttachShader(this->Program, vertex);
glAttachShader(this->Program, fragment);
glLinkProgram(this->Program);
// Print linking errors if any
glGetProgramiv(this->Program, GL_LINK_STATUS, &success);
if(!success)
{
glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" <<
infoLog << std::endl;
}
// Delete the shaders as theyre linked into our program now
and no longer necessery
glDeleteShader(vertex);
glDeleteShader(fragment);
最后来实现一个use函数
void Use() { glUseProgram(this->Program); }
接下来是一个使用这个简单实例:
Shader ourShader("path/to/shaders/shader.vs", "path/to/shaders/shader.frag");
...
while(...)
{
ourShader.Use();
glUniform1f(glGetUniformLocation(ourShader.Program, "
someUniform"), 1.0f);
DrawStuff();
}
上面我们已经把顶点着色器和片段着色器代码分别放在shader.vs和shader.frag里面了这些文件的名字和后缀名都可以随意命名的只要符合文件名规范就好。
完整的代码实例:
[使用的实例](http://learnopengl.com/code_viewer.php?code=getting-started/shaders-using-object)
[着色器类](http://learnopengl.com/code_viewer.php?type=header&code=shader)
[顶点着色器代码](http://learnopengl.com/code_viewer.php?type=vertex&code=getting-started/basic)
[片段着色器代码](http://learnopengl.com/code_viewer.php?type=fragment&code=getting-started/basic)
**练习题**
1.通过调整的顶点着色器,以使三角形是倒置 [答案](http://learnopengl.com/code_viewer.php?code=getting-started/shaders-exercise1)
2.通过一个常量使得三角在x方向偏移 [答案](http://learnopengl.com/code_viewer.php?code=getting-started/shaders-exercise2)
3.使用in 和out 关键字,把顶点着色器的位置数据作为片段着色器的颜色,然后看看得出的三角形颜色,进一步理解差值的问题,同时可以尝试回答下面的问题:为什么我们三角形左下侧有黑边?:[答案](http://learnopengl.com/code_viewer.php?code=getting-started/shaders-exercise3)