opengl 字体渲染

opengl 字体渲染
opengl字体渲染与纹理渲染类似。都是
glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D,Text2DTextureID);
	glUniform1i(Text2DUniformID,0);



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

#include "glm.hpp"
#include "ext.hpp"
GLFWwindow* window;
int main(void)
{
	//GLFWwindow* window;

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

	/* Create a windowed mode window and its OpenGL context */
	window = glfwCreateWindow(800, 600, "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;
	}


	glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

	// Enable depth test
	glEnable(GL_DEPTH_TEST);
	// Accept fragment if it closer to the camera than the former one
	glDepthFunc(GL_LESS); 

	glDisable(GL_CULL_FACE);

	GLuint VertexArrayID;
	glGenVertexArrays(1, &VertexArrayID);
	glBindVertexArray(VertexArrayID);

	// Our vertices. Tree consecutive floats give a 3D vertex; Three consecutive vertices give a triangle.
	// A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices
	std::vector<glm::vec3> vertices;
	std::vector<glm::vec2> uvs;
	std::vector<glm::vec3> normals; // Won't be used at the moment.
	bool res = loadOBJ("./resource/suzanne.obj", vertices, uvs, normals);
	

	std::vector<unsigned short>indices;
	std::vector<glm::vec3> indexed_vertices;
	std::vector<glm::vec2> indexed_uvs;
	std::vector<glm::vec3> indexed_normals;
	indexVBO(vertices,uvs,normals,indices,indexed_vertices,indexed_uvs,indexed_normals);

	//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, indexed_vertices.size() * sizeof(glm::vec3), &indexed_vertices[0], GL_STATIC_DRAW);

	GLuint uvbuffer;
	glGenBuffers(1, &uvbuffer);
	glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
	glBufferData(GL_ARRAY_BUFFER, indexed_uvs.size() * sizeof(glm::vec2), &indexed_uvs[0], GL_STATIC_DRAW);

	GLuint normalbuffer;
	glGenBuffers(1, &normalbuffer);
	glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
	glBufferData(GL_ARRAY_BUFFER, indexed_normals.size() * sizeof(glm::vec3), &indexed_normals[0], GL_STATIC_DRAW);
	GLuint Texture = loadDDS("./resource/uvmap.DDS");//loadBMP_custom("./resource/uvtemplate.bmp");
	
	
	// One color for each vertex. They were generated randomly.	

	GLuint elementbuffer;
	glGenBuffers(1,&elementbuffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elementbuffer);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER,indices.size() * sizeof(unsigned short),&indices[0],GL_STATIC_DRAW);


	GLuint programID = LoadShaders("./shader/vertex.shader","./shader/fragment.shader");
	
	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(-4.0f/3.0f, 4.0f/3.0f, -1.0f, 1.0f, 0.1f, 100.0f);
	
	
		
	
		// Get a handle for our "MVP" uniform.
		// Only at initialisation time.
		GLuint MatrixID = glGetUniformLocation(programID,"MVP");		
		GLuint ViewMatrixID = glGetUniformLocation(programID, "V");
		GLuint ModelMatrixID = glGetUniformLocation(programID, "M");
		GLuint LightID = glGetUniformLocation(programID, "LightPosition_worldspace");
		// 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)
		

		GLuint TextureID = glGetUniformLocation(programID,"myTextureSampler");
		int width,height;	
		glfwGetWindowSize(window,&width,&height);
		float centerX = width;
		float centerY = height;
		centerX /= 2;
		centerY /= 2;		
		//initMatrices();

		initText2D( "./resource/Holstein.DDS" );
		double lastTime = glfwGetTime();
		int nbFrames = 0;
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	while (glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && !glfwWindowShouldClose(window))
	{
		double currentTime = glfwGetTime();
		nbFrames++;
		if (currentTime - lastTime >= 1.0)
		{
			// printf and reset
			//printf("%f ms/frame\n", 1000.0/double(nbFrames));
			printf("fps %d ", nbFrames);
			nbFrames = 0;
			lastTime += 1.0;
		}

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glUseProgram(programID);
		computeMatricesFromInputs();
		glm::mat4 ProjectionMatrix = getProjectionMatrix();
		glm::mat4 ViewMatrix = getViewMatrix();
		glm::mat4 ModelMatrix = glm::mat4(1.0);
		glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;

		// Send our transformation to the currently bound shader, 
		// in the "MVP" uniform
		glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
		glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix[0][0]);
		glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]);

		glm::vec3 lightPos = glm::vec3(4,4,4);
		glUniform3f(LightID, lightPos.x, lightPos.y, lightPos.z);


		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D,Texture);
		glUniform1i(TextureID, 0);
		

		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,			// size
			GL_FLOAT,	// type
			GL_FALSE,	// normalized?
			0,			// stride
			(void*)0	// array buffer offset
			);

		

		glEnableVertexAttribArray(1);
		glBindBuffer(GL_ARRAY_BUFFER,uvbuffer);	
		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, normalbuffer);
		glVertexAttribPointer(
			2,                                // attribute
			3,                                // size
			GL_FLOAT,                         // type
			GL_FALSE,                         // normalized?
			0,                                // stride
			(void*)0                          // array buffer offset
			);


		//glDrawArrays(GL_TRIANGLES, 0, vertices.size() );
		
			
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elementbuffer);
		glDrawElements(GL_TRIANGLES,indices.size(),GL_UNSIGNED_SHORT,(void*)0);
		
		

		
		glDisableVertexAttribArray(0);
		glDisableVertexAttribArray(1);
		glDisableVertexAttribArray(2);
		

		char text[256];
		sprintf(text,"%.2f sec",glfwGetTime());
		printText2D(text,10,500,60);

		/* Swap front and back buffers */
		glfwSwapBuffers(window);

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


	glDeleteBuffers(1, &vertexbuffer);
	glDeleteBuffers(1, &uvbuffer);
	glDeleteBuffers(1, &normalbuffer);
	glDeleteBuffers(1, &elementbuffer);
	glDeleteProgram(programID);
	glDeleteTextures(1, &Texture);
	glDeleteVertexArrays(1, &VertexArrayID);

	// Delete the text's VBO, the shader and the texture
	cleanupText2D();

	glfwTerminate();
	return 0;
}

//text2d.cpp
#include "text2d.h"
#include "loadShader.h"

unsigned int Text2DTextureID;
unsigned int Text2DVertexBufferID;
unsigned int Text2DUVBufferID;
unsigned int Text2DShaderID;
unsigned int Text2DUniformID;


void initText2D(const char * texturePath)
{
	Text2DTextureID = loadDDS(texturePath);
	glGenBuffers(1,&Text2DVertexBufferID);
	glGenBuffers(1,&Text2DUVBufferID);

	Text2DShaderID = LoadShaders("./shader/TextVertex.shader","./shader/TextFragment.shader");

	Text2DUniformID = glGetUniformLocation(Text2DShaderID,"myTextureSampler");
}

void printText2D(const char* text,int x,int y,int size)
{
	unsigned int length = strlen(text);

	std::vector<glm::vec2> vertices;
	std::vector<glm::vec2> UVs;
	for (unsigned int i = 0; i < length ; i++)
	{
		glm::vec2 vertex_up_left	= glm::vec2( x+i*size		,y+size);
		glm::vec2 vertex_up_right	= glm::vec2( x+i*size+size	,y+size);
		glm::vec2 vertex_down_right = glm::vec2( x+i*size+size	,y);
		glm::vec2 vertex_down_left	= glm::vec2( x+i*size		,y);

		vertices.push_back(vertex_up_left);
		vertices.push_back(vertex_down_left);
		vertices.push_back(vertex_up_right);
		
		vertices.push_back(vertex_down_right);
		vertices.push_back(vertex_up_right);
		vertices.push_back(vertex_down_left);

		char character = text[i];
		float uv_x = (character % 16) / 16.0f;
		float uv_y = (character / 16) / 16.0f;

		glm::vec2 uv_up_left	= glm::vec2(uv_x				,uv_y);
		glm::vec2 uv_up_right	= glm::vec2(uv_x + 1.0f/16.0f	,uv_y);
		glm::vec2 uv_down_right = glm::vec2(uv_x + 1.0f/16.0f	,(uv_y + 1.0f/16.0f));
		glm::vec2 uv_down_left	= glm::vec2(uv_x				,(uv_y + 1.0f/16.0f));

		UVs.push_back(uv_up_left);
		UVs.push_back(uv_down_left);
		UVs.push_back(uv_up_right);

		UVs.push_back(uv_down_right);
		UVs.push_back(uv_up_right);
		UVs.push_back(uv_down_left);
	} 	

	glBindBuffer(GL_ARRAY_BUFFER,Text2DVertexBufferID);
	glBufferData(GL_ARRAY_BUFFER,vertices.size() * sizeof(glm::vec2),&vertices[0],GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER,Text2DUVBufferID);
	glBufferData(GL_ARRAY_BUFFER, UVs.size() * sizeof(glm::vec2), &UVs[0],GL_STATIC_DRAW);

	

	glUseProgram(Text2DShaderID);


	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D,Text2DTextureID);
	glUniform1i(Text2DUniformID,0);

	

	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER,Text2DVertexBufferID);
	glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,0,(void*)0);

	
	glEnableVertexAttribArray(1);
	glBindBuffer(GL_ARRAY_BUFFER, Text2DUVBufferID);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 );
	

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	glDrawArrays(GL_TRIANGLES,0,vertices.size());

	glDisable(GL_BLEND);

	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);
}

void cleanupText2D()
{
	glDeleteBuffers(1,&Text2DVertexBufferID);
	glDeleteBuffers(1,&Text2DUVBufferID);

	glDeleteTextures(1,&Text2DTextureID);
	glDeleteProgram(Text2DShaderID);


}

TextVertex.shader
<pre name="code" class="cpp">#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec2 vertexPosition_screenspace;
layout(location = 1) in vec2 vertexUV;


// Output data ; will be interpolated for each fragment.
out vec2 UV;

void main(){

	vec2 vertexPosition_homoneneousspace = vertexPosition_screenspace - vec2(400,300);
	vertexPosition_homoneneousspace /= vec2(400,300);
	gl_Position = vec4(vertexPosition_homoneneousspace,0,1);

	UV = vertexUV;

}

TextFragment.shader
 
  
<pre name="code" class="cpp">#version 330 core

// Interpolated values from the vertex shaders
in vec2 UV;


// Ouput data
out vec4 color;

// Values that stay constant for the whole mesh.
uniform sampler2D myTextureSampler;


void main(){

	color = texture2D(myTextureSampler,UV);
}


 
  


你可能感兴趣的:(opengl 字体渲染)