zoukankan      html  css  js  c++  java
  • OpenGL(二十四) VAO、VBO和着色器使用示例


    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:
    %s
    ", 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
    ", 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
    "
    		"layout(location=0) in vec4 position;
    "
    		"void main()
    "
    		"{gl_Position = position;}
    "
    	);
    
    	const std::string fragmentStr(
    		"#version 450
    "
    		"out vec4 outputColor;
    "
    		"void main()
    "
    		"{outputColor = vec4(1.0f,1.0f,0.0f,1.0f);}
    "
    	);
    
    	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”。完成之后编译生成效果:



  • 相关阅读:
    GMM的EM算法
    SQL Server 有关EXCEPT和INTERSECT使用
    nginx.conf 完整的集群配置
    一些建议方案猿简历
    漫游Kafka实战篇clientAPI
    iPhone发展【一】从HelloWorld开始
    SpringMVC+Spring3+Hibernate4开发环境的搭建
    tar.gz文件命名和压缩解压方法
    贪心算法(Greedy Algorithm)最小生成树 克鲁斯卡尔算法(Kruskal&#39;s algorithm)
    微软将彻底改变Windows发布方式
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9411900.html
Copyright © 2011-2022 走看看