OpenGL学习(4)
来源:互联网 发布:淘宝质量叫高的女装店 编辑:程序博客网 时间:2024/05/21 06:42
给图形上色
对于图形的上色有两种基本的方法:直接使用glColor~() 系列的函数 和 使用shader脚本。下文将简要介绍下这两种方法。
1.直接使用glColor~() 系列的函数
方法:在相应的坐标顶点使用该函数,如下程序所示
<span style="white-space:pre"></span>glBegin(GL_TRIANGLES);glColor3f(1.0f,0.0f,0.0f);//set the redglVertex3f(-1.0f,-1.0f,0.0f);glColor3f(0.0f,1.0f,0.0f);//set the greenglVertex3f(1.0f,-1.0f,0.0f);glColor3f(0.0f,0.0f,1.0f);//set the blueglVertex3f(0.0f,1.0f,0.0f);glEnd();
需要说明的是,每一个glColor~() 函数都是从开始使用处生效,在出现另一个glColor~() 函数时失效
调试运行结果:如图1所示
图1
小结:
这种方法在程序理解和写法上比较简单,但传输效率比较低;在多顶点的情况下,程序比较冗长;
2.使用shader脚本
方法:通过将颜色写在frangment(片元)脚本上,来实现图形着色
首先,编写读取shader脚本的程序。该程序包括如下:
(1)利用glCreateShader() 函数创建 vertex shader (顶点着色器)和 fragment shader(片元着色器)
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
(2)利用getline() 函数读取 vertex shader 和 fragment shader
<span style="white-space:pre"></span>std::string VertexShaderCode;std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);if(VertexShaderStream.is_open()){std::string Line = "";while(getline(VertexShaderStream, Line))VertexShaderCode += "\n" + Line;VertexShaderStream.close();}else//Open vertex shader source code failed{printf("Failed to open %s. Are you in the right directory ? \n", vertex_file_path);return ;}std::string FragmentShaderCode;std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);if(FragmentShaderStream.is_open()){std::string Line = "";while(getline(FragmentShaderStream, Line))FragmentShaderCode += "\n" + Line;FragmentShaderStream.close();}else{printf("Failed to open %s. Are you in the right directory ? \n", fragment_file_path);return ;}
<span style="white-space:pre"></span>GLint Result = GL_FALSE;int InfoLogLength;printf("Compiling shader : %s\n", vertex_file_path);char const * VertexSourcePointer = VertexShaderCode.c_str();glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);glCompileShader(VertexShaderID);glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); if ( InfoLogLength > 0 ){std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);printf("%s\n", &VertexShaderErrorMessage[0]);}
(3-2)同样,使用glCompileShader() 函数编译fragment shader,并根据其日志判断是否存在代码语法错误
<span style="white-space:pre"></span>printf("Compiling shader : %s\n", fragment_file_path);char const * FragmentSourcePointer = FragmentShaderCode.c_str();glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);glCompileShader(FragmentShaderID);glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);if ( InfoLogLength > 0 ){std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);printf("%s\n", &FragmentShaderErrorMessage[0]);}
<span style="white-space:pre"></span>printf("Linking program\n");m_uiProgramID = glCreateProgram();glAttachShader(m_uiProgramID, VertexShaderID);glAttachShader(m_uiProgramID, FragmentShaderID);glLinkProgram(m_uiProgramID);
(5)再次检查脚本,并释放相关shader
<span style="white-space:pre"></span>glGetProgramiv(m_uiProgramID, GL_LINK_STATUS, &Result);glGetProgramiv(m_uiProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);if ( InfoLogLength > 0 ){std::vector<char> ProgramErrorMessage(InfoLogLength+1);glGetProgramInfoLog(m_uiProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);printf("%s\n", &ProgramErrorMessage[0]);}glDetachShader(m_uiProgramID, VertexShaderID);glDetachShader(m_uiProgramID, FragmentShaderID);//Delete the vertex and fragment shaderglDeleteShader(VertexShaderID);glDeleteShader(FragmentShaderID);
(1)关于vertex shader:基本包括,OpenGL版本声、定义存储顶点变量、传输顶点数据
#version 330 corelayout(location = 0) in vec3 vertexPosition_modelspace;void main(){gl_Position = vec4(vertexPosition_modelspace,1);}
(2)关于fragment shader:基本包括,OpenGL版本声明、定义存储颜色变量、设定颜色数据
#version 330 coreout vec3 color;void main(){color = vec3(1,0,0);}
glUseProgram(m_uiProgramID);
运行调试结果:如图2所示
图2
小结:
使用shader来进行着色,充分地利用GPU进行上色,极大地提高了编码的灵活性;但是在程序的理解上比较难,写法上也比较繁琐;需要说的是,对于读取shader的程序只要在一组shader(包括vertex shader 和 fragment shader)中,只要调用一次。
0 0
- OpenGL学习(4)
- Android的OpenGL学习笔记(4)
- openGL学习笔记4(动画)
- OpenGL学习4
- opengl学习笔记(4)
- OpenGL学习记录4
- openGL学习笔记4
- OpenGL学习(一)
- opengl学习(一)
- opengl学习(二)
- OpenGL 学习(二)
- Opengl学习(一)
- openGL学习(1)
- OpenGL学习(hello)
- OPENGL学习(一)
- OpenGL学习(1)
- OpenGL学习(2)
- OpenGL学习(3)
- struts2学习笔记
- JAVASCRIPT - AJAX基础知识
- StrongOD的ShowBar窗口简要使用说明
- Abstract(抽象)可以修饰类、方法 http://www.cnblogs.com/suneryong/p/3571362.html
- (gitgutter)第一次的Github与sublime text
- OpenGL学习(4)
- vector模板的用法
- OpenGL入门学习(十)
- POJ 2528 Mayor's posters (线段树+离散化)
- Android 日期信息及其格式化
- Tornado开发技巧
- 4298: [ONTAK2015]Bajtocja 启发式合并 hash
- 贝叶斯学派与频率学派的不同
- hdu3068最长回文 后缀数组TLE版本23333