中文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結果