Qt5.12 + OpenGL 着色器
點擊上方藍字可直接關注!方便下次閱讀。如果對你有幫助,可以點個在看,讓它可以幫助到更多老鐵~
原教程地址:
https://learnopengl-cn.github.io/01%20Getting%20started/05%20Shaders/
一、 着色器概述
從基本意義上來講,着色器只是一種把輸入轉化爲輸出的程序。它們之間唯一的“通訊”方式只有通過輸入和輸出來實現。
着色器是使用一種叫GLSL的類 C 語言寫成的, GLSL 是爲圖形計算量身定製的,它包含一些針對向量和矩陣操作的有用特性。
1. 輸入與輸出
頂點着色器中定義一個輸出,在片段着色器中定義輸入來接收這個輸出。
頂點着色器:
out vec4 vertexColor; // 爲片段着色器指定一個顏色輸出
片段着色器:
in vec4 vertexColor; // 從頂點着色器傳來的輸入變量 (名稱相同、類型相同)
就是紅色三角形的例子!
2. Uniform 數據發送方式
Uniform 是一種從 CPU 中的應用向 GPU 中的着色器發送數據的方式,但 uniform 和頂點屬性有些不同。
首先, uniform 是全局的 (Global) 。 第二,無論你把 uniform 值設置成什麼, uniform 會一直保存它們的數據,直到它們被重置或更新。
爲了實現例程中的效果,我使用了QObject自帶的定時器事件,並使用 Qt update() 函數來更新繪圖。
程序例子:
//使用uniform的片段着色器
static const char *fragmentShaderSourceUniform =
"#version 330 core\n"
"out vec4 FragColor;\n"
"uniform vec4 ourColor;\n" // 在OpenGL程序代碼中設定這個變量
"void main(){\n"
" FragColor = ourColor;\n"
"}\n\0";
paintGL中更新 Uniform :
#ifdef COLORCHANGE
// 更新uniform顏色
float greenValue = sin(m_timeout) / 2.0f + 0.5f;
int vertexColorLocation = m_core->glGetUniformLocation(m_shaderProgram, "ourColor");
m_core->glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
#elif MULTICOLOR
#endif
定時器更新計數:
void MyGLWidget::timerEvent(QTimerEvent *e)
{
Q_UNUSED(e);
if(m_timeout >= 1.0)
{
m_timeout = -1.0;
}
m_timeout = m_timeout + 0.05;
update();
}
效果視頻:
三角形顏色漸變:
矩形顏色漸變:
3. 頂點屬性傳遞顏色
GLfloat vertices[] = {
// 位置 // 顏色
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 右下
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 左下
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // 頂部
};
m_core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), nullptr);
m_core->glEnableVertexAttribArray(0); //以頂點屬性位置值作爲參數,啓用頂點屬性;頂點屬性默認是禁用的
m_core->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3* sizeof(float)));
m_core->glEnableVertexAttribArray(1); //以頂點屬性位置值作爲參數,啓用頂點屬性;頂點屬性默認是禁用的
效果圖:
二、 總結
1、 小結
原教程中主要介紹了着色器的語法,改變顏色的三種方式。不同着色器間的輸入輸出、全局變量Uniform的使用、在頂點屬性中設置顏色等。
最後,如需完整工程可在公衆號後臺留言
學不可以已