opengl学习笔记(四):openCV读入图片,openGL实现纹理贴图
在opengl中实现三维物体的纹理贴图的第一步就是要读入图片,然后指定该图片为纹理图片。
首先利用opencv的cvLoadImage函数把图像读入到内存中
- img = cvLoadImage("../shanghai.bmp", ); //读入彩色图
然后利用下面代码在内存中开辟一个跟读入图片大小相同的内存空间:
- #include <iostream>
- #include <GL/gl.h>
- #include <GL/glu.h>
- #include <opencv2/opencv.hpp>
- using namespace cv;
- using namespace std;
- /*
- Mat img = imread("../shanghai.bmp");
- int width = img.cols;
- int height = img.cols;
- GLubyte* pixels;
- GLuint load_texture(cv::Mat& image)
- {
- int width = image.cols;
- int height = image.cols;
- //OpenGL纹理用整型数表示
- GLuint texture_ID;
- //获取图像指针
- int pixellength = width*height*3;
- pixels = new GLubyte[pixellength];
- memcpy(pixels, image.data, pixellength * sizeof(unsigned char));
- //将texture_ID设置为2D纹理信息
- glGenTextures(1, &texture_ID);
- glBindTexture(GL_TEXTURE_2D, texture_ID);
- //纹理放大缩小使用线性插值
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels);
- free(pixels);
- return texture_ID;
- }
- void draw()
- {
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
- drawCameraFrame();
- glFlush();
- }
- void drawCameraFrame()
- {
- GLuint image = load_texture();
- if (!m_isTextureInitialized)
- {
- glGenTextures(1, &m_backgroundTextureId);
- glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- m_isTextureInitialized = true;
- }
- int w = m_backgroundTextureId.cols;
- int h = m_backgroundTextureId.rows;
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
- glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId);
- if (m_backgroundImage.channels() == 3)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, m_backgroundImage.data);
- else if(m_backgroundImage.channels() == 4)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_backgroundImage.data);
- else if (m_backgroundImage.channels()==1)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_backgroundImage.data);
- const GLfloat bgTextureVertices[] = { 0, 0, w, 0, 0, h, w, h };
- const GLfloat bgTextureCoords[] = { 1, 0, 1, 1, 0, 0, 0, 1 };
- const GLfloat proj[] = { 0, -2.f/w, 0, 0, -2.f/h, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1 };
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(proj);
- glMatrixMode(GL_MODEVIEW);
- glLoadIdentity();
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, bgTextureVertices);
- glTexCoordPointer(2, GL_FLOAT, 0, bgTextureCoords);
- glColor4f(1,1,1,1);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisable(GL_TEXTURE_2D);
- }
- void processVideo()
- {
- cv::Mat currentFrame;
- capture >> currentFrame;
- // Check the capture succeeded:
- if (currentFrame.empty())
- {
- std::cout << "Cannot open video capture device" << std::endl;
- return;
- }
- cv::Size frameSize(currentFrame.cols, currentFrame.rows);
- }
- bool processFrame(const cv::Mat& cameraFrame)
- {
- // Clone image used for background (we will draw overlay on it)
- cv::Mat img = cameraFrame.clone();
- // Set a new camera frame:
- drawingCtx.updateBackground(img);
- // Request redraw of the window:
- drawingCtx.updateWindow();
- }
- int main( int argc, char** argv)
- {
- cv::VideoCapture capture = cv::VideoCapture(1);
- cv::namedWindow(windowName, cv::WINDOW_OPENGL);
- cv::resizeWindow(windowName, frameSize.width, frameSize.height);
- cv::setOpenGlContext(windowName);
- cv::setOpenGlDrawCallback(windowName, draw, NULL);
- cv::updateWindow(windowName);
- }
- */
- Mat m_backgroundImage = imread("../shanghai.bmp");
- GLuint m_backgroundTextureId;
- void drawCameraFrame()
- {
- glGenTextures(, &m_backgroundTextureId);
- glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- int w = m_backgroundImage.cols;
- int h = m_backgroundImage.rows;
- glPixelStorei(GL_PACK_ALIGNMENT, );
- glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId);
- // Upload new texture data:
- glTexImage2D(GL_TEXTURE_2D, , GL_RGB, w, h, , GL_BGR_EXT, GL_UNSIGNED_BYTE, m_backgroundImage.data);
- //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_backgroundImage.data);
- //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_backgroundImage.data);
- const GLfloat bgTextureVertices[] = { , , w, , , h, w, h };
- const GLfloat bgTextureCoords[] = { , , , , , , , };
- const GLfloat proj[] = { , -.f/w, , , -.f/h, , , , , , , , , , , };
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(proj);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId);
- // Update attribute values.
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glVertexPointer(, GL_FLOAT, , bgTextureVertices);
- glTexCoordPointer(, GL_FLOAT, , bgTextureCoords);
- glColor4f(,,,);
- glDrawArrays(GL_TRIANGLE_STRIP, , );
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisable(GL_TEXTURE_2D);
- }
- void draw(void* param)
- {
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
- drawCameraFrame();
- glFlush();
- }
- int main ( int argc, char** argv )
- {
- cv::namedWindow("windowName", cv::WINDOW_OPENGL);
- cv::resizeWindow("windowName", m_backgroundImage.cols, m_backgroundImage.rows);
- cv::setOpenGlContext("windowName");
- cv::setOpenGlDrawCallback("windowName", draw, NULL);
- updateWindow("windowName");
- waitKey();
- return ;
- }
- /*
- #include <GL/glut.h>
- #include <GL/gl.h>
- #include <opencv2/cv.h>
- #include <opencv2/highgui/highgui.hpp>
- GLuint texture; //纹理图
- IplImage *img;
- unsigned char* textureImage;
- void makeTextureImg(IplImage *image)
- {
- int width = image->width;
- int height = image->height;
- CvScalar s;
- //读入彩色图
- textureImage = new unsigned char[width * height * 3];
- for (int i = 0; i < height; i++ )
- for (int j = 0; j < width; j++)
- {
- s = cvGet2D(image, i, j);
- textureImage[i * 3 * width + 3 * j] = s.val[0];
- textureImage[i * 3 * width + 3 * j + 1] = s.val[1];
- textureImage[i * 3 * width + 3 * j + 2] = s.val[2];
- }
- }
- int loadTexture(IplImage* image, GLuint* text)
- {
- if (image==NULL) return -1;
- glGenTextures(1, text);
- glBindTexture(GL_TEXTURE_2D, *text);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image->width, image->height, 0, GL_RGB, GL_UNSIGNED_BYTE, image->data);
- return 0;
- }
- void display()
- {
- glClearColor (0.0,0.0,0.0,1.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- }
- int main(int argc, char** argv)
- {
- glutInit (&argc, argv);
- glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE);
- glutInitWindowSize (500, 500);
- }
- */
程序运行结果如下:
参考博客:
https://blog.csdn.net/learn_sunzhuli/article/details/46642379
http://blog.sina.com.cn/s/blog_8d8425f30100yoi4.html
https://blog.csdn.net/u013898698/article/details/77164775
https://blog.csdn.net/wan_exe/article/details/70943020
代码下载:github
opengl学习笔记(四):openCV读入图片,openGL实现纹理贴图的更多相关文章
- OpenGL学习笔记3——缓冲区对象
在GL中特别提出了缓冲区对象这一概念,是针对提高绘图效率的一个手段.由于GL的架构是基于客户——服务器模型建立的,因此默认所有的绘图数据均是存储在本地客户端,通过GL内核渲染处理以后再将数据发往GPU ...
- OpenGL学习笔记:拾取与选择
转自:OpenGL学习笔记:拾取与选择 在开发OpenGL程序时,一个重要的问题就是互动,假设一个场景里面有很多元素,当用鼠标点击不同元素时,期待作出不同的反应,那么在OpenGL里面,是怎么知道我当 ...
- 基础学习笔记之opencv(6):实现将图片生成视频
基础学习笔记之opencv(6):实现将图片生成视频 在做实验的过程中.难免会读视频中的图片用来处理,相反将处理好的图片又整理输出为一个视频文件也是非经常常使用的. 以下就来讲讲基于opencv的C+ ...
- OpenGL学习笔记2017/8/29
OpenGL学习日志: 感谢doing5552 的OpenGL入门学习:http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html 相 ...
- 官网实例详解-目录和实例简介-keras学习笔记四
官网实例详解-目录和实例简介-keras学习笔记四 2018-06-11 10:36:18 wyx100 阅读数 4193更多 分类专栏: 人工智能 python 深度学习 keras 版权声明: ...
- C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻
前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
- Android学习笔记进阶之在图片上涂鸦(能清屏)
Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...
- IOS学习笔记(四)之UITextField和UITextView控件学习
IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...
- java之jvm学习笔记四(安全管理器)
java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
随机推荐
- 使用d3.v3插件绘制出svg图
众所周知,这个插件使用的svg技术,而IE8(包括IE8)之前的浏览器是不支持svg的 接下来看代码吧 从后台获取到带id和父id的目录数据[json格式] var module = requestU ...
- jquery组件WebUploader文件上传用法详解
这篇文章主要为大家详细介绍了jquery组件WebUploader文件上传用法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 WebUploader是由Baidu WebFE(FEX)团队开发的一 ...
- Dubbo -- 系统学习 笔记 -- 示例 -- 静态服务
Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 静态服务 有时候希望人工管理服务提供者的上线和下线,此时需将注册中心标识为非动态管 ...
- Yii 汉化翻译
一).首先创建一个zh_cn语言包.(参考网址:制作语言包) 1.复制framework\messages\config.php 文件到 protected\messages\下 2.更改config ...
- MongoDB文档的增删改操作
上一篇文章中介绍了MongoDB的一些基本知识,同时看到了怎么启动一个MongoDB服务,并且通过MongoDB自带的shell工具连接到了服务器. 这一次,就通过MongoDB shell介绍一下对 ...
- 关于openssl的编译与使用
关于openssl的编译与使用,可以参考这两往篇文章 http://blog.csdn.net/lazyclough/article/details/7456131 http://www.leaves ...
- mongodb命令(1)
成功启动MongoDB服务后,打开一个命令行窗口输入mongo,就可以进行数据库的一些操作. 输入help可以看到基本操作命令: show dbs:显示数据库列表 show collections:显 ...
- Netty权威指南之Netty入门程序
package com.hjp.netty.netty; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Chan ...
- PHP代码审计笔记--命令执行漏洞
命令执行漏洞,用户通过浏览器在远程服务器上执行任意系统命令,严格意义上,与代码执行漏洞还是有一定的区别. 0x01漏洞实例 例1: <?php $target=$_REQUEST['ip']; ...
- [Git] 解决 insufficient permission for adding an object to repository database
[环境] OS: CentOS 6.5 Git: 1.7.1 [症状描述] Git 中心仓库路径 ~/project.git,克隆库路径 ~/project.clone,克隆库中包含一个文件 ~/pr ...