1. 新建一个工程,新建一个头文件Shader.h,内容如下:

#ifndef _SHADER_H_
#define _SHADER_H_ #include <vector>
#include <string>
#include <cstring>
#include <GL/glew.h> class Shader
{
public:
static GLuint createShader(GLenum eShaderType, const std::string &strShaderFile);
static GLuint createShader(GLenum eShaderType, const char* fileName);
static GLuint createProgram(const std::vector<GLuint> &shaderList);
}; #endif


2. 相应的新建一个源文件Shader.h,内容如下:

#include <fstream>
#include <sstream>
#include "shader.h" //从字符串流构造着色器对象
GLuint Shader::createShader(GLenum eShaderType, const std::string &strShaderFile)
{
GLuint shader = glCreateShader(eShaderType);//根据类型创建shader
const char * strFileData = strShaderFile.c_str();
glShaderSource(shader, 1, &strFileData, NULL);//绑定shader字符串
glCompileShader(shader);//编译shader
//检查shader状态
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
GLint infoLogLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
const char * strShaderType = NULL;
switch (eShaderType)
{
case GL_VERTEX_SHADER: strShaderType = "vertex"; break;
case GL_GEOMETRY_SHADER: strShaderType = "geometry"; break;
case GL_FRAGMENT_SHADER: strShaderType = "fragment"; break;
}
fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog);
delete[] strInfoLog;
}
return shader;
} //从文件构造着色器对象
GLuint Shader::createShader(GLenum eShaderType, const char* fileName)
{
std::ifstream infile(fileName);
if (!infile)
{
fprintf(stderr, "Could not open file : %s for reading.", fileName);
return 0;
}
std::stringstream buffer;
buffer << infile.rdbuf();
infile.close();
return Shader::createShader(eShaderType, buffer.str());
} //构造着色器程序对象
GLuint Shader::createProgram(const std::vector<GLuint> &shaderList)
{
GLuint programId = glCreateProgram();//创建program
for (std::vector<GLuint>::size_type iLoop = 0; iLoop < shaderList.size(); iLoop++)
glAttachShader(programId, shaderList[iLoop]);//绑定shader glLinkProgram(programId);//链接shader
//检查program状态
GLint status;
glGetProgramiv(programId, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
GLint infoLogLength;
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLogLength); GLchar *strInfoLog = new GLchar[infoLogLength + 1];
glGetProgramInfoLog(programId, infoLogLength, NULL, strInfoLog);
fprintf(stderr, "Linker failure: %s\n", strInfoLog);
delete[] strInfoLog;
}
for (size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
glDetachShader(programId, shaderList[iLoop]);
return programId;
}



3. Shader.h和Shader.cpp文件主要作用是构建了一个着色器,以下是主要的工程实现代码,新建一个源文件VaoVboTest.cpp,内容如下:

//使用VAO VBO和着色器绘制三角形(现代OpenGL方式)
#include <string>
#include <vector>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "Shader.h" using namespace std; void userInit();
void reshape(int w, int h);
void display(void);
void keyboardAction(unsigned char key, int x, int y); GLuint vboId;//vertex buffer object句柄
GLuint vaoId;//vertext array object句柄
GLuint programId;//shader program 句柄 int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(512, 512);
glutCreateWindow("Triangle demo"); glewInit();
userInit();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc(keyboardAction);
glutMainLoop();
return 0;
} //自定义初始化函数
void userInit()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
//创建顶点数据
const GLfloat vertices[] = {
-0.5f,-0.5f,0.0f,1.0f,
0.5f,0.0f,0.0f,1.0f,
0.0f,0.5f,0.0f,1.0f,
}; //创建vertex array object对象
glGenVertexArrays(1, &vaoId);
glBindVertexArray(vaoId); //创建vertex buffer object对象
glGenBuffers(1, &vboId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); //创建着色器
const std::string vertexStr(
"#version 450\n"
"layout(location=0) in vec4 position;\n"
"void main()\n"
"{gl_Position = position;}\n"
); const std::string fragmentStr(
"#version 450\n"
"out vec4 outputColor;\n"
"void main()\n"
"{outputColor = vec4(1.0f,1.0f,0.0f,1.0f);}\n"
); std::vector<GLuint> idVector;
idVector.push_back(Shader::createShader(GL_VERTEX_SHADER, vertexStr));
idVector.push_back(Shader::createShader(GL_FRAGMENT_SHADER, fragmentStr));
programId = Shader::createProgram(idVector);
} //调整窗口大小回调函数
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
} //绘制回调函数
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(programId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0);
glDisableVertexAttribArray(0);
glutSwapBuffers();
} //键盘按键回调函数
void keyboardAction(unsigned char key, int x, int y)
{
switch (key)
{
case 033: // Escape key
exit(EXIT_SUCCESS);
break;
}
}


不要忘了在链接器->输入->附加依赖项里添加 “glew32.lib”。完成之后编译生成效果:



OpenGL(二十四) VAO、VBO和着色器使用示例的更多相关文章

  1. Unity3D学习笔记(三十四):Shader着色器(1)

    一.GPU:图形处理器,Graphics Processing Unit 显卡的处理器就是图形处理器.与CPU类似.   GPU和CPU的区别? 1.CPU主要是为了串行指令设计,GPU则是为了大规模 ...

  2. JMeter学习(二十四)HTTP属性管理器HTTP Cookie Manager、HTTP Request Defaults(转载)

    转载自 http://www.cnblogs.com/yangxia-test Test Plan的配置元件中有一些和HTTP属性相关的元件:HTTP Cache Manager.HTTP Autho ...

  3. Bootstrap<基础二十四> 缩略图

    Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 ...

  4. 二十四、Struts2中的UI标签

    二十四.Struts2中的UI标签 Struts2中UI标签的优势: 数据回显 页面布局和排版(Freemark),struts2提供了一些常用的排版(主题:xhtml默认 simple ajax) ...

  5. WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的?

    原文:WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的? 服务端只有抛出FaultException异常才能被正常地序列化成Fault消息,并实现向客户 ...

  6. VMware vSphere 服务器虚拟化之二十四 桌面虚拟化之手动池管理物理机

    VMware vSphere 服务器虚拟化之二十四 桌面虚拟化之手动池管理物理机 VMwareView手动池可以管理物理计算机 说明: 环境基于实验二十三 1.准备一台Windows 7的物理计算机名 ...

  7. Bootstrap入门(二十四)data属性

    Bootstrap入门(二十四)data属性 你可以仅仅通过 data 属性 API 就能使用所有的 Bootstrap 插件,无需写一行 JavaScript 代码.这是 Bootstrap 中的一 ...

  8. 3360: [Usaco2004 Jan]算二十四

    3360: [Usaco2004 Jan]算二十四 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6  Solved: 6[Submit][Statu ...

  9. JAVA之旅(二十四)——I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习

    JAVA之旅(二十四)--I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习 JAVA之旅林林总总也是写了二十多篇了,我们今天终于是接触到了I/O了 ...

随机推荐

  1. 结合Wireshark捕获分组深入理解TCP/IP协议栈之DNS协议

    摘要:     本文简单介绍了DNS协议理论知识,给出URL解析步骤,详细讲述了DNS报文各个字段含义,并从Wireshark俘获分组中选取DNS相关报文进行分析. 一.概述 1.1 DNS      ...

  2. [TypeStyle] Style CSS pseudo-classes using TypeStyle with $nest

    TypeStyle is a very thin layer on top of CSS. In this lesson we show how to change styles based on p ...

  3. C++中string类的操作函数。

    相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有没有这样使用起来非常方便的类呢?答案是肯 ...

  4. blob-照片转换与展示

    File转java.sql.Blob(照片)Struts2 public Blob photos(File zp) { Blob photo=null; try { FileInputStream f ...

  5. Android 控件EditText的setOnEditorActionListener方法的理解

    需要注意的是 setOnEditorActionListener这个方法,并不是在我们点击EditText的时候触发,也不是在我们对EditText进行编辑时触发,而是在我们编辑完之后点击软键盘上的回 ...

  6. sysbench压测Oracle

    安装: yum -y install make m4  autoconf automake libtool pkgconfig libaio-devel rpm -Uvh http://dl.fedo ...

  7. java中的subString具体解释及应用

    substring(參数)是java中截取字符串的一个方法 有两种传參方式 一种是public String substring(int beginIndex) 返回一个新的字符串,它是此字符串的一个 ...

  8. Android菜鸟的成长笔记(27)——SurfaceView的使用

    前面有关自定义View中进行了绘图,但View的绘图机制存在如下缺陷: 1.View缺乏双缓冲机制. 2.当程序需要更新View上的图像时,程序必须重绘View上显示的整张图片. 3.新线程无法直接更 ...

  9. [Angular] Subscribing to the valueChanges Observable

    For example we have built a form: form = this.fb.group({ store: this.fb.group({ branch: '', code: '' ...

  10. Cocos2d-x 3.2 Lua演示样例FontTest(字体測试)

    Cocos2d-x 3.2 Lua演示样例FontTest(字体測试) 本篇博客介绍Cocos2d-x 3.2中Lua測试项目中的FontTest样例,主要使用了字体文件来创建我们想要的字体样式: 第 ...