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:\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”。完成之后编译生成效果:



  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值