OpenGL颜色插值

绘制四边形的时候,实际上是绘制两个三角形,即6个点,但是实际上有两个点重复存储了,解决点重复存储的方法是使用EBO,详细见代码部分。

Shader.h

#pragma once
#include<string>
#define GLEW_STATIC  //glew32s.lib
#include<GL\glew.h>
#include<GLFW\glfw3.h>

class Shader
{
public:
	Shader(const char* vertexPath, const char* fragmentPath);
	void use();

	//检查编译错误
	void checkCompileErrors(GLuint ID, std::string type);

private:
	std::string vertexString;
	std::string fragmentString;
	const char* vertexSource;
	const char* fragmentSource;
	
	GLuint shaderProgramID;  //Shader program ID
};

Shader.cpp

#include "Shader.h"
#include<iostream>
#include<fstream>
#include<sstream>

Shader::Shader(const char * vertexPath, const char * fragmentPath)
{
	std::ifstream vertexFile;
	std::ifstream fragmentFile;

	std::stringstream vertexSStream;
	std::stringstream fragmentSStream;

	vertexFile.open(vertexPath);
	fragmentFile.open(fragmentPath);

	// 保证ifstream对象可以抛出异常:
	vertexFile.exceptions(std::ifstream::failbit || std::ifstream::badbit);
	fragmentFile.exceptions(std::ifstream::failbit || std::ifstream::badbit);

	try
	{
		if (!vertexFile.is_open() || !fragmentFile.is_open())
		{
			throw std::exception("open file error!");
		}

		// step1:读取文件的缓冲内容到 字符串流(数据流)
		vertexSStream << vertexFile.rdbuf();
		fragmentSStream << fragmentFile.rdbuf();

		// step2:转换 字符串流(数据流)到 string
		vertexString = vertexSStream.str();
		fragmentString = fragmentSStream.str();

		// step3:转换 string 到 char*
		vertexSource = vertexString.c_str();
		fragmentSource = fragmentString.c_str();


		GLuint vertexShaderID, fragmentShaderID;

		vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
		glShaderSource(vertexShaderID, 1, &vertexSource, NULL);
		glCompileShader(vertexShaderID);
		checkCompileErrors(vertexShaderID, "VERTEX");

		fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
		glShaderSource(fragmentShaderID, 1, &fragmentSource, NULL);
		glCompileShader(fragmentShaderID);
		checkCompileErrors(fragmentShaderID, "FRAGMENT");

		shaderProgramID = glCreateProgram();
		glAttachShader(shaderProgramID, vertexShaderID);
		glAttachShader(shaderProgramID, fragmentShaderID);
		glLinkProgram(shaderProgramID);
		checkCompileErrors(shaderProgramID, "PROGRAM");

		glDeleteShader(vertexShaderID);
		glDeleteShader(fragmentShaderID);

	}
	catch (const std::exception& ex)
	{
		std::cout << ex.what() << std::endl;
	}
}

void Shader::use()
{
	glUseProgram(shaderProgramID);
}

void Shader::checkCompileErrors(GLuint ID, std::string type)
{
	GLint success;
	GLchar infoLog[512];

	if (type != "PROGRAM")
	{
		glGetShaderiv(ID, GL_COMPILE_STATUS, &success);
		if (!success)  //编译不成功
		{			
			glGetShaderInfoLog(ID, 512, NULL, infoLog);  //取得到底报的什么错误
			std::cout << "shader compile error!" << infoLog << std::endl;
		}
	}
	else
	{
		glGetProgramiv(ID, GL_LINK_STATUS, &success);
		if (!success)  //链接不成功
		{
			glGetProgramInfoLog(ID, 512, NULL, infoLog);
			std::cout << "program linking error!" << infoLog << std::endl;
		}
	}
}

main.cpp

#define GLEW_STATIC  //glew32s.lib
#include<GL\glew.h>
#include<GLFW\glfw3.h>
#include<iostream>
#include<vector>
#include"Shader.h"


//键盘回调函数原型声明
void processInput(GLFWwindow* window);

//定义程序常量
const int WINDOW_WIDTH = 800, WINDOW_HEIGHT = 600;


int main(int argc, char** argv)
{


	// 开启OpenGL 3.3 core profile
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); //主版本号
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); //次版本号
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	
	
	//create OpenGL GLFW Window
	GLFWwindow *window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "OpenglWindow", NULL, NULL);
	if (window == NULL)
	{
		std::cout << "Failed to create GLFW window!" << std::endl;
		glfwTerminate();  //终止glfw
		return -1;
	}
	glfwMakeContextCurrent(window); // 创建的窗口的context指定为当前context


	// 初始化GLEW 获取OpenGL函数
	glewExperimental = true;  // 让glew获取所有拓展函数
	if (glewInit() != GLEW_OK)
	{
		std::cout << "Failed to Init GLEW" << std::endl;
		glfwTerminate();
		return -1;
	}
	
	glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);   //设置视口参数

	Shader *shader = new Shader("vertexSource.txt", "fragmentSource.txt");
	
	// 指定顶点属性数据 
	GLfloat vertices[] = {
		//顶点位置                 //顶点颜色
		0.5f, 0.5f, 0.0f,         1.0f,0.0f,0.0f,        // 右上角 0
		0.5f, -0.5f, 0.0f,        0.0f,1.0f,0.0f,        // 右下角 1
		-0.5f, -0.5f, 0.0f,       0.0f,0.0f,1.0f,        // 左下角 2
		-0.5f, 0.5f, 0.0f,        0.3f,0.8f,0.5f         // 左上角 3
	}; 

	//索引数据(用于EBO)
	GLuint indices[] = { // 注意索引从0开始! 
	0, 1, 3, // 第一个三角形
	1, 2, 3  // 第二个三角形
	};
	

	//创建缓存对象
	GLuint VAO, VBO;

	//step1:创建并绑定VAO对象(VAO:vertex array object)
	glGenVertexArrays(1, &VAO);
	glBindVertexArray(VAO);

	//step2:创建并绑定VBO对象 (VBO:vertex buffer object)
	glGenBuffers(1, &VBO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);

	//step3:分配空间,将数据传送到GPU中
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	//step4:指定解析方式,并启用顶点属性
	//位置属性
	glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GL_FLOAT), (GLvoid*)0);
	glEnableVertexAttribArray(6);
	//颜色属性
	glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GL_FLOAT), (GLvoid*)(3*sizeof(GLfloat)));
	glEnableVertexAttribArray(7);

	//EBO(绘制四边形,解决顶点重复存储)
	GLuint EBO;
	glGenBuffers(1, &EBO);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

		
	// 开始游戏主循环
	while (!glfwWindowShouldClose(window))
	{
		glfwPollEvents(); // 处理例如鼠标 键盘等事件

		// 清除颜色缓冲区 重置为指定颜色
		glClearColor(0.18f, 0.04f, 0.14f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		// 这里填写场景绘制代码
		glBindVertexArray(VAO);  //使用VAO信息
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); //使用EBO信息
		shader->use();

		//glDrawArrays(GL_TRIANGLES, 0, 3);  //使用VBO数据绘制物体
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);  //使用EBO数据绘制物体,第4个参数是EBO中的偏移量


		glBindVertexArray(0);
		glUseProgram(0);

		glfwSwapBuffers(window); // 交换缓存
		glfwPollEvents();
	}
	// 释放资源
	//glDeleteProgram(shaderProgram);
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);
	glfwTerminate();
	return 0;
}



void processInput(GLFWwindow* window)
{
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
	{
		glfwSetWindowShouldClose(window, true);
	}
}

运行结果:
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

*Heygirl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值