OpenGL(二十四) VAO、VBO和着色器使用示例
2016-12-06 23:33
447 查看
1. 新建一个工程,新建一个头文件Shader.h,内容如下:
2. 相应的新建一个源文件Shader.h,内容如下:
3. Shader.h和Shader.cpp文件主要作用是构建了一个着色器,以下是主要的工程实现代码,新建一个源文件VaoVboTest.cpp,内容如下:
不要忘了在链接器->输入->附加依赖项里添加 “glew32.lib”。完成之后编译生成效果:
#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”。完成之后编译生成效果:
相关文章推荐
- VB通过windows API实现窗口透明,部分透明,CreateRectRgn,CombineRgn
- VBS入门基础
- VBA:合并同一文件夹下的所有表
- 命令行创建虚拟机,无桌面运行virtualbox
- Excel VBA
- VC实现一个库,并用VB(Visual Basic)来调用的方法,包括传递数组的方法
- EXCEL vba 实现通过超链接跳转到隐藏工作表 回到目录隐藏打开工作表
- VBA:按照表中的一列的名称拆分出独立的表
- PS 制作.ICO 图标(VB6.0)
- 【OA】EXCEL常用VBA总结
- ArcGIS中的VBA修复
- excel查看VBA代码快捷键
- 利用EXCEL批量提取超链接
- 杀死指定进程名称的小VBS
- 通过vbs修改以点结尾的文件的属性为隐藏
- 查询电脑开关机时间的vbs代码
- vbs枚举进程 vbs列出进程的详细列表
- VBA_Excel_教程:字典类型
- 最近开发的基于Excel的考试系统---VBA
- VBA_Excel_教程:单元格颜色