使用OpenGL绘制一个矩形和一个三角形

使用OpenGL绘制一个矩形和一个三角形

软件:VS

语言:C++

引入两个库一个是glew和glfw

具体步骤可看此知乎步骤
https://zhuanlan.zhihu.com/p/559251417

部分参考

[]((4条消息) OpenGL——绘制三角形和矩形_Simple J的博客-CSDN博客_opengl绘制矩形代码)

资源文件

这部分内容命名可以随意,但是后缀名一定不能修改!

core.vs

在资源文件中新建一个core.vs文档

#version 330 core
layout(location = 0) in vec3 position;
void main()
{
	gl_Position = vec4(position,1.0f);
}

更改gl位置

core.fs

在资源文件中新建一个core.fs文档

#version 330 core
out vec4 FragColor;
void main()
{
	FragColor = vec4(1.0f,0.0f,0.0f,1.0f);
}

可以修改图形的颜色

头文件

在头文件中新建命名为Shader.h文件

#pragma once
#include 
#include
#include
#include
#include

class Shader {
public:
	//GLuint ShaderProgram;

	Shader(const char* vertexPath, const char* fragmentPath)
	{
		ShaderProgram = glCreateProgram();
		CompileShaderFromFile(vertexPath, GL_VERTEX_SHADER);
		CompileShaderFromFile(fragmentPath, GL_FRAGMENT_SHADER);
		glLinkProgram(ShaderProgram);
		CheckErrors(ShaderProgram, "PROGRAM", GL_LINK_STATUS);

#ifndef __APPLE__
		glValidateProgram(ShaderProgram);
		CheckErrors(ShaderProgram, "PROGRAM", GL_VALIDATE_STATUS);
#endif //!__APPLE__
	}
	~Shader()
	{
		glDeleteProgram(ShaderProgram);
	}
	void UseProgram()
	{
		glUseProgram(ShaderProgram);
	}
private:
	GLuint ShaderProgram;
	void CompileShaderFromFile(const char* path, GLenum shaderType)
	{
		std::string code;
		std::ifstream shaderFile;
		shaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
		try {
			shaderFile.open(path);
			std::stringstream shaderStream;
			shaderStream << shaderFile.rdbuf();
			shaderFile.close();
			code = shaderStream.str();
		}
		catch (std::ifstream::failure& e)
		{
			std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLU_READ:" << e.what() << std::endl;
		}
		const GLchar* shaderCode = code.c_str();
		GLuint shader = glCreateShader(shaderType);
		glShaderSource(shader, 1, &shaderCode, NULL);
		glCompileShader(shader);
		CheckErrors(shader, "SHADER", GL_COMPILE_STATUS);
		glAttachShader(ShaderProgram, shader);
		glDeleteShader(shader);

	}
	void CheckErrors(GLuint obj, std::string type, GLenum checkStatus)
	{
		GLint success;
		if (type == "SHADER")
		{
			glGetShaderiv(obj, checkStatus, &success);
			if (!success)
			{
				GLchar infoLog[1024];
				glGetShaderInfoLog(obj, 1024, NULL, infoLog);
				std::cout << "ERROR::SHADER::COMPILATION_FAILED\n" << infoLog << std::endl;
				exit(-1);
			}

		}
		else if (type == "PROGRAM")
		{
			glGetProgramiv(obj, checkStatus, &success);
			if (!success)
			{
				GLchar infoLog[1024];
				glGetProgramInfoLog(obj, 1024, NULL, infoLog);
				std::cout << "ERROR::PROGRAM::COMPILATION_FAILED\n" << infoLog << std::endl;
				exit(-1);
			}
		}

	}
};


源文件

在源文件中新建命名为main.cpp文件

#include 
#include 
#include 
#include "Shader.h"


#define ERRORLOG(message) std::cout << message << std::endl;glfwTerminate();return -1;

/*
const GLchar* vertexShaderSource = "$version 330 core\n"
"layout(location = 0) in vec3 position;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(position,1.0f);\n"
"}";

const GLchar* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"FragColor = vec4(1.0f,0.0f,0.0f,0.0f);\n"
"}";

static void CreateShaderProgram(GLuint shaderProgram)
{
	GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
	glCompileShader(vertexShader);
	GLint success;
	GLchar infoLog[1024];
	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(vertexShader, 1024, NULL, infoLog);
		std::cout << "ERROR::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
	}
	GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
	glCompileShader(fragmentShader);
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(fragmentShader, 1024, NULL, infoLog);
		std::cout << "ERROR::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
	}
	glAttachShader(shaderProgram, vertexShader);
	glAttachShader(shaderProgram, fragmentShader);
	glLinkProgram(shaderProgram);
	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
	if (!success)
	{
		glGetProgramInfoLog(shaderProgram, 1024, NULL, infoLog);
		std::cout << "ERROR::PROGRAM::LINK_FAILED\n" << infoLog << std::endl;
	}
#ifndef  __APPLE__
	glValidateProgram(shaderProgram);
	glGetProgramiv(shaderProgram, GL_VALIDATE_STATUS, &success);
	if (!success)
	{
		glGetProgramInfoLog(shaderProgram, 1024, NULL, infoLog);
		std::cout << "ERROR::PROGRAM::VALIDATION_FAILED\n" << infoLog << std::endl;
	}
#endif
	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);
}
*/

GLuint VAO, VBO,VEO;
static void RenderScreen(GLFWwindow* window)
{
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);//界面颜色
	glClear(GL_COLOR_BUFFER_BIT);
	glBindVertexArray(VAO);
	//glDrawArrays(GL_POINTS, 0, 1);
	glDrawArrays(GL_TRIANGLES, 4, 3);//三角形
	glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);//矩形
	glBindVertexArray(0);
	glfwSwapBuffers(window);
}

static void CreateVertexBuffer()
{
	GLfloat vertices1[] = { 
							-1.0f, 0.0f, 0.0f, // 左  
							0.0f, 0.0f, 0.0f, // 右 
							-0.5f,  0.5f, 0.0f  // 顶点   
	};
	GLfloat vertices2[] = {
							0.5f, 0.0f, 0.0f,   // 右上角
							0.5f, -0.5f, 0.0f,  // 右下角
							0.0f, -0.5f, 0.0f,// 左下角
							1.0f, 0.0f, 0.0f,// 左上角
	};

	unsigned int indices[] = { // 注意索引从0开始! 
								0, 1, 3, // 第一个三角形
								1, 2, 3  // 第二个三角形
	};

	GLfloat vertices[] = {
							//矩形
							0.5f, 0.0f, 0.0f,   // 右上角
							0.5f, -0.5f, 0.0f,  // 右下角
							0.0f, -0.5f, 0.0f,// 左下角
							0.0f, 0.0f, 0.0f,// 左上角
							//三角形
							-1.0f, 0.0f, 0.0f, // 左  
							0.0f, 0.0f, 0.0f, // 右 
							-0.5f,  0.5f, 0.0f  // 顶点   
	};

	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);//三角形
	glGenBuffers(1, &VEO);//矩形

	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);//三角形
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VEO);//矩形
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
	
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);
}

static void SetViewport(GLFWwindow* window)
{
	int screenWidth, screenHeight;
	glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
	glViewport(0, 0, screenWidth, screenHeight);
}
int main()
{
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

#ifdef __APPLE__
	glfwWindowHint(GLFE_OPENGL_FORENGL_FOREARD_COMPAT, GL_TRUE);
#endif //__APPLE__

	GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGLTutorial1", NULL, NULL);
	if (window == NULL) { ERRORLOG("Failde to creat GLFW window") }
	glfwMakeContextCurrent(window);

	if (GLEW_OK != glewInit()) { ERRORLOG("Failed tp init glew") }
	CreateVertexBuffer();
	Shader shader = Shader("res/core.vs", "res/core.fs");
	//GLuint ShaderProgram = glCreateProgram();
	//CreateShaderProgram(ShaderProgram);
	while (!glfwWindowShouldClose(window))
	{
		SetViewport(window);
		glfwPollEvents();
		//glUseProgram(ShaderProgram);
		shader.UseProgram();
		RenderScreen(window);
	}
	glfwTerminate();
	return 1;
}

运行结果

使用OpenGL绘制一个矩形和一个三角形_第1张图片

可能问题

  1. 打代码的过程中可能会飘红,就是引入库失败,思考可能是引入glew和glfw路径不对

使用OpenGL绘制一个矩形和一个三角形_第2张图片

明明一开始和教程一步步配置的怎么可能会出错!后来和舍友对比后,发现在新建项目的时候,有一个地方不能勾选

使用OpenGL绘制一个矩形和一个三角形_第3张图片

就是这儿!因为如果勾选了的话路径就和教程中的不一样了。可以看看下图如果勾选了的文件里是啥

使用OpenGL绘制一个矩形和一个三角形_第4张图片

下图是没勾选的,新建完后可以去你的项目文件夹下面看看。如果和下图一致那就没问题

使用OpenGL绘制一个矩形和一个三角形_第5张图片

  1. 还有一种情况就是代码没飘红,能运行,但是运行出来是这样,如下图

使用OpenGL绘制一个矩形和一个三角形_第6张图片

error原因是打不开文件,思考应该是fs和vs两个文件路径不对。看了看代码

在这里插入图片描述

果然,因为是上课跟着老师打的,根本没有res这个文件夹哈哈哈哈。那就要去Project5文件下自己新建一个res文件夹,然后把core.fs和core.vs两个文件放进去,如下图

使用OpenGL绘制一个矩形和一个三角形_第7张图片

注意看清楚res的路径哦

改进

就是如何让两个图形的颜色不一样,再能改下他们的位置吧,可能在下篇笔记放出来(如果有时间的话哈哈哈)

你可能感兴趣的:(c++,vscode)