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 ...
随机推荐
- [原]unity3d调用android webView
1.配置dialog xml文件: <resources> <style name="dialogStyleWindow" parent="@an ...
- ios开发之--AVAudioPlayer/AVPlayer的应用
项目当中用到了音频播放器,所以就参考官方文档,写了一个,代码如下: .h #import <UIKit/UIKit.h> @interface hAudioPlayViewControll ...
- zabbix的启动和关闭脚本
1. zabbix客户端的系统服务脚本 1.1 拷贝启动脚本 zabbix的源码提供了系统服务脚本,在/usr/local/src/zabbix-3.2.6/misc/init.d目录下,我的系统是C ...
- 在javaweb的项目当中实现随机数字的生成
首先,需要在javaweb的项目当中新建一个Servlet文件,然后再web.xml中配置一下: 这样运行的时候就可以通过“http://localhost:8080/Response/Respons ...
- GDI+ gif文件的显示和格式转换
GDI+ gif文件的显示和格式转换 gdi+imagedeletenulltiff GDI+ gif文件的显示和格式转换 怎么获取gif文件的每一帧,并且显示出来呢? 1.怎么用gid+显示gi ...
- Java中过滤器和拦截器的区别
1.拦截器是基于java反射机制的,而过滤器是基于函数回调的. 2.过滤器依赖于servlet容器,而拦截器不依赖于servlet容器. 3.拦截器只对action起作用,而过滤器几乎可以对所有请求起 ...
- Eclipse新建动态web工程项目出现红叉解决方案
问题描述:之前新建动态web工程一直没有问题,今天新建一个项目后项目名称上突然出现小红叉,子目录文件没有红叉. 解决过程:一开始想到的就是编译器的level设置,调整了一下,仍然没有解决. 然后在标记 ...
- Swift - static和class的使用
Swift中表示 “类型范围作用域” 这一概念有两个不同的关键字,它们分别是static和class.这两个关键字确实都表达了这个意思,但是在其他一些语言,包括Objective-C中,我们并不会特别 ...
- 《转载》脚本实现从客户端服务端HTTP请求快速分析
本文转载自https://www.imooc.com/article/14107 首先我想介绍下,分享这个脚本的用处: 当客户告知我们,一个页面http://www.xxx.com 有问题时,作为PE ...
- Windows 下 Tomcat 添加为系统服务
标记一下,以便以后查看 setclasspath.bat 第一行插入 SET JAVA_HOME=C:\Program Files\Java\jre1.8.0_51 service.bat 第一行插入 ...