GTK4+OpenGL+FreeTpye2显示文字教程——OpenGL基本使用

文章目录

  • 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的关系如下图
GTK4+OpenGL+FreeTpye2显示文字教程——OpenGL基本使用_第1张图片
①定义并绑定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结合使用

返回系列目录页


GTK4+OpenGL+FreeTpye2显示文字教程——OpenGL基本使用_第2张图片

你可能感兴趣的:(OpenGL,GTK,gtk/gtk+,opengl,freetype,图形学)