文章目錄
- OpenGL基本使用
OpenGL基本使用
//GLSL腳本程式識別符號
static GLuint program;
//OpenGL頂點識別符號
GLuint vao;
//OpenGL buffer識別符號
GLuint vbo;
//OpenGL 紋理識別符號
GLuint tex;
static const GLfloat quad_data[] =
{
//OpenGL繪制坐標點初始值
0.0f, 0.0f,
0.0f, 0.0f,
0.0f, 0.0f,
0.0f, 0.0f,
//OpenGL紋理坐標點初始值
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f
};
頂點著色器腳本,主要是確定文字的繪制坐標,以及紋理坐標位置
#version 400 core
layout (location = 0) in vec2 in_position;
layout (location = 1) in vec2 in_tex_coord;
out vec2 tex_coord;
void main(void)
{
gl_Position = vec4(in_position, 0.0f, 1.0);
tex_coord = in_tex_coord;
}
片段著色器腳本,定義一個紋理器,輸出對應坐標的紋理顏色資訊
#version 450 core
in vec2 tex_coord;
layout (location = 0) out vec4 color;
uniform sampler2D tex;
void main(void)
{
color = texture(tex, tex_coord);
}
編譯GLSL腳本
/* Create and compile a shader */
/* type指示編譯的是頂點腳本,還是片段腳本 */
/* src是對應腳本的字串 */
static GLuint
create_shader (int type,
const char *src)
{
GLuint shader;
int status;
//創建一個著色器
shader = glCreateShader (type);
//將腳本與著色器系結
glShaderSource (shader, 1, &src, NULL);
//編譯GLSL腳本
glCompileShader (shader);
//獲取編譯資訊
glGetShaderiv (shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
int log_len;
char *buffer;
//編譯失敗,獲取失敗log
glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &log_len);
buffer = g_malloc (log_len + 1);
glGetShaderInfoLog (shader, log_len, NULL, buffer);
g_warning ("Compile failure in %s shader:\n%s",
type == GL_VERTEX_SHADER ? "vertex" : "fragment",
buffer);
g_free (buffer);
glDeleteShader (shader);
return 0;
}
//回傳著色器編譯結果
return shader;
}
鏈接著色器
/* Initialize the shaders and link them into a program */
/* vertex_path:頂點著色器腳本路徑 */
/* fragment_path:片段著色器腳本路徑 */
/* program_out:生成的著色器程式 */
static void
init_shaders (const char *vertex_path,
const char *fragment_path,
GLuint *program_out)
{
GLuint vertex, fragment;
GLuint _program = 0;
int status;
GBytes *source;
//獲取頂點著色器檔案索引
source = g_resources_lookup_data (vertex_path, 0, NULL);
//獲取頂點著色器腳本檔案內容,并編譯著色器程式
vertex = create_shader (GL_VERTEX_SHADER, g_bytes_get_data (source, NULL));
g_bytes_unref (source);
if (vertex == 0)
{
*program_out = 0;
return;
}
//獲取片段著色器檔案索引
source = g_resources_lookup_data (fragment_path, 0, NULL);
//獲取片段著色器腳本檔案內容,并編譯著色器程式
fragment = create_shader (GL_FRAGMENT_SHADER, g_bytes_get_data (source, NULL));
g_bytes_unref (source);
if (fragment == 0)
{
glDeleteShader (vertex);
*program_out = 0;
return;
}
//創建一個著色器程式
_program = glCreateProgram ();
//將頂點著色器與新創建的著色器程式系結起來
glAttachShader (_program, vertex);
//將片段著色器與新創建的著色器程式系結起來
glAttachShader (_program, fragment);
//鏈接著色器程式
glLinkProgram (_program);
//獲取鏈接資訊
glGetProgramiv (_program, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
int log_len;
char *buffer;
//獲取鏈接錯誤資訊
glGetProgramiv (_program, GL_INFO_LOG_LENGTH, &log_len);
buffer = g_malloc (log_len + 1);
glGetProgramInfoLog (_program, log_len, NULL, buffer);
g_warning ("Linking failure:\n%s", buffer);
g_free (buffer);
glDeleteProgram (_program);
_program = 0;
goto out;
}
glDetachShader (_program, vertex);
glDetachShader (_program, fragment);
out:
glDeleteShader (vertex);
glDeleteShader (fragment);
//回傳著色器程式
if (program_out != NULL)
*program_out = _program;
}
創建頂點物件、快取物件和紋理物件,并設定頂點引數和紋理引數資訊
static void
realize (GtkWidget *widget)
{
......
//創建一個快取buffer
glGenBuffers(1, &vbo);
//將vbo系結到GL_ARRAY_BUFFER
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//初始化快取資料
glBufferData(GL_ARRAY_BUFFER, sizeof(quad_data), quad_data, GL_STATIC_DRAW);
//生成并系結一個頂點陣列物件
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
//設定頂點陣列物件引數
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)(8 * sizeof(float)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
//生成并系結一個紋理物件
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
//設定紋理引數
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glGenerateMipmap(GL_TEXTURE_2D);
......
}
vao與vbo的關系如下圖👇

①定義并系結vbo,初始化vbo系結的buffer資料
②定義并系結vao,設定vao中的pointer0 和 pointer1屬性,其實就是設定如何獲取vbo系結的buffer中的資料
③開啟pointer0 和 pointer1屬性
static gboolean
render (GtkGLArea *area,
GdkGLContext *context)
{
......
/* Clear the viewport */
glClearColor(0.11765f, 0.11765f, 0.11765f, 1.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_CULL_FACE);
glUseProgram(program);
glBindTexture(GL_TEXTURE_2D,tex);
glBindVertexArray(vao);
glEnable(GL_BLEND);
//設定像素演算法
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
......
}
下一篇文章會介紹OpenGL、FreeType2與GTK4結合使用
回傳系列目錄頁

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/279904.html
標籤:其他
上一篇:LLC諧振變換器原理及變頻控制
