在Ubuntu Linux操作系统中有不少开源且好用的工具库用于读取图片文件,识别它们的格式,然后以RGB等原生像素格式保存到存储器中。比如libpng就是其中之一。不过我们这里使用更方便、更快捷、更通用的GTK+库中所包含的GDK工具库对指定的图片文件进行读取,然后读取其内部原生像素数据,最后映射到纹理单元上。

我们可以参考这篇文章来下载安装GTK+:Ubuntu下安装GTK+3的方法。

下面我们先建立一个shell文件,命名为build.sh,用它进行构建整个程序。

clang main.c -std=gnu11 -lglut -lGL -I/usr/include/glib-2.0/ -I/usr/include/atk-1.0/ -I/usr/include/gdk-pixbuf-2.0/ -I/usr/include/cairo/ -I/usr/include/pango-1.0/ -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ -I/usr/include/gtk-3.0/ -L/usr/lib/x86_64-linux-gnu/ -lgtk-3 -lgobject-2.0 -lpangocairo-1.0 -lgio-2.0 -latk-1.0 -lgdk-3 -lgdk_pixbuf-2.0 -lglib-2.0 -o glutTexture

如果你的电脑没有安装Clang,也可以使用GCC。如果用GCC进行编译构建的话,只需要将上述的clang改为gcc就可以了。

下面展示main.c源文件:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#ifndef var

#define var __auto_type

#endif

static const GLfloat sRectVertices[] = {

// top left

-0.4f, 0.4f,

// bottom left

-0.4f, -0.4f,

// top right

0.4f, 0.4f,

// bottom right

0.4f, -0.4f

};

static const GLfloat sRectTexCoords[] = {

// top left

0.0f, 0.0f,

// bottom left

0.0f, 1.0f,

// top right

1.0f, 0.0f,

// bottom right

1.0f, 1.0f

};

static void TimerHandler(int value);

static GLfloat sDisplacement = -0.5f;

static GLfloat sDelta = 0.005f;

static int sTimerDuration = 20; //默认以50FPS的帧率进行刷新

static void RenderHandler(void)

{

glutTimerFunc(sTimerDuration, TimerHandler, 0);

sTimerDuration = 20;

glClear(GL_COLOR_BUFFER_BIT);

// Draw rectangle

glVertexPointer(2, GL_FLOAT, 0, sRectVertices);

glTexCoordPointer(2, GL_FLOAT, 0, sRectTexCoords);

glLoadIdentity();

glTranslatef(sDisplacement, 0.0f, -2.0f);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glFlush();

glutSwapBuffers();

sDisplacement += sDelta;

if(sDisplacement >= 0.5f)

{

sDisplacement = 0.5f;

sDelta = -sDelta;

sTimerDuration = 1500;

}

else if(sDisplacement <= -0.5f)

{

sDisplacement = -0.5f;

sDelta = -sDelta;

sTimerDuration = 1500;

}

}

static void TimerHandler(int value)

{

RenderHandler();

}

static bool LoadPixelsFromImageToTexture(const char *filePath)

{

var pixBuf = gdk_pixbuf_new_from_file(filePath, NULL);

if(pixBuf == NULL)

{

puts("The image is not found!");

printf("The file path is: %s\n", filePath);

return false;

}

const var width = gdk_pixbuf_get_width(pixBuf);

const var height = gdk_pixbuf_get_height(pixBuf);

printf("The image width is: %d, height is: %d\n", width, height);

var pixels = gdk_pixbuf_read_pixels(pixBuf);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

g_object_unref(pixBuf);

return true;

}

int main(int argc, char* argv[])

{

gtk_init(&argc, &argv);

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_MULTISAMPLE);

glutInitWindowSize(480, 480);

glutInitWindowPosition(200, 100);

glutCreateWindow("OpenGL GLUT Demo");

glutSetOption(GLUT_MULTISAMPLE, 4);

glutDisplayFunc(RenderHandler);

var vendor = (const char*)glGetString(GL_VENDOR);

var renderer = (const char*)glGetString(GL_RENDERER);

var version = (const char*)glGetString(GL_VERSION);

printf("The vendor is: %s\n", vendor);

printf("The renderer is: %s\n", renderer);

printf("The GL version is: %s\n", version);

glViewport(0, 0, 480, 480);

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

glShadeModel(GL_SMOOTH);

glFrontFace(GL_CCW);

glCullFace(GL_BACK);

glEnable(GL_CULL_FACE);

glEnable(GL_MULTISAMPLE_ARB);

glEnable(GL_TEXTURE_2D);

glEnableClientState(GL_VERTEX_ARRAY);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glActiveTexture(GL_TEXTURE0);

GLuint texID;

glGenTextures(1, &texID);

glBindTexture(GL_TEXTURE_2D, texID);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

char path[512];

int size = readlink("/proc/self/exe", path, 512);

int index = 0;

for(int i = size - 1; i >= 0; i--)

{

const var ch = path[i];

if(ch == '/')

{

index = i + 1;

break;

}

}

bool result = false;

do

{

if(index == 0)

break;

strcpy(&path[index], "image.png");

result = LoadPixelsFromImageToTexture(path);

}

while(false);

if(!result)

{

puts("Image data load failed!");

glDeleteTextures(1, &texID);

return 0;

}

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 3.0f);

glMatrixMode(GL_MODELVIEW);

glutMainLoop();

glDeleteTextures(1, &texID);

}

这里需要注意,在运行上述程序之前先搞一个PNG的图片,把它命名为image.png,然后将它放到build.sh和main.c同一文件目录下。这里对image.png是有要求的,它的宽和高的像素个数必须至少为32的倍数,并且最小值取为64,这是符合作为纹理的最低要求。

相关主题

Linux第7章Gdk及Cairo基础,源文件:Ubuntu中使用GLUT和GDK将图片文件加载到纹理单元...相关推荐

  1. linux 加载 iso,Linux iso文件加载和解包的用法

    Linux iso文件已被广泛应用但是也在不断的更新,这里介绍Linux iso文件安装设置使用,帮助大家安装更新Linux iso文件系统.软件包管理 之Linux Fedora 软件包管理器sys ...

  2. linux中人脸识别不了,虹软人脸识别在 linux中so文件加载不到的问题

    其实是可以加载到的,不过是so文件放的位置不一对,最简单的方式是放在 /usr/lib64 目录下,也可自己设置. so文件加载不到会报这个错误: .lang.UnsatisfiedLinkError ...

  3. java class文件 代码_java_基础——用代码编译.java文件+加载class文件

    java_基础--用代码编译.java文件+加载class文件 java_基础--用代码编译.java文件+加载class文件 [简单编译的流程] package com.zjm.www.test; ...

  4. Linux系统安装驱动过程中ko文件加载错误(Required key not available)的解决办法

    Linux系统安装驱动过程中ko文件加载错误(Required key not available)的解决办法 问题描述 在Ubuntu上使用CP210x USB转UART设备时需要安装驱动程序(CP ...

  5. Objective-C学习笔记第十五章文件加载与保存

    第十五章文件加载与保存 Cocoa提供了Core Data,他能在后台处理所有文件内容 Cocoa提供了两个通用的文件处理类:属性列表和对象编码 一.属性列表类 在Cocoa中,有一类名为属性列表的对 ...

  6. linux系统css样式加载不出,Linux系统虚拟主机网站访问页面css样式文件加载失败或图片无法显示的分析解决...

    问题场景:客户使用Linux系统虚拟主机,网站程序上传之后访问发现页面排版有问题,css样式文件加载失败,部分图片显示不出来,以织梦CMS程序为例,如下图所所示: 问题原因: 1.Linux系统虚拟主 ...

  7. nodejs学习巩固笔记-nodejs基础,Node.js 高级编程(核心模块、模块加载机制)

    目录 Nodejs 基础 大前端开发过程中的必备技能 nodejs 的架构 为什么是 Nodejs Nodejs 异步 IO Nodejs 事件驱动架构 全局对象 全局变量之 process 核心模块 ...

  8. Spring Cloud Alibaba基础教程:Nacos配置的多文件加载与共享配置

    <Spring Cloud Alibaba基础教程>连载中,关注我一起学期!前情回顾: <使用Nacos实现服务注册与发现> <支持的几种服务消费方式> <使 ...

  9. Linux中ELF格式 可执行文件+动态链接器 的加载

    两种加载方式 (1)加载可执行文件,通过PT_INTERP加载动态链接器 (2)直接加载动态链接器,再由其加载可执行文件 On a typical ELF system such as Linux, ...

  10. Linux复制文件到usb设备中,使用shell脚本实现USB设备的加载与文件复制

    使用shell脚本实现USB设备的加载与文件复制 在Linux操作系统中,如果插入一个USB设备,需要用mount挂载命令才能实现这个设备的加载,下面写一个USB设备挂载与文件复制的Shell程序,程 ...

最新文章

  1. spring-gateway(一)Reactor编程基础
  2. node-serialport —— Node.js 串口数据读写包
  3. 连载:阿里巴巴大数据实践—实时技术
  4. oracle or 循环 查询,Oracle的循环和Corsor
  5. 架构设计 | 分布式系统调度,Zookeeper集群化管理
  6. [导入]用ASP.Net(C#)连接Oracle数据库的方法
  7. Android Gradle动态打32位或者64位的包
  8. sql数据库自动备份
  9. APP图片加载库(框架)和缓存
  10. 博客9-12css2
  11. 页面性能优化办法有哪些?
  12. 《C++高级进阶》读书笔记 第一章 C++基础知识
  13. 谷歌离线版下载及vs中添加谷歌浏览器(启动项目用谷歌浏览)
  14. IEEP部署企业级网络工程-网络故障-环路故障
  15. 蒲公英wifi怎么卸载干净_蒲公英wifi怎么卸载干净
  16. iPhone用android充电头,iPhone 6s用什么充电头充电最快?安卓快充头可以混用吗?
  17. 关于Ajax请求服务器端的处理
  18. ZeroMQ教程中文版
  19. 天大的本事,顶不上一张会说话的嘴
  20. Ubuntu 安装MySQL 并设置其他主机可访问

热门文章

  1. 微信/钉钉电脑端登录后手机端不再提醒
  2. arduino继电器控制风扇_Arduino基础入门篇24—继电器控制
  3. 循环结构(计算0到100之间的奇数和偶数的和)
  4. 锐捷服务器无线认证配置,锐捷AC CMCC-WEB认证配置详解
  5. QQ小程序内测邀请码内部获取群
  6. 微软的teredo服务器,win10系统通过teredo连接ipv6的操作方法
  7. android ip v6 teredo,[转] 在家轻轻松松上IPv6站点之Teredo篇
  8. Android Jetpack架构组件之Room
  9. HTML中Form表单的使用
  10. GDS和OTA未来之路