您的位置:首页 > 理论基础

计算机图形学——OpenGL渲染基础架构二之着色器的使用

2017-04-13 16:21 621 查看

计算机图形学——OpenGL渲染基础架构二之着色器的使用

1、使用步骤

1.把着色器写到文本文件中,以便在程序中读取调用shader.vert;shader.fragment
2.用读文件的方式把两个着色器中的代码读到字符串中
3.新建shader对象,判断创建是否成功glCreateShader()
4.将着色器字符串关联到shader对象glShaderSource()
5.编译着色器对象,判断编译是否成功,如果不成功,输出错误日志glCompileShader()
6.创建着色器程序,判断是否创建成功glCreateProgram()
7.关联着色器对象和着色器程序glAttachShader()
8.链接着色器程序,判断链接是否成功glLinkProgram()
9.使用着色器程序 即让着色器在主程序运行过程中发挥作用glUseProgram()

2、使用实例:



Shade.h写成通用的使用的时候直接导入头文件就行
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <string>
#include <glew.h>
GLuint loadShaders(const GLchar *vertex_shader_file, const GLchar *fragment_shader_file) {

GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

std::string vertexShaderCode;
std::ifstream vertexShaderStream(vertex_shader_file, std::ios::in);
if (vertexShaderStream.is_open()) {
std::string line = "";
while (getline(vertexShaderStream, line))
vertexShaderCode += "\n" + line;
vertexShaderStream.close();
} else {
std::cerr << "Failed to open vertex shader source file." << vertex_shader_file << std::endl;
return 0;
}

std::string fragmentShaderCode;
std::ifstream fragmentShaderStream(fragment_shader_file, std::ios::in);
if (fragmentShaderStream.is_open()) {
std::string line = "";
while (getline(fragmentShaderStream, line))
fragmentShaderCode += "\n" + line;
fragmentShaderStream.close();
} else {
std::cerr << "Failed to open fragment shader source file." << std::endl;
return 0;
}

GLint result = GL_FALSE;
GLint infoLogLength;

const GLchar *vertexSource = vertexShaderCode.c_str();
glShaderSource(vertexShaderID, 1, &vertexSource, nullptr);
glCompileShader(vertexShaderID);

glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &result);
glGetShaderiv(vertexShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 0) {
std::cout << "VertexShader Error Message:" << std::endl;
GLchar *vertexShaderErrorMessage = new GLchar[infoLogLength + 1];
glGetShaderInfoLog(vertexShaderID, infoLogLength, nullptr, vertexShaderErrorMessage);
std::cout << vertexShaderErrorMessage << std::endl;
delete [] vertexShaderErrorMessage;
}

if (!result) {
std::cerr << "Failed to compile vertex shader." << std::endl;
return 0;
}

const GLchar *fragmentSource = fragmentShaderCode.c_str();
glShaderSource(fragmentShaderID, 1, &fragmentSource, nullptr);
glCompileShader(fragmentShaderID);

glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &result);
glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 0) {
std::cout << "FragmentShader Error Message:" << std::endl;
GLchar *fragmentShaderErrorMessage = new GLchar[infoLogLength + 1];
glGetShaderInfoLog(fragmentShaderID, infoLogLength, nullptr, fragmentShaderErrorMessage);
std::cout << fragmentShaderErrorMessage << std::endl;
delete [] fragmentShaderErrorMessage;
}

if (!result) {
std::cerr << "Failed to compile fragment shader." << std::endl;
return 0;
}

GLuint programID = glCreateProgram();
glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID);
glLinkProgram(programID);

glGetProgramiv(programID, GL_LINK_STATUS, &result);
glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 0) {
std::cout << "Program Error Message:" << std::endl;
GLchar *programErrorMessage = new GLchar[infoLogLength + 1];
glGetProgramInfoLog(programID, infoLogLength, nullptr, programErrorMessage);
std::cout << programErrorMessage << std::endl;
delete [] programErrorMessage;
}

if (!result) {
std::cerr << "Failed to link program." << std::endl;
return 0;
}

glDetachShader(programID, vertexShaderID);
glDetachShader(programID, fragmentShaderID);

glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);

return programID;
}
// 包含着色器加载库
#include "shader.h"
#include <GL/glut.h>
void draw(){
//生成一个VAO
GLuint VertexArrayID;
glGenVertexArrays(1,&VertexArrayID);
glBindVertexArray(VertexArrayID);
//顶点信息
float positionData[]= {  
    -0.6f, -0.6f, 0.0f,  
    0.6f, -0.6f, 0.0f,  
    0.6f, 0.6f, 0.0f };  
GLuint vertexbuffer;

// Generate 1 buffer,put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer);
// The followingcommands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
// Give our verticesto OpenGL.
glBufferData(GL_ARRAY_BUFFER,sizeof(positionData), positionData, GL_STATIC_DRAW);

//颜色信息
float colorData[] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f };
// This will identifyour vertex buffer
GLuint colorbuffer;

// Generate 1 buffer,put the resulting identifier in vertexbuffer
glGenBuffers(1,&colorbuffer);
// The followingcommands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER,colorbuffer);

// Give our verticesto OpenGL.
glBufferData(GL_ARRAY_BUFFER,sizeof(colorData), colorData, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
glVertexAttribPointer(
0,                  // attribute 0. No particularreason for 0, but must match the layout in the shader.
3,                  // size
GL_FLOAT,           // type
GL_FALSE,          // normalized?
0,                  // stride
(void*)0            // array buffer offset
);
// 2cond attributebuffer : vertices
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER,colorbuffer);
glVertexAttribPointer(
1,                  // attribute 1. No particularreason for 0, but must match the layout in the shader.
3,                  // size
GL_FLOAT,           // type
GL_FALSE,           // normalized?
0,                  // stride
(void*)0            // array buffer offset
);
glDrawArrays(GL_TRIANGLES,0, 3 );
}
void mydisplay(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清空颜色和深度缓冲
glEnable(GL_DEPTH_TEST);
// 创建透视效果视图
glMatrixMode(GL_PROJECTION);//对投影矩阵操作
glLoadIdentity();//将坐标原点移到中心
gluPerspective(90.0f, 1.0f, 1.0f, 20.0f);//设置透视投影矩阵
glMatrixMode(GL_MODELVIEW);//对模型视景矩阵操作
glLoadIdentity();
gluLookAt(0.0, 5.0, -10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);//视点转换
GLuint programID = loadShaders("F:\\大三下课程\\Computer Graphic\\Shader\\ColorArrays.vertexshader", "F:\\大三下课程\\Computer Graphic\\Shader\\ColorArrays.fragmentshader");
glUseProgram(programID);
draw();
glFlush();
}
int main(int argc, char *argv[])
{
glewInit();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(600, 600);
glutCreateWindow("HelloShader");
glewInit();
glutDisplayFunc(&mydisplay);
glutMainLoop();
return 0;
}
   顶点着色器文件:
#version 400
layout(location = 0)in vec3 VertexPosition;
layout(location = 1)in vec3 VertexColor;
out vec3 Color;
void main()
{
Color = VertexColor;
gl_Position = vec4(VertexPosition,1.0); }

片段着色器:
#version 400
in vec3 Color;
out vec4 FragColor;
void main() {
FragColor = vec4(Color, 1.0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opengl 着色器