opengl 渲染四边形的方式

opengl 渲染四边形的方式

GL_TRIANGLE_STRIP绘制三角形方式很多时候令人疑惑,在这里对其运作机理进行解释。

一般情况下有三种绘制一系列三角形的方式,分别是GL_TRIANGLESGL_TRIANGLE_STRIPGL_TRIANGLE_FAN

如下图所示:

opengl 渲染四边形的方式_第1张图片

它的渲染根据顶点数据组成方式不同分为两种方式:

一、它的渲染可以通过glGenBuffers,glBindBuffer,glBufferData个来完成。当需要动态修改顶点数据时,通过调用glBufferSubData来完成。

#include "glew.h"
#include <glfw3.h>
#include "common/loadShader.h"
#include "glm.hpp"
#include "ext.hpp"

int main(void)
{
	GLFWwindow* window;

	/* Initialize the library */
	if (!glfwInit())
		return -1;

	/* Create a windowed mode window and its OpenGL context */
	window = glfwCreateWindow(480, 480, "Hello World", NULL, NULL);
	if (!window)
	{
		glfwTerminate();
		return -1;
	}

	/* Make the window's context current */
	glfwMakeContextCurrent(window);

	// Needed in core profile
	if( glewInit() != GLEW_OK)
	{
		glfwTerminate();
		return -1;
	}

	

	float g_vertex_buffer_data[] =
	{
		-1,  1, 1,
		-1, -1, 1,
		 1,  1, 1,
		 1, -1, 1
		 
	};

	float g_uv_buffer_data[] =
	{
		0, 1,
		0, 0,
		1, 1,
		1, 0		
	};

	float g_color_buffer_data[] = 
	{
		1, 1, 1, 1,
		1, 1, 1, 1,
		1, 1, 1, 1,
		1, 1, 1, 1
	};

	GLuint Texture = loadBMP_custom("./resource/uvtemplate.bmp");

	//This will identify our vertex buffer
	GLuint vertexbuffer;	
	//Generate 1 buffer,put the resulting identifier in vertexbuffer
	glGenBuffers(1,&vertexbuffer);
	//The following commands will talk about our 'vertexbuffer' buffer
	glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
	//Give our vertices to OpenGL.
	glBufferData(GL_ARRAY_BUFFER,sizeof(g_vertex_buffer_data),g_vertex_buffer_data,GL_STATIC_DRAW);


	
	
	GLuint uvbuffer;
	glGenBuffers(1,&uvbuffer);
	glBindBuffer(GL_ARRAY_BUFFER,uvbuffer);
	glBufferData(GL_ARRAY_BUFFER,sizeof(g_uv_buffer_data),g_uv_buffer_data,GL_STATIC_DRAW);

	GLuint colorbuffer;
	glGenBuffers(1,&colorbuffer);
	glBindBuffer(GL_ARRAY_BUFFER,colorbuffer);
	glBufferData(GL_ARRAY_BUFFER,sizeof(g_color_buffer_data),g_color_buffer_data,GL_STATIC_DRAW);


	GLuint programID = LoadShaders("./shader/vertex.shader","./shader/fragment.shader");
	glUseProgram(programID);
	glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
	/* Loop until the user closes the window */

	// Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit  100 units
	glm::mat4 Projection = glm::ortho(-2.0f, 2.0f, -2.0f, 2.0f, 0.1f, 100.0f);	
	glm::mat4 View = glm::lookAt(
		glm::vec3(0,0,100), // Camera is at (4,3,3), in World Space
		glm::vec3(0,0,0), // and looks at the origin
		glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)		
		);

	
		glm::mat4 Model = glm::mat4(1.0f);
		
		// Our ModelViewProjection : multiplication of our 3 matrices
		glm::mat4 MVP = Projection * View * Model;// Remember, matrix multiplication is the other way around
	
		
	
		// Get a handle for our "MVP" uniform.
		// Only at initialisation time.
		GLuint MatrixID = glGetUniformLocation(programID,"MVP");
	
		// Send our transformation to the currently bound shader,
		// in the "MVP" uniform
		// For each model you render, since the MVP will be different (at least the M part)
		glUniformMatrix4fv(MatrixID,1,GL_FALSE,&MVP[0][0]);

		GLuint TextureID = glGetUniformLocation(programID,"myTextureSampler");
		 
		
	while (!glfwWindowShouldClose(window))
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		
		glActiveTexture(GL_TEXTURE5);
		glBindTexture(GL_TEXTURE_2D,Texture);
		glUniform1i(TextureID, 5);
		

		glEnableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
		//glBufferSubData(GL_ARRAY_BUFFER,0,sizeof(g_vertex_buffer_data),g_vertex_buffer_data);
		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
			);

		

		glEnableVertexAttribArray(1);
		glBindBuffer(GL_ARRAY_BUFFER,uvbuffer);	
		//glBufferSubData(GL_ARRAY_BUFFER,0,sizeof(g_uv_buffer_data),g_uv_buffer_data);
		glVertexAttribPointer(
			1,			// attribute 0. No particular reason for 0, but must match the layout in the shader.
			2,			// size
			GL_FLOAT,	// type
			GL_FALSE,	// normalized?
			0,			// stride
			(void*)0	// array buffer offset
			);


		glEnableVertexAttribArray(2); 
		glBindBuffer(GL_ARRAY_BUFFER,colorbuffer);	
		//glBufferSubData(GL_ARRAY_BUFFER,0,sizeof(g_color_buffer_data),g_color_buffer_data);	
		glVertexAttribPointer(
			2,			// attribute 0. No particular reason for 0, but must match the layout in the shader.
			4,			// size
			GL_FLOAT,	// type
			GL_FALSE,	// normalized?
			0,			// stride
			(void*)0	// array buffer offset
			);


		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LESS);
		glDrawArrays(GL_TRIANGLE_STRIP,0,4);// Starting from vertex 0; 3 vertices total -> 1 triangle
		
		glDisableVertexAttribArray(0);
		glDisableVertexAttribArray(1);
		glDisableVertexAttribArray(2);
		/* Swap front and back buffers */
		glfwSwapBuffers(window);

		/* Poll for and process events */
		glfwPollEvents();
	}

	glfwTerminate();
	return 0;
}

二、 它的渲染可以通过内存数据指针来完成,当需要动态修改顶点数据时,修改内存数据就可以了。

// glfwTest.cpp : 定义控制台应用程序的入口点。
//
#include "glew.h"
#include <glfw3.h>
#include "common/loadShader.h"
#include "glm.hpp"
#include "ext.hpp"

typedef struct {
	float Position[3];
	float Colors[4];
	float TexCoord[2];
} Vertex;

int main(void)
{
	GLFWwindow* window;

	/* Initialize the library */
	if (!glfwInit())
		return -1;

	/* Create a windowed mode window and its OpenGL context */
	window = glfwCreateWindow(320, 320, "Hello World", NULL, NULL);
	if (!window)
	{
		glfwTerminate();
		return -1;
	}

	/* Make the window's context current */
	glfwMakeContextCurrent(window);

	// Needed in core profile
	if( glewInit() != GLEW_OK)
	{
		glfwTerminate();
		return -1;
	}	

	Vertex Vertices[] = {	
	{{-1,  1, 1}, {1, 1, 1, 1}, {0, 1}},
		
	{{-1, -1, 1}, {1, 1, 1, 1}, {0, 0}},

	{{ 1,  1, 1}, {1, 1, 1, 1}, {1, 1}},
		
	{{ 1, -1, 1}, {1, 1, 1, 1}, {1, 0}}	
	
	};

	
	GLuint Texture = loadBMP_custom("./resource/uvtemplate.bmp");	


	GLuint programID = LoadShaders("./shader/vertex.shader","./shader/fragment.shader");
	glUseProgram(programID);
	glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
	/* Loop until the user closes the window */

	// Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit  100 units
	glm::mat4 Projection = glm::ortho(-2.0f, 2.0f, -2.0f, 2.0f, 0.1f, 100.0f);
	//glm::mat4 Projection = glm::perspective(45.0f,4.0f/3.0f,0.1f,100.f);
	glm::mat4 View = glm::lookAt(
		glm::vec3(0,0,100), // Camera is at (4,3,3), in World Space
		glm::vec3(0,0,0), // and looks at the origin
		glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)		
		);

	
		glm::mat4 Model = glm::mat4(1.0f);
		
		// Our ModelViewProjection : multiplication of our 3 matrices
		glm::mat4 MVP = Projection * View * Model;// Remember, matrix multiplication is the other way around
	
		
	
		// Get a handle for our "MVP" uniform.
		// Only at initialisation time.
		GLuint MatrixID = glGetUniformLocation(programID,"MVP");
	
		// Send our transformation to the currently bound shader,
		// in the "MVP" uniform
		// For each model you render, since the MVP will be different (at least the M part)
		glUniformMatrix4fv(MatrixID,1,GL_FALSE,&MVP[0][0]);

		GLuint TextureID = glGetUniformLocation(programID,"myTextureSampler");
		 
		
	while (!glfwWindowShouldClose(window))
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		
		glActiveTexture(GL_TEXTURE5);
		glBindTexture(GL_TEXTURE_2D,Texture);
		glUniform1i(TextureID, 5);
		

#define kQuadSize sizeof(Vertex)
		long offset = (long)Vertices;
		int diff = offsetof( Vertex, Position);

		glEnableVertexAttribArray(0); 	
		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?
			kQuadSize,			// stride
			(void*)(offset + diff)	// array buffer offset
			);

		

		diff = offsetof( Vertex, TexCoord);
		glEnableVertexAttribArray(1); 	
		glVertexAttribPointer(
			1,			// attribute 0. No particular reason for 0, but must match the layout in the shader.
			2,			// size
			GL_FLOAT,	// type
			GL_FALSE,	// normalized?
			kQuadSize,			// stride
			(void*)(offset + diff)	// array buffer offset
			);


		diff = offsetof( Vertex, Colors);		
		glEnableVertexAttribArray(2); 				
		glVertexAttribPointer(
			2,			// attribute 0. No particular reason for 0, but must match the layout in the shader.
			4,			// size
			GL_FLOAT,	// type
			GL_FALSE,	// normalized?
			kQuadSize,			// stride
			(void*)(offset + diff)	// array buffer offset
			);


		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LESS);
		glDrawArrays(GL_TRIANGLE_STRIP,0,4);// Starting from vertex 0; 3 vertices total -> 1 triangle		
		
		glDisableVertexAttribArray(0);
		glDisableVertexAttribArray(1);
		glDisableVertexAttribArray(2);
		/* Swap front and back buffers */
		glfwSwapBuffers(window);

		/* Poll for and process events */
		glfwPollEvents();
	}

	glfwTerminate();
	return 0;
}




你可能感兴趣的:(OpenGL)