OpenGL學習(二)着色器

中文OpenGL學習網站:https://learnopengl-cn.github.io

一、着色器之間可以相互傳遞數據(只要類型和名稱一樣)

畫一個紅色的三角形

1.1代碼

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>


const unsigned int WIDTH = 800;
const unsigned int HEIGHT = 600;
void callbackFramebufferSize(GLFWwindow *vWindow, int vWidth, int vHeight)
{
	glViewport(0, 0, vWidth, vHeight);
}
void processInput(GLFWwindow *vWindow)
{
	if (glfwGetKey(vWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS)
	{
		glfwSetWindowShouldClose(vWindow, true);
	}
}
const char *VertexShaderSource =
"#version 330 core\n"
"layout (location=0) in vec3 aPos;\n"
"out vec4 VertexColor;\n"
"void main()\n"
"{\n"
"	gl_Position=vec4(aPos,1.0);\n"
"	VertexColor=vec4(0.5,0.0,0.0,0.0);\n"
"}\0";
const char *FragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"in vec4 VertexColor;\n"
"void main()\n"
"{\n"
"	FragColor=VertexColor;\n"
"}\n\0";
int main()
{
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	GLFWwindow *Window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
	if (Window == NULL)
	{
		std::cout << "failed to  create window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(Window);
	glfwSetFramebufferSizeCallback(Window, callbackFramebufferSize);
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "failed to initialize glad" << std::endl;
		return -1;
	}
	//着色器
	int VertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(VertexShader, 1, &VertexShaderSource, NULL);
	glCompileShader(VertexShader);
	int Success;
	char InfoLog[512];
	glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &Success);
	if (!Success)
	{
		glGetShaderInfoLog(VertexShader, 512, NULL, InfoLog);
		std::cout << "error::shader::vertex::compilation failed\n" << InfoLog << std::endl;
	}
	int FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(FragmentShader, 1, &FragmentShaderSource, NULL);
	glCompileShader(FragmentShader);
	glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &Success);
	if (!Success)
	{
		glGetShaderInfoLog(FragmentShader, 512, NULL, InfoLog);
		std::cout << "error::shader::fragment::compilation failed\n" << InfoLog << std::endl;
	}
	int ShaderProgram = glCreateProgram();
	glAttachShader(ShaderProgram, VertexShader);
	glAttachShader(ShaderProgram, FragmentShader);
	glLinkProgram(ShaderProgram);
	glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success);
	if (!Success)
	{
		glGetProgramInfoLog(ShaderProgram, 512, NULL, InfoLog);
		std::cout << "error::shader::program::linking failed\n" << InfoLog << std::endl;
	}
	glDeleteShader(VertexShader);
	glDeleteShader(FragmentShader);
	//數據
	float Vertices[] =
	{
		0.0f,0.5f,0.0f,
		-0.5f,0.0f,0.0f,
		0.5f,0.0f,0.0f
	};
	unsigned int VAO, VBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
	glBindVertexArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	while (!glfwWindowShouldClose(Window))
	{
		processInput(Window);
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		glUseProgram(ShaderProgram);
		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, 3);
		glfwSwapBuffers(Window);
		glfwPollEvents();
	}
	glDeleteVertexArrays(1,&VAO);
	glDeleteBuffers(1, &VBO);
	glfwTerminate();
	return 0;
}

1.2 結果

 

二、利用uniform傳遞參數

繪製顏色有綠變黑然後由黑變綠的三角形,其中顏色的值使用uniform傳遞

2.1代碼

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>


const unsigned int WIDTH = 800;
const unsigned int HEIGHT = 600;
void callbackFramebufferSize(GLFWwindow *vWindow, int vWidth, int vHeight)
{
	glViewport(0, 0, vWidth, vHeight);
}
void processInput(GLFWwindow *vWindow)
{
	if (glfwGetKey(vWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS)
	{
		glfwSetWindowShouldClose(vWindow, true);
	}
}
const char *VertexsShaderSource1 =
"#version 330 core\n"
"layout (location=0) in vec3 aPos;\n"
"void main()\n"
"{\n"
"	gl_Position=vec4(aPos,1.0f);\n"
"}\n\0";
const char *FragmentShaderSource1 =
"#version 330 core\n"
"out vec4 FragColor;\n"
"uniform vec4 OurColor;\n"
"void main()\n"
"{\n"
"	FragColor=OurColor;\n"
"}\n\0";

//着色器使用uniform傳遞數據
int main()
{
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	GLFWwindow *Window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
	if (Window == NULL)
	{
		std::cout << "failed to create glfw window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(Window);
	glfwSetFramebufferSizeCallback(Window, callbackFramebufferSize);
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "failed to initialze glad" << std::endl;
		return -1;
	}
	int VertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(VertexShader, 1, &VertexsShaderSource1, NULL);
	glCompileShader(VertexShader);
	int Success;
	char InfoLog[512];
	glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &Success);
	if (!Success)
	{
		glGetShaderInfoLog(VertexShader, 512, NULL, InfoLog);
		std::cout << "error::shader::vertex::compilation failed\n" << InfoLog << std::endl;
	}
	int FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(FragmentShader, 1, &FragmentShaderSource1, NULL);
	glCompileShader(FragmentShader);
	glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &Success);
	if (!Success)
	{
		glGetShaderInfoLog(FragmentShader, 512, NULL, InfoLog);
		std::cout << "error::shader::fragment::compilation failed\n" << InfoLog << std::endl;
	}
	int ShaderProgram = glCreateProgram();
	glAttachShader(ShaderProgram, VertexShader);
	glAttachShader(ShaderProgram, FragmentShader);
	glLinkProgram(ShaderProgram);
	glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success);
	if (!Success)
	{
		glGetProgramInfoLog(ShaderProgram, 512, NULL, InfoLog);
		std::cout << "error::shader::program::linking failed\n" << InfoLog << std::endl;
	}
	glDeleteShader(VertexShader);
	glDeleteShader(FragmentShader);
	float Vertices[] =
	{
		0.0f,0.5f,0.0f,
		-0.5f,0.0f,0.0f,
		0.5f,0.0f,0.0f
	};
	unsigned int VAO, VBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
	glBindVertexArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	while (!glfwWindowShouldClose(Window))
	{
		processInput(Window);
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		glUseProgram(ShaderProgram);
		float TimeValue = glfwGetTime();
		float GreenValue = sin(TimeValue) / 2.0f + 0.5f;
		int ColorLocation = glGetUniformLocation(ShaderProgram, "OurColor");
		glUniform4f(ColorLocation, 0.0f, GreenValue, 0.0f, 1.0f);
		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, 3);
		glfwSwapBuffers(Window);
		glfwPollEvents();
	}
	glDeleteVertexArrays(1,&VAO);
	glDeleteBuffers(1, &VBO);
	glfwTerminate();
	return 0;
}

 

2.2結果

跟隨時間由綠變黑,然後又由黑變綠

三、利用頂點數據傳遞更多的屬性

畫一個每個頂點帶顏色的三角形

3.1代碼

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>


const unsigned int WIDTH = 800;
const unsigned int HEIGHT = 600;
void callbackFramebufferSize(GLFWwindow *vWindow, int vWidth, int vHeight)
{
	glViewport(0, 0, vWidth, vHeight);
}
void processInput(GLFWwindow *vWindow)
{
	if (glfwGetKey(vWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS)
	{
		glfwSetWindowShouldClose(vWindow, true);
	}
}

const char *VertexShaderSource2 =
"#version 330 core\n"
"layout (location=0) in vec3 aPos;\n"
"layout (location=1) in vec3 Color;\n"
"out vec4 OurColor;\n"
"void main()\n"
"{\n"
"	gl_Position=vec4(aPos,1.0f);\n"
"	OurColor=vec4(Color,1.0f);\n"
"}\n\0";
const char *FragmentShaderSource2 =
"#version 330 core\n"
"out vec4 FragColor;\n"
"in vec4 OurColor;\n"
"void main()\n"
"{\n"
"	FragColor=OurColor;\n"
"}\n\0";

//頂點屬性在頂點數據裏面
int main()
{
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	GLFWwindow *Window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
	if (Window == NULL)
	{
		std::cout << "failed to create glfw window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(Window);
	glfwSetFramebufferSizeCallback(Window, callbackFramebufferSize);
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "failed to initialize glad" << std::endl;
		return -1;
	}
	int VertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(VertexShader, 1, &VertexShaderSource2, NULL);
	glCompileShader(VertexShader);
	int FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(FragmentShader, 1, &FragmentShaderSource2, NULL);
	glCompileShader(FragmentShader);
	int ShaderProgram = glCreateProgram();
	glAttachShader(ShaderProgram, VertexShader);
	glAttachShader(ShaderProgram, FragmentShader);
	glLinkProgram(ShaderProgram);
	glDeleteShader(VertexShader);
	glDeleteShader(FragmentShader);
	float Vertices[] =
	{
		0.0f,0.5f,0.0f,1.0f,0.0f,0.0f,
		-0.5f,0.0f,0.0f,0.0f,1.0f,0.0f,
		0.5f,0.0f,0.0f,0.0f,0.0f,1.0f
	};
	unsigned int VAO, VBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);
	glBindVertexArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	while (!glfwWindowShouldClose(Window))
	{
		processInput(Window);
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		glUseProgram(ShaderProgram);
		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, 3);
		glfwSwapBuffers(Window);
		glfwPollEvents();
	}
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1,&VBO);
	glfwTerminate();
	return 0;
}

 

3.2結果

設置頂點帶顏色,OpenGL會對片元進行插值,所以會出現漸變的顏色。

 

四、創建着色器類,方便以後使用

畫一個頂點帶顏色的三角形,和上面一樣

4.1代碼

//着色器類
#pragma once
#include <glad/glad.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>

class CShader
{
public:
	unsigned int m_ShaderId;
	CShader(const char* VertexPath, const char* FragmentPath)
	{
		std::string VertexCode, FragmentCode;
		//着色器文件
		std::ifstream VertexShaderFile, FragmentShaderFile;
		//確保可以拋出異常
		VertexShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
		FragmentShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
		try
		{
			//打開文件
			VertexShaderFile.open(VertexPath);
			FragmentShaderFile.open(FragmentPath);
			//讀取文件緩衝區的內容到stream流中
			std::stringstream VertexShaderStream, FragmentShaderStream;
			VertexShaderStream << VertexShaderFile.rdbuf();
			FragmentShaderStream << FragmentShaderFile.rdbuf();
			//關閉文件
			VertexShaderFile.close();
			FragmentShaderFile.close();
			//將stream流的內容轉換成字符串類型,得到着色器代碼
			VertexCode = VertexShaderStream.str();
			FragmentCode = FragmentShaderStream.str();
		}
		catch (std::ifstream::failure e)
		{
			std::cout << "error::shader failed to open shader file" << std::endl;
		}
		const char *VertexShaderCode = VertexCode.c_str();
		const char *FragmentShaderCode = FragmentCode.c_str();
		//編譯着色器
		unsigned int VertexShader, FragmentShader;
		//編譯頂點着色器
		VertexShader = glCreateShader(GL_VERTEX_SHADER);
		glShaderSource(VertexShader, 1, &VertexShaderCode,NULL);
		glCompileShader(VertexShader);
		checkCompileErrors(VertexShader, "VERTEX");
		//編譯片段着色器
		FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
		glShaderSource(FragmentShader, 1, &FragmentShaderCode, NULL);
		glCompileShader(FragmentShader);
		checkCompileErrors(FragmentShader, "FRAGMENT");
		//編譯着色器程序
		m_ShaderId = glCreateProgram();
		glAttachShader(m_ShaderId, VertexShader);
		glAttachShader(m_ShaderId, FragmentShader);
		glLinkProgram(m_ShaderId);
		checkCompileErrors(m_ShaderId, "PROGRAM");
		glDeleteShader(VertexShader);
		glDeleteShader(FragmentShader);
	}
	void useProgram()
	{
		glUseProgram(m_ShaderId);
	}

	void setBool(const std::string &vName, bool Value) const
	{
		glUniform1i(glGetUniformLocation(m_ShaderId, vName.c_str()), (int)Value);
	}
	void setInt(const std::string &vName, int Value) const
	{
		glUniform1i(glGetUniformLocation(m_ShaderId, vName.c_str()), Value);
	}
	void setFloat(const std::string &vName, float Value) const
	{
		glUniform1f(glGetUniformLocation(m_ShaderId, vName.c_str()), Value);
	}

private:
	void checkCompileErrors(unsigned int vShader, std::string vType)
	{
		int Success;
		char InfoLog[1024];
		if (vType != "PROGRAM")
		{
			glGetShaderiv(vShader, GL_COMPILE_STATUS, &Success);
			if (!Success)
			{
				glGetShaderInfoLog(vShader, 1024, NULL, InfoLog);
				std::cout << "error::shader::complie "<<vType<<"\n" << InfoLog << std::endl;
			}
		}
		else
		{
			glGetProgramiv(m_ShaderId, GL_LINK_STATUS, &Success);
			if (!Success)
			{
				glGetProgramInfoLog(m_ShaderId, 1024, NULL, InfoLog);
				std::cout << "error::shader::link " << vType << "\n" << InfoLog << std::endl;
			}
		}
	}
};
//main函數
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "CShader.h"


const unsigned int WIDTH = 800;
const unsigned int HEIGHT = 600;
void callbackFramebufferSize(GLFWwindow *vWindow, int vWidth, int vHeight)
{
	glViewport(0, 0, vWidth, vHeight);
}
void processInput(GLFWwindow *vWindow)
{
	if (glfwGetKey(vWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS)
	{
		glfwSetWindowShouldClose(vWindow, true);
	}
}

//自己創建一個Shader類,方便以後使用
int main()
{
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	GLFWwindow *Window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
	if (Window == NULL)
	{
		std::cout << "failed to create glfw window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(Window);
	glfwSetFramebufferSizeCallback(Window, callbackFramebufferSize);
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "failed to initialize glad" << std::endl;
		return -1;
	}
	CShader ShaderProgram("Shader/Vertex/VertexSource1.glsl", "Shader/Fragment/FragmentSource1.glsl");
	float Vertices[] =
	{
		0.0f,0.5f,0.0f,1.0f,0.0f,0.0f,
		-0.5f,0.0f,0.0f,0.0f,1.0f,0.0f,
		0.5f,0.0f,0.0f,0.0f,0.0f,1.0f
	};
	unsigned int VAO, VBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);
	glBindVertexArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	while (!glfwWindowShouldClose(Window))
	{
		processInput(Window);
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		ShaderProgram.useProgram();
		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, 3);
		glfwSwapBuffers(Window);
		glfwPollEvents();
	}
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);
	glfwTerminate();
	return 0;
}
//頂點着色器文件
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 Color;
out vec4 OurColor;
void main()
{
	gl_Position = vec4(aPos, 1.0f);
	OurColor = vec4(Color, 1.0f);
}
//片段着色器文件
#version 330 core
out vec4 FragColor;
in vec4 OurColor;
void main()
{
	FragColor = OurColor;
}

4.2結果

五、修改頂點着色器讓三角形上下顛倒

畫一個顛倒的三角形

5.1代碼

CShader類使用上面抽象的類,以後直接使用,着色器程序需要用文本保存,注意路徑!

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "CShader.h"


const unsigned int WIDTH = 800;
const unsigned int HEIGHT = 600;
void callbackFramebufferSize(GLFWwindow *vWindow, int vWidth, int vHeight)
{
	glViewport(0, 0, vWidth, vHeight);
}
void processInput(GLFWwindow *vWindow)
{
	if (glfwGetKey(vWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS)
	{
		glfwSetWindowShouldClose(vWindow, true);
	}
}
//修改頂點着色器讓三角形上下顛倒
int main()
{
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	GLFWwindow *Window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
	if (Window == NULL)
	{
		std::cout << "failed to create glfw window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(Window);
	glfwSetFramebufferSizeCallback(Window, callbackFramebufferSize);
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "failed to initialize glad" << std::endl;
		return -1;
	}
	float Vertices[] =
	{
		0.0f,0.5f,0.0f,1.0f,0.0f,0.0f,
		-0.5f,0.0f,0.0f,0.0f,1.0f,0.0f,
		0.5f,0.0f,0.0f,0.0f,0.0f,1.0f
	};
	unsigned int VAO, VBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);
	CShader ShaderProgram("Shader/Vertex/VertexSource2.glsl", "Shader/Fragment/FragmentSource1.glsl");
	while (!glfwWindowShouldClose(Window))
	{
		processInput(Window);
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		ShaderProgram.useProgram();
		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, 3);
		glfwSwapBuffers(Window);
		glfwPollEvents();
	}
	glDeleteVertexArrays(1,&VAO);
	glDeleteBuffers(1, &VBO);
	glfwTerminate();
	return 0;

}
//頂點着色器部分
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 Color;
out vec4 OurColor;
void main()
{
	gl_Position = vec4(aPos.x,-aPos.y,aPos.z, 1.0f);
	OurColor = vec4(Color, 1.0f);
}
//片段着色器部分
#version 330 core
out vec4 FragColor;
in vec4 OurColor;
void main()
{
	FragColor = OurColor;
}

5.2結果

六、使用uniform定義一個水平偏移量,在頂點着色器中使用這個偏移量把三角形移動到屏幕右側

6.1代碼

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "CShader.h"


const unsigned int WIDTH = 800;
const unsigned int HEIGHT = 600;
void callbackFramebufferSize(GLFWwindow *vWindow, int vWidth, int vHeight)
{
	glViewport(0, 0, vWidth, vHeight);
}
void processInput(GLFWwindow *vWindow)
{
	if (glfwGetKey(vWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS)
	{
		glfwSetWindowShouldClose(vWindow, true);
	}
}
//使用uniform定義一個水平偏移量,在頂點着色器中使用這個偏移量把三角形移動到屏幕右側
int main()
{
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	GLFWwindow *Window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
	if (Window == NULL)
	{
		std::cout << "failed to create glfw window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(Window);
	glfwSetFramebufferSizeCallback(Window, callbackFramebufferSize);
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "failed to initialize glad" << std::endl;
		return -1;
	}
	float Vertices[] =
	{
		0.0f,0.5f,0.0f,1.0f,0.0f,0.0f,
		-0.5f,0.0f,0.0f,0.0f,1.0f,0.0f,
		0.5f,0.0f,0.0f,0.0f,0.0f,1.0f
	};
	unsigned int VAO, VBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);
	CShader ShaderProgram("Shader/Vertex/VertexSource3.glsl", "Shader/Fragment/FragmentSource1.glsl");
	while (!glfwWindowShouldClose(Window))
	{
		processInput(Window);
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		ShaderProgram.useProgram();
		ShaderProgram.setFloat("Distance", 0.5f);
		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, 3);
		glfwSwapBuffers(Window);
		glfwPollEvents();
	}
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);
	glfwTerminate();
	return 0;
}
//頂點着色器
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 Color;
uniform float Distance;
out vec4 OurColor;
void main()
{
	gl_Position = vec4(aPos.x + Distance, aPos.y, aPos.z, 1.0f);
	OurColor = vec4(Color, 1.0f);
}
//片段着色器
#version 330 core
out vec4 FragColor;
in vec4 OurColor;
void main()
{
	FragColor = OurColor;
}

6.2結果

七、使用out關鍵字把頂點位置輸出到片段着色器,並將片段的顏色設置爲與頂點位置相等(來看看連頂點位置值都在三角形中被插值的結果)

7.1代碼

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "CShader.h"


const unsigned int WIDTH = 800;
const unsigned int HEIGHT = 600;
void callbackFramebufferSize(GLFWwindow *vWindow, int vWidth, int vHeight)
{
	glViewport(0, 0, vWidth, vHeight);
}
void processInput(GLFWwindow *vWindow)
{
	if (glfwGetKey(vWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS)
	{
		glfwSetWindowShouldClose(vWindow, true);
	}
}
//使用out關鍵字把頂點位置輸出到片段着色器,並將片段的顏色設置爲與頂點位置相等
//(來看看連頂點位置值都在三角形中被插值的結果)
int main()
{
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	GLFWwindow *Window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
	if (Window == NULL)
	{
		std::cout << "failed to create glfw window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(Window);
	glfwSetFramebufferSizeCallback(Window, callbackFramebufferSize);
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "failed to initialize glad" << std::endl;
		return -1;
	}
	float Vertices[] =
	{
		0.1f,0.5f,0.0f,
		-0.5f,0.1f,0.0f,
		0.5f,0.1f,0.0f
	};
	unsigned int VAO, VBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
	CShader ShaderProgram("Shader/Vertex/VertexSource4.glsl", "Shader/Fragment/FragmentSource2.glsl");
	while (!glfwWindowShouldClose(Window))
	{
		processInput(Window);
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		ShaderProgram.useProgram();
		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, 3);
		glfwSwapBuffers(Window);
		glfwPollEvents();
	}
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);
	glfwTerminate();
	return 0;
}
//頂點着色器
#version 330 core
layout(location = 0) in vec3 aPos;
out vec3 Dis;
void main()
{
	gl_Position = vec4(aPos, 1.0f);
	Dis = aPos;
}
//片段着色器
#version 330 core
out vec4 FragColor;
in vec3 Dis;
void main()
{
	FragColor = vec4(Dis, 1.0f);
}

7.2結果

 

 

 

 

 

 

 

 

 

發佈了37 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章