您的位置:首页 > 运维架构

OpenGL 入门基础教程 —— 在第一个窗口绘制一个三角形

2017-06-05 10:07 791 查看
首先了解缓冲区对象相关:

1:缓冲区对象的定义

GLuint vertexbuffer;  //定义了一个unsigned int类型的正整形缓冲区对象

2:创建缓冲区对象—创建

void glGenBuffers(GLsizei n, GLuint *buffers);
//在buffers数组中返回当前n个未使用的名称,表示缓冲区对象

3:激活缓冲区对象—绑定

void glBindBuffer(GLenum target, GLuint buffer); //指定当前活动缓冲区的对象

4:用数据分配和初始化缓冲区对象—填充

void glBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
//target:可以是GL_ARRAY_BUFFER()(顶点数据)或GL_ELEMENT_ARRAY_BUFFER(索引数据)
//size:存储相关数据所需的内存容量
//data:用于初始化缓冲区对象,可以是一个指向客户区内存的指针,也可以是NULL
//usage:数据在分配之后如何进行读写,如GL_STREAM_READ,GL_STREAM_DRAW,GL_STREAM_COPY


画形状的流程:

1:启用顶点数组/关闭Disable

glEnableVertexAttribArray(0); //参数为顶点数组的索引值
索引值:index必须是一个介于0到GL_MAX_VERTEX_ATTRIBS-1之间的值。

2:指定了渲染时索引值为 index 的顶点属性数组的数据格式和位置—配置

glVertexAttribPointer(
0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
3,                  // size
GL_FLOAT,           // type
GL_FALSE,           // normalized?
0,                  // stride
(void*)0            // array buffer offset
);


void glVertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,const GLvoid * pointer);


参数:

index:指定要修改的顶点属性的索引值

size:指定每个顶点属性的组件数量。必须为1、2、3或者4。初始值为4。(如position是由3个(x,y,z)组成,而颜色是4个(r,g,b,a))

type:指定数组中每个组件的数据类型。可用的符号常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT,GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值为GL_FLOAT。

normalized:指定当被访问时,固定点数据值是否应该被归一化(GL_TRUE)或者直接转换为固定点值(GL_FALSE)。

stride:指定连续顶点属性之间的偏移量。如果为0,那么顶点属性会被理解为:它们是紧密排列在一起的。初始值为0。

pointer:指定第一个组件在数组的第一个顶点属性中的偏移量。该数组与GL_ARRAY_BUFFER绑定,储存于缓冲区中。初始值为0;

3:根据顶点数组中的坐标数据和指定的模式,进行绘制

glDrawArrays(GL_TRIANGLES, 0, 3);


void glDrawArrays (GLenum mode, GLint first, GLsizei count);
参数说明:

mode,绘制方式,OpenGL2.0以后提供以下参数:GL_POINTS、GL_LINES、GL_LINE_LOOP、GL_LINE_STRIP、GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN。

first,从数组缓存中的哪一位开始绘制,一般为0。

count,数组中顶点的数量。

GL_TRIANGLES - 这个参数意味着OpenGL使用三个顶点来组成图形。所以,在开始的三个顶点,将用顶点1,顶点2,顶点3来组成一个三角形。完成后,在用下一组的三个顶点(顶点4,5,6)来组成三角形,直到数组结束,注意多个三角形之间不连接。且顶点在设置的过程中一定要注意需要成三角形,别再一条直线上了~

GL_TRIANGLE_STRIP - OpenGL的使用将最开始的两个顶点出发,然后遍历每个顶点,这些顶点将使用前2个顶点一起组成一个三角形。

GL_TRIANGLE_FAN - 在跳过开始的2个顶点,然后遍历每个顶点,让OpenGL将这些顶点于它们前一个,以及数组的第一个顶点一起组成一个三角形

// Include standard headers
#include <stdio.h>
#include <stdlib.h>

// Include GLEW
#include <GL/glew.h>

// Include GLFW
#include <glfw3.h>
GLFWwindow* window;

// Include GLM
#include <glm/glm.hpp>
using namespace glm;

#include <common/shader.hpp>

int main( void )
{
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
getchar();
return -1;
}

glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

// Open a window and create its OpenGL context
window = glfwCreateWindow( 1024, 768, "Tutorial 02 - Red triangle", NULL, NULL);
if( window == NULL ){
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);

// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
getchar();
glfwTerminate();
return -1;
}

// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

//创建VAO数组,并将其设定为当前对象
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);

// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );

//三角形的顶点数组
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f,  0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
0.0f,  0.0f, 0.0f
};

//STRIP形式的顶点数组
static const GLfloat g_vertex_buffer_data_square[] = {
0.0f,1.0f, 0.0f,
0.0f,-1.0f, 0.0f,
1.0f,0.0f, 0.0f,
-1.0f,0.0f, 0.0f,

};

//通过缓冲(buffer)将三角形顶点数据传给OpenGL
GLuint vertexbuffer;              //首先定义一个GLunit类型的顶点缓冲区对象
glGenBuffers(1, &vertexbuffer);   //将该顶点缓冲置为当前对象
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); //激活缓冲区对象
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); 	//用数据初始化缓冲区对象

do{

// 用之前设定的颜色清除屏幕
glClear( GL_COLOR_BUFFER_BIT );

// 使用之前定义的着色器
glUseProgram(programID);

// 启用顶点数组
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(      //缓冲区的配置
0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
3,                  // 这里注意是顶点属性的个数
GL_FLOAT,           // type
GL_FALSE,           // normalized?
0,                  // stride
(void*)0            // array buffer offset
);

// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 6); // 3 indices starting at 0 -> 1 triangle

glDisableVertexAttribArray(0);

// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();

} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );

// Cleanup VBO
glDeleteBuffers(1, &vertexbuffer);
glDeleteVertexArrays(1, &VertexArrayID);

glDeleteProgram(programID);

// Close OpenGL window and terminate GLFW
glfwTerminate();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  三角形 OpenGL 形状 C++ gl
相关文章推荐