17.OpenGL--替换纹理图像的全部或一部分

转载 2016年12月28日 19:30:26
  • 理论基础 
    和修改原有纹理相比,创建新纹理的开销更大。我们主要使用glTexSubImage*和glCopyTexSubImage*()来修改纹理,前者用于替换的纹理来源外部读取,后者替换的纹理来源自身帧缓冲区。

  • 实例代码
#include "GLTools.h"

#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif

#define checkImageWidth 64
#define checkImageHeight 64
#define subImageWidth 45
#define subImageHeight 45
static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
static GLubyte subImage[subImageHeight][subImageWidth][4];

static GLuint texName;

//纹理数据(黑白相间的棋盘和蓝色区域)
void makeCheckImages(void)
{
    int i, j, c;

    for (i = 0; i < checkImageHeight; i++) {
        for (j = 0; j < checkImageWidth; j++) {
            c = ((((i&0x8)==0)^((j&0x8))==0))*255;
            checkImage[i][j][0] = (GLubyte) c;
            checkImage[i][j][1] = (GLubyte) c;
            checkImage[i][j][2] = (GLubyte) c;
            checkImage[i][j][3] = (GLubyte) 255;
        }
    }
    for (i = 0; i < subImageHeight; i++) {
        for (j = 0; j < subImageWidth; j++) {
            subImage[i][j][0] = (GLubyte) 0;
            subImage[i][j][1] = (GLubyte) 0;
            subImage[i][j][2] = (GLubyte) 255;
            subImage[i][j][3] = (GLubyte) 255;
        }
    }
}

void init(void)
{
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
    glEnable(GL_DEPTH_TEST);

    makeCheckImages();
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    glGenTextures(1, &texName);
    glBindTexture(GL_TEXTURE_2D, texName);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight,
                 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    glBindTexture(GL_TEXTURE_2D, texName);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
    glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);
    glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);
    glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);

    glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
    glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);
    glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421);
    glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);
    glEnd();
    glFlush();
    glDisable(GL_TEXTURE_2D);
}

void reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -3.6);
}

void keyboard (unsigned char key, int x, int y)
{
    switch (key) {
        case 's':
        case 'S':
            //指定当前活动的纹理
            glBindTexture(GL_TEXTURE_2D, texName);
            /*用subImage纹理替换原纹理的(12,12)至
            (subImageWidth,subImageHeight)区域*/
            glTexSubImage2D(GL_TEXTURE_2D, 0, 12, 12, 
            subImageWidth, subImageHeight, 
            GL_RGBA,GL_UNSIGNED_BYTE, subImage);

            glutPostRedisplay();
            break;
        case 'r':
        case 'R':
            glBindTexture(GL_TEXTURE_2D, texName);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 
            checkImageWidth, checkImageHeight, 0, 
            GL_RGBA,GL_UNSIGNED_BYTE, checkImage);

            glutPostRedisplay();
            break;
        case 27:
            exit(0);
            break;
        default:
            break;
    }
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(250, 250);
    glutInitWindowPosition(100, 100);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
    glutMainLoop();
    return 0; 

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141

这里写图片描述

OGL纹理之纹理替换glTexSubImage2D/glCopyTexSubImage2D/纹理矩形

glTexSubImage2D函数 提供修改图像函数,因为修改一个纹理比重新创建一个纹理开销小得多,对于一些视频捕捉程序可以先将视频图像存储在更大的初始图像中(该图像大小要求是2的次方,OGL 2.0...
  • Blues1021
  • Blues1021
  • 2016-08-25 09:50:14
  • 5715

OpenGL绘制纹理时,glGenTextures()函数带来的内存泄露,使程序被杀死。

项目中,我需要定时的去更换纹理图片,贴到指定的位置。我就理所当然的写了一个函数,然后定时去执行一次该函数。 函数中有代码:             glPixelStorei(GL_UNPACK_...
  • gagabook
  • gagabook
  • 2016-09-02 13:58:55
  • 2065

OpenGL--替换纹理图像的全部或一部分

理论基础 和修改原有纹理相比,创建新纹理的开销更大。我们主要使用glTexSubImage*和glCopyTexSubImage*()来修改纹理,前者用于替换的纹理来源外部读取,后者替换的纹理来源自...
  • u010223072
  • u010223072
  • 2015-04-20 15:30:10
  • 2684

加载纹理与使用glGenTextures时应注意的一点(解决吃内存)[转]

加载纹理与使用glGenTextures时应注意的一点(解决吃内存)[转] glGenTextures   glGenTextures(GLsizei n, GLuint *te...
  • lovehota
  • lovehota
  • 2012-03-29 15:41:20
  • 7457

OpenGL的几何变换-纹理贴图

通过纹理贴图有两种方案: 1、图片分割化,即是把一张完整的全景图片(就是支持720度全景图片)人工的分隔成前后左右上下六张图片(静态),然后分别加载这六张图片; 2、数据分割化,即是保留一...
  • dcba2014
  • dcba2014
  • 2016-09-21 13:53:49
  • 641

《高效学习OpenGL》 之 纹理对象 glGenTextures(),glIsTexture(),glBindTexture(),glDeleteTextures()

命名纹理对象: void glGenTextures (GLsizei n, GLuint *textures); //在数组textures中返回n个当期未使用的值,表示纹理对象的名称...
  • huangbangqing12
  • huangbangqing12
  • 2014-02-28 11:25:08
  • 4428

OpenGL纹理详解(上)

转载自http://www.jianshu.com/p/1829b4acc58d,感谢原博主的指点,个人觉得这篇博文很适合初学者,特此转发。     写在前面的话     现实生活中,纹...
  • lhd_ustc
  • lhd_ustc
  • 2016-04-09 22:10:45
  • 1676

OpenGL深入探索——纹理加载(ImageMagick)与贴图

转载自:第十六课 基本的纹理贴图 背景 纹理贴图就是将任意一种类型的图片应用到 3D 模型的一个或多个面上。图片(也可以称之为纹理)内容可以是任何东西,但是他们一般都是一些比如砖,叶子,地面等的图案,...
  • panda1234lee
  • panda1234lee
  • 2016-06-23 19:25:04
  • 1474

OpenGL函数思考-glGenTextures

OpenGL函数思考-glGenTextures函数原型:      void glGenTextures(GLsizei n, GLuint *textures)参数说明:      n:用来生成纹...
  • shuaihj
  • shuaihj
  • 2012-02-09 09:37:32
  • 7987
收藏助手
不良信息举报
您举报文章:17.OpenGL--替换纹理图像的全部或一部分
举报原因:
原因补充:

(最多只允许输入30个字)