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 ...
随机推荐
- SpringBoot------thymeleaf的使用
1.pom.xml添加相应依赖 <dependency> <groupId>org.springframework.boot</groupId> <artif ...
- 8 -- 深入使用Spring -- 7...1 启动Spring 容器
8.7.1 启动Spring容器 对于使用Spring的Web应用,无须手动创建Spring容器,而是通过配置文件声明式地创建Spring容器.因此,在Web应用中创建Spring容器有如下两种方式: ...
- 基础SELECT实例
SELECT查询语句 ---进行单条记录.多条记录.单表.多表.子查询…… SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIORITY] [MAX_ST ...
- Nginx 域名重定向
假设 www.old.com 为旧的域名,而 www.new.com 为新的域名,要实现当我们访问 new 的时候自动重定向到 old 域名,配置如下: server { //第一种配置方法 serv ...
- U3D的有限状态机系统
或许广大程序员之前接触过游戏状态机,这已不是个新鲜的词汇了.其重要性我也不必多说了,但今天我要讲到的一个状态机框架或许您以前并未遇到过.所以,我觉得有必要将自己的心得分享一下.下面是一个链接:http ...
- 《Mysql 入门很简单》(读后感①)
下载完整版<Mysql 入门很简单>,点击这里~: http://files.cnblogs.com/files/zhengyeye/MySQL%E5%85%A5%E9%97%A8%E5% ...
- VC++进行窗口枚举
https://blog.csdn.net/u012372584/article/details/53735242 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...
- ios设备唯一标识获取策略
In iOS 7 and later, if you ask for the MAC address of an iOS device, the system returns the value 02 ...
- c++ auto 理解
for (auto i : b) Fuck(i); 是 for (auto bitch = std::begin(b); bitch != std::end(b); bitch++) { auto t ...
- Message Queue
RabbitMQ 是使用Erlang编写的一个开源的消息队列,本身支持很多的协议:AMQP,XMPP, SMTP, STOMP,也正是如此,使的它变的非常重量级,更适合于企业级的开发.同时实现了一个经 ...