【OpenGL】三角形
步骤
- 初始化顶点数组对象VAO
- 分配顶点缓冲对象VBO
- 将顶点数据载入缓冲对象中 glBufferData()
- 链接顶点属性 glVertexAttribPointer(指定了顶点着色器的变量与我们存储在缓冲对象VBO中数据的关系)
顶点数组
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
因为是3D坐标,所以有三个轴(x,y,z),三个轴范围在-1~1之间。这里统一将z设为0,这样三个点的深度为0,所以看起来就是2D平面上的三角形。
顶点缓冲对象VBO
GLuint VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO); //把缓冲绑定到GL_ARRAY_BUFFER上
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //复制顶点数据到内存
glBufferData是一个用来把用户定义数据复制到当前绑定缓冲的函数。它的第一个参数是我们希望把数据复制到上面的缓冲类型:顶点缓冲对象当前绑定到GL_ARRAY_BUFFER目标上。第二个参数指定我们希望传递给缓冲的数据的大小(字节);用一个简单的sizeof计算出顶点数据就行。第三个参数是我们希望发送的真实数据。
第四个参数指定了我们希望显卡如何管理给定的数据。有三种形式:
- GL_STATIC_DRAW:数据不会或几乎不会改变。
- GL_DYNAMIC_DRAW:数据会被改变很多。
- GL_STREAM_DRAW:数据每次绘制时都会改变。
顶点着色器
#version 330 core //版本声明,opengl3.3
layout (location = 0) in vec3 position;
void main()
{
gl_Position = vec4(position.x, position.y, position.z, 1.0);
}
编译
GLuint vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, null);
glCompileShader(vertexShader);
//错误检查
GLint success;
GLchar infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if(!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
像素着色器
#version 330 core
out vec4 color;
void main()
{
color = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
编译
GLuint fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, null);
glCompileShader(fragmentShader);
着色器程序
GLuint shaderProgram;
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if(!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
...
glUseProgram(shaderProgram); //将着色器对象链接到程序
//删除着色器对象
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
VAO
// ..:: 初始化代码 (一次完成 (除非你的物体频繁改变)) :: ..
// 1. 绑定VAO
glBindVertexArray(VAO);
// 2. 把顶点数组复制到缓冲中提供给OpenGL使用
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 3. 设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid * )0);
glEnableVertexAttribArray(0);
//4. 解绑VAO
glBindVertexArray(0);
[...]
// ..:: 绘制代码 (in Game loop) :: ..
// 5. 绘制物体
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
someOpenGLFunctionThatDrawsOurTriangle();
glBindVertexArray(0);
绘制
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
所有代码
#include<iostream>
// Include GLEW
#include <GL/glew.h>
// Include GLFW
#include <glfw3.h>
GLFWwindow* window;
// Function prototypes
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 600;
// Shaders
const GLchar* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
"}\0";
const GLchar* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
// The MAIN function, from here we start the application and run the game loop
int main()
{
// Init GLFW
glfwInit();
// Set all the required options for GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
// Create a GLFWwindow object that we can use for GLFW's functions
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);
glfwMakeContextCurrent(window);
// Set the required callback functions
glfwSetKeyCallback(window, key_callback);
// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
glewExperimental = GL_TRUE;
// Initialize GLEW to setup the OpenGL Function pointers
glewInit();
// Define the viewport dimensions
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
// Build and compile our shader program
// Vertex shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// Check for compile time errors
GLint success;
GLchar infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// Fragment shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// Check for compile time errors
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// Link shaders
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// Check for linking errors
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// Set up vertex data (and buffer(s)) and attribute pointers
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f, // Left
0.5f, -0.5f, 0.0f, // Right
0.0f, 0.5f, 0.0f // Top
};
GLuint VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind
glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs)
// Game loop
while (!glfwWindowShouldClose(window))
{
// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
glfwPollEvents();
// Render
// Clear the colorbuffer
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw our first triangle
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
// Swap the screen buffers
glfwSwapBuffers(window);
}
// Properly de-allocate all resources once they've outlived their purpose
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
// Terminate GLFW, clearing any resources allocated by GLFW.
glfwTerminate();
return 0;
}
// Is called whenever a key is pressed/released via GLFW
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
【OpenGL】三角形的更多相关文章
- OpenGL三角形的双面不同颜色的绘制
对于一个三角形,我要给它正反面不同的颜色.然后通过旋转,看出它的效果. 我只想到了2种方法,下面我来写一下这两种方法. 第一种方法,通过角度的判断重设glColor3f的参数(这种方法局限性很大,不推 ...
- NeHe OpenGL教程 第二课:多边形
前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢 ...
- 现代3D图形编程学习-你好,三角形(译)
你好,三角形 传统的入门教程在介绍编程语言的时候,通常从"Hello,World!"的程序开始.这样的程序拥有最简单的能够直接输出"Hello, World!" ...
- 第02课 OpenGL 多边形
你的第一个多边形: 在第一个教程的基础上,我们添加了一个三角形和一个四边形.也许你认为这很简单,但你已经迈出了一大步,要知道任何在OpenGL中绘制的模型都会被分解为这两种简单的图形.读完了这一课,你 ...
- (8)nehe教程2-多边形
参考自: http://www.yakergong.net/nehe/ 你的第一个多边形: 在第一个教程的基础上,我们添加了一个三角形和一个四边形.也许你认为这很简单,但你已经迈出了一大步,要知道任何 ...
- Qt Creator中的3D绘图及动画教程(参照NeHe)
Qt Creator中的3D绘图及动画教程(参照NeHe) http://blog.csdn.net/cly116/article/details/47184729 刚刚学习了Qt Creator,发 ...
- [Modern OpenGL系列(三)]用OpenGL绘制一个三角形
本文已同步发表在CSDN:http://blog.csdn.net/wenxin2011/article/details/51347008 在上一篇文章中已经介绍了OpenGL窗口的创建.本文接着说如 ...
- OpenGL ES 3.0 点,线,三角形绘制形式总结
OpenGL ES 3.0 顶点 -1, 1, 0, -0.5f, 0, 0, 0, -1, 0, -1, 0, 0, 0.5f, 0, 0, 1, -1, ...
- openGl超级宝典学习笔记 (1)第一个三角形
执行效果 代码及解析: // // Triangle.cpp // Triangle // // Created by fengsser on 15/6/20. // Copyright (c) 20 ...
- Android OpenGL ES(十)绘制三角形Triangle .
三角形为OpenGL ES支持的面,同样创建一个DrawTriangle Activity,定义6个顶点使用三种不同模式来绘制三角形: float vertexArray[] = { -0.8f, - ...
随机推荐
- <转载> nginx服务器安装及配置文件详解 https://segmentfault.com/a/1190000002797601
nginx在工作中已经有好几个环境在使用了,每次都是重新去网上扒博客,各种编译配置,今天自己也整理一份安装文档和nginx.conf配置选项的说明,留作以后参考.像负载均衡配置(包括健康检查).缓存( ...
- windows 运行hadoop的WordCount报nativeio.NativeIO$Windows.createDirectoryWithMode0(Ljava/lang/String;I)
window eclipse连接hadoop集群,本地运行wordcount,报以下错误,尝试网络上的方法无果,如:换64JDK,添加hadoop_home,path,以及在hadoop\bin和c: ...
- 机器学习进阶-svm支持向量机
支持向量机需要解决的问题:找出一条最好的决策边界将两种类型的点进行分开 这个时候我们需要考虑一个问题,在找到一条直线将两种点分开时,是否具有其他的约束条件,这里我们在满足找到一条决策边界时,同时使得距 ...
- win7下iis的配置问题
开始asp的学习时,首先得配置iis服务,中途遇到各种问题也谷歌了不少,但是答案都很凌乱,折腾了两天才彻底解决这个问题.下面是我坎坷的配置过程,希望对你有所帮助: 第一步:打开Internet信息服务 ...
- 飞利浦 PHILIPS 电动牙刷HX6730 拆解
今日,一直比较喜欢用的电动牙刷,飞利浦HX6730坏掉了,初步感觉考虑飞利浦的保修,但是发现发票找不到了.飞利浦的客服也说,电动牙刷的两年保修依据分别是:1.发票开据日期:2.在无发票的情况下,看底部 ...
- 尚硅谷springboot学习2-微服务
2014年,martin flowler发表关于微服务的博客 微服务是一种架构风格:一个应用应该是一组小型服务:可以通过HTTP的方式进行互通: 单体应用:ALL IN ONE 微服务:每一个功能元素 ...
- js判断对象
一般学java的小伙伴,刚开始写js时如果遇到要判断一个字符串是否不为空,往往会这样写 if(str != undefined && str != null && st ...
- C语言复习:编译
C接口的封装和设计专题 Win32环境下动态链接库(DLL)编程原理 比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作.其中可能存在一些模块的 ...
- 1.Zabbix配置[仅环境搭建]
Zabbix配置分为两部分1.Zabbix服务端的配置 安装Zabbix源: [root@c71 ~]# rpm -ivh https://mirrors.aliyun.com/zabbix/zabb ...
- Oracle数据文件迁移到裸设备
本文主要描述如何将Oracle表空间的文件系统形式的数据文件迁移到LV裸设备上. 前提条件 1.oracle运行正常. 2.已使用LVM命令规划好LV文件.如/dev/vgoracle/lvdatat ...