OpenGL 绘制应用纹理的矩形

#include <iostream>

#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>

// 使用 SOIL 头文件
#include <SOIL.h>

// 使用上一篇里的着色器类
#include "Shader.h"

#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")

// 窗口大小
const GLuint WIDTH = 800, HEIGHT = 600;

int main () {
	// GLFW
	glfwInit();

	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);

	GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "UseTexture.cpp", nullptr, nullptr);
	glfwMakeContextCurrent(window);

	// GLEW
	glewExperimental = GL_TRUE;
	glewInit();

	glViewport(0, 0, WIDTH, HEIGHT);

	// 配置着色器,使用着色器函数加载、编译、链接着色器源码
	Shader ourShader("useTexture.vgl", "useTexture.fgl");

	// 顶点
	GLfloat vertices[] = {
		// 顶点坐标           // 颜色值           // 纹理坐标
		 0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // 右上角
		 0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f,-0.0f, // 右下角
		-0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,  -0.0f,-0.0f, // 左下角
		-0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,  -0.0f, 1.0f  // 左上角 
	};
	// 索引
	GLuint indices[] = {
		0, 1, 3,
		1, 2, 3
	};

	// 创建和使用 VBO、VAO、EBO
	GLuint VBO, VAO, EBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glGenBuffers(1, &EBO);

	glBindVertexArray(VAO);

	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

	// 顶点坐标
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
	glEnableVertexAttribArray(0);
	// 颜色值
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
	glEnableVertexAttribArray(1);
	// 纹理坐标
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
	glEnableVertexAttribArray(2);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0); 

	// 创建纹理对象
	GLuint texture;
	// 生成 1 个纹理
	glGenTextures(1, &texture);
	// 将纹理绑定到 GL_TEXTURE_2D 上,对 GL_TEXTURE_2D 的所有操作都会附加到 texture 上
	glBindTexture(GL_TEXTURE_2D, texture);
	// 设置纹理取样步长(防止图像扭曲倾斜)
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	// 设置纹理环绕方式(重复方式)
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);	// S 轴
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);   // T 轴
	//float borderColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };
	//glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
	// 设置纹理过滤方式(线性方式)
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	// 宽高数据
	int width, height;
	// 加载图片,其宽高将会存到参数变量中,返回一个非常大的 char(byte)数组
	unsigned char* image = SOIL_load_image("a.jpg", &width, &height, 0, SOIL_LOAD_RGB);
	// glTexImage2D() 
	// 绑定图像(目标,多级渐远纹理级别[0,基本级别],格式[RGB],宽度,高度,格式,数据类型[char数组],图像)
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
	// 自动生成多级渐远纹理
	glGenerateMipmap(GL_TEXTURE_2D);
	// 绑定好图像后释放内存和解绑
	SOIL_free_image_data(image);
	glBindTexture(GL_TEXTURE_2D, 0);

	// 主循环
	while (!glfwWindowShouldClose(window)) {

		// 事件处理
		glfwPollEvents();
		// 指定背景色(深蓝色)
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		// 绑定纹理对象,函数会自动把纹理赋值给片段着色器的采样器
		glBindTexture(GL_TEXTURE_2D, texture);

		// 使用着色器
		ourShader.use();

		// 绘制矩形
		glBindVertexArray(VAO);
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
		glBindVertexArray(0);

		// 交换缓冲
		glfwSwapBuffers(window);
	}

	// 删除 VAO、VBO 和 EBO,释放空间
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);
	glDeleteBuffers(1, &EBO);
	// 释放 GLFW 内存
	glfwTerminate();
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/darkmorn/p/12295050.html