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了 ...
随机推荐
- stm32的adc时钟周期,ADC_SampleTime_1Cycles5是多长时间
- 【t048】水流
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 全球气候变暖,小镇A面临水灾.于是你必须买一些泵把水抽走.泵的抽水能力可以认为是无穷大,但你必须把泵放 ...
- kernel build & preempt-rt patch & xenomai
提前准备好 linux 内核源代码,假设是 x86 系统.能够去下载原生内核(Vanilla kernel): wget https://www.kernel.org/pub/linux/kernel ...
- JavaScript、Ajax与jQuery的关系 分类: C1_HTML/JS/JQUERY 2014-07-31 10:15 3388人阅读 评论(0) 收藏
简单总结: 1.JS是一门前端语言. 2.Ajax是一门技术,它提供了异步更新的机制,使用客户端与服务器间交换数据而非整个页面文档,实现页面的局部更新. 3.jQuery是一个框架,它对JS进行了封装 ...
- android,安卓get请求的提交以及我遇到的异常
首先说明 我是安卓4.0以上的版本,这个时候直接用网上的代码会报错的,先赋上网上的普遍代码 String uri = "http://url"; HttpGet httpGet = ...
- USB 3.0规范中译本 第2章 术语及缩略语
本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 本章列出并定义本规范通篇将使用的术语及缩略语. 术语/略缩语 定义 ACK(确认包) 表示积极肯定的握手包. ...
- 微信开发学习日记(五):weiphp开源框架的bug,公众号权限编辑问题
最近在研究weiphp,总体感觉还行,bug据说还挺多. 这不,我就遇到一个比较严重影响使用的.感觉不太应该出现这么严重的bug啊. weiphp的微信公众号等级,权限增加和编辑bug,看不到权限列表 ...
- MySQL建立双向主备复制server配置方法
1.环境描写叙述 serverA(主) 192.85.1.175 serverB(从) 192.85.1.176 Mysql版本号:5.1.61 系统版本号:System OS:ubuntu 10.1 ...
- java-线程-生产者-消费者
概述 在Java中有四种方法支持同步,其中前三个是同步方法,一个是管道方法. wait() / notify()方法 await() / signal()方法 BlockingQueue阻塞队列方法 ...
- Watchdog问题实例分析
1.日志获取 Watchdog相关的问题甚至需要以下所有的日志: logcat 通过adb logcat命令输出Android的一些当前运行日志,可以通过logcat的 -b 参数指定要输出的日志缓冲 ...