在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实现纹理贴图的更多相关文章

  1. OpenGL学习笔记3——缓冲区对象

    在GL中特别提出了缓冲区对象这一概念,是针对提高绘图效率的一个手段.由于GL的架构是基于客户——服务器模型建立的,因此默认所有的绘图数据均是存储在本地客户端,通过GL内核渲染处理以后再将数据发往GPU ...

  2. OpenGL学习笔记:拾取与选择

    转自:OpenGL学习笔记:拾取与选择 在开发OpenGL程序时,一个重要的问题就是互动,假设一个场景里面有很多元素,当用鼠标点击不同元素时,期待作出不同的反应,那么在OpenGL里面,是怎么知道我当 ...

  3. 基础学习笔记之opencv(6):实现将图片生成视频

    基础学习笔记之opencv(6):实现将图片生成视频 在做实验的过程中.难免会读视频中的图片用来处理,相反将处理好的图片又整理输出为一个视频文件也是非经常常使用的. 以下就来讲讲基于opencv的C+ ...

  4. OpenGL学习笔记2017/8/29

    OpenGL学习日志: 感谢doing5552 的OpenGL入门学习:http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html 相 ...

  5. 官网实例详解-目录和实例简介-keras学习笔记四

    官网实例详解-目录和实例简介-keras学习笔记四 2018-06-11 10:36:18 wyx100 阅读数 4193更多 分类专栏: 人工智能 python 深度学习 keras   版权声明: ...

  6. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  7. Android学习笔记进阶之在图片上涂鸦(能清屏)

    Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...

  8. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  9. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  10. Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

随机推荐

  1. 【nginx】nginx tomcat session 共享配置

    tomcat,redis下载忽略. 一.从github上下载源码,https://github.com/jcoleman/tomcat-redis-session-manager, 将源码复制到开发工 ...

  2. Linux服务器部署 Elasticsearch 成功,本机却访问不了

    Elasticsearch版本: elasticsearch- 服务器版本: CentOS release 6.8 (Final) 问题: Linux服务器上部署了 Elasticsearch 5.5 ...

  3. Java获取一维数组的最小值

    编写程序,实现接受用户在文本框中输入的单行数据.这些数据都是整数数字,以空格进行分隔,空格数量不限.并将这些数据分割成一维数组,再从数组中提取最小值显示在界面中.思路是先对用户的输入进行验证,即先用t ...

  4. 【Java知识点专项练习】之 volatile 关键字的功能

    volatile是java中的一个类型修饰符.它是被设计用来修饰被不同线程访问和修改的变量.如果不加入volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器 失去大量优化的机会. ...

  5. 【数据处理】SQL Server高效大数据量存储方案SqlBulkCopy

    要求将Excel数据,大批量的导入到数据库中,尽量少的访问数据库,高性能的对数据库进行存储. 一个比较好的解决方案,就是采用SqlBulkCopy来处理存储数据. SqlBulkCopy存储大批量的数 ...

  6. Android开发训练之第五章第三节——Transferring Data Without Draining the Battery

    Transferring Data Without Draining the Battery GET STARTED DEPENDENCIES AND PREREQUISITES Android 2. ...

  7. WP8.1学习系列(第八章)——透视Pivot设计指南

    在本文中 描述 应做事项和禁止事项 其他使用指南 相关主题 重要的 API Pivot class (XAML) PivotItem class (XAML) Windows Phone 应用:具有透 ...

  8. Qt编写视频播放器(vlc内核)

    在研究qt+vlc的过程中,就想直接做个播放器用于独立的项目,vlc还支持硬件加速,不过部分电脑硬件不支持除外.用vlc的内核写播放器就是快,直接调用api就行,逻辑处理和ui展示基本上分分钟的事情, ...

  9. 删除RHSA文件方法

    DEL /F /A /Q \\?\%1RD /S /Q \\?\%1新建一个批处理文件,包含上面两行代码,然后将要删除的文件拖放进里面就OK!

  10. Android Studio项目提交(或更新)到github的方法

    一 配置github登陆信息 二 上传工程到github 1. 2. 点击Share按钮 3. 点击ok按钮 状态栏提示: 4. 点击 No 按钮 5.AS右下脚弹出提示框 查看github网站,已经 ...