OpenGL(二十四) VAO、VBO和着色器使用示例
#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
#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;
}
//使用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;
}
}
OpenGL(二十四) VAO、VBO和着色器使用示例的更多相关文章
- Unity3D学习笔记(三十四):Shader着色器(1)
一.GPU:图形处理器,Graphics Processing Unit 显卡的处理器就是图形处理器.与CPU类似. GPU和CPU的区别? 1.CPU主要是为了串行指令设计,GPU则是为了大规模 ...
- JMeter学习(二十四)HTTP属性管理器HTTP Cookie Manager、HTTP Request Defaults(转载)
转载自 http://www.cnblogs.com/yangxia-test Test Plan的配置元件中有一些和HTTP属性相关的元件:HTTP Cache Manager.HTTP Autho ...
- Bootstrap<基础二十四> 缩略图
Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 ...
- 二十四、Struts2中的UI标签
二十四.Struts2中的UI标签 Struts2中UI标签的优势: 数据回显 页面布局和排版(Freemark),struts2提供了一些常用的排版(主题:xhtml默认 simple ajax) ...
- WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的?
原文:WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的? 服务端只有抛出FaultException异常才能被正常地序列化成Fault消息,并实现向客户 ...
- VMware vSphere 服务器虚拟化之二十四 桌面虚拟化之手动池管理物理机
VMware vSphere 服务器虚拟化之二十四 桌面虚拟化之手动池管理物理机 VMwareView手动池可以管理物理计算机 说明: 环境基于实验二十三 1.准备一台Windows 7的物理计算机名 ...
- Bootstrap入门(二十四)data属性
Bootstrap入门(二十四)data属性 你可以仅仅通过 data 属性 API 就能使用所有的 Bootstrap 插件,无需写一行 JavaScript 代码.这是 Bootstrap 中的一 ...
- 3360: [Usaco2004 Jan]算二十四
3360: [Usaco2004 Jan]算二十四 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 6 Solved: 6[Submit][Statu ...
- JAVA之旅(二十四)——I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习
JAVA之旅(二十四)--I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习 JAVA之旅林林总总也是写了二十多篇了,我们今天终于是接触到了I/O了 ...
随机推荐
- 0、驱动及应用小技巧、uboot指令及环境变量配置、linux常用命令
(内核make menuconfig之后,通过insmod安装的驱动都应该重新make,可能会出现一些莫名的问题) (nor flash/SDRAM/DM9000都受内存控制器控制,需要配置内存控制器 ...
- iOS Universal Static Framework 手动转 XCode Cocoa Framework
不须要又一次创建Project,手动改动project设置. 第一步:在Project文件里,改动type,去掉static 1. 搜索wrapper.framework.static,去掉stati ...
- 2020发布 .NET 5 下一代全平台 .Net 框架
[翻译] 正式宣布 .NET 5 2019-05-07 01:18 by Rwing, 16515 阅读, 79 评论, 收藏, 编辑 原文: Introducing .NET 5 今天,我们宣布 . ...
- 简要分析武汉一起好P2P平台的核心功能
写作背景 加入武汉一起好,正式工作40天了,对公司的核心业务有了更多的了解,想梳理下自己对于P2P平台的认识. 武汉一起好,自己运营的yiqihao.com,是用PHP实现的,同时也帮助若干P2P平台 ...
- 简单的Java多线程的使用
前几天做一个功能.就是在前台更改信息后会自己主动发邮件给其它的人,相关信息已更改,刚開始是直接在更改信息代码后面增加发送邮件的代码,但发现这样会使界面特别慢,而慢的主要原因是因为发送邮件有时会耗时非常 ...
- gcc编译选项--转
gcc提供了大量的警告选项,对代码中可能存在的问题提出警告,通常可以使用-Wall来开启以下警告: -Waddress -Warray-bounds (only with -O2) ...
- MQ选型对比RabbitMQ RocketMQ ActiveMQ
原文:MQ选型对比RabbitMQ RocketMQ ActiveMQ 几种MQ产品说明: ZeroMQ : 扩展性好,开发比较灵活,采用C语言实现,实际上他只是一个socket库的重新封装 ...
- js实现表格配对小游戏
js实现表格配对小游戏 一.总结 一句话总结: 二.js实现表格配对 1.配对游戏案例说明 实例描述: 当用户点击两个相同的图案或字符后配对成功,全部配对成功后游戏获胜 案例008采用了大家常见的小游 ...
- oracle 全部查询和表空间,以及其关系
select * from dba_users; 查看数据库里面全部用户,前提是你是有dba权限的帐号.如sys,system select * from all_users; 查看你能管 ...
- SecureCRT 向多个终端发送相同命令
选中view,选择command windows 在下方出现的窗口中右键,接下来在窗口中输入命令即可,可以一定程度上代替分发脚本,具体请参考https://www.cnblogs.com/tele-s ...