qq349263818
小笨笨不懂编程
2021-06-16 11:33
采纳率: 0%
浏览 90

opengles获取纹理数据运算并装载

现有接口  

GLuint onProcess(GLuint textureID, CGFloat width, CGFloat height)
{
    //textureID为纹理ID,此纹理已有图片数据,格式为 GL_TEXTURE_2D, RGBA
    //width 为图片宽度,height为图片高度

    提问:我如何在此处获取 textureID 对应纹理的数据进行矢量运算,再装载回原来的纹理

    return textureID;

}

 

我的做法是:

GLuint onProcess(GLuint textureID, CGFloat width, CGFloat height)
{
    static GLubyte buffer[2048*2048*4] = {0};
    glBindTexture(GL_TEXTURE_2D, textureID);
    glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    int nCount = width * height * 4;
    for (int i = 0; i < nCount; i++)
    {
        buffer[i] = 255;
    }

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    return textureID;

}

   

    

然后发现没用,请问要怎么做?

 

  • 点赞
  • 收藏

2条回答 默认 最新

  • Tao_improvement
    ipv-tao 2021-06-16 12:43
    点赞 评论
  • Feng_wwf
    NDSC专家-王文峯 2021-06-16 15:28

    试一试这个

    // BMPLoader.h
    
    #pragma once
    
    #include "stdafx.h"
    #define BITMAP_ID 0x4D42
    
    class CBMPLoader
    {
    public:
    CBMPLoader(void);
    ~CBMPLoader(void);
    
    bool LoadBitmap(const char *filename);      // 装载一个bmp文件
    void FreeImage();           // 释放图像数据
    bool Load(const char *fileName);       // 载入位图并创建纹理
    
    GLuint ID;             // 生成纹理的ID号
    int imageWidth;            // 图像宽度
    int imageHeight;           // 图像高度
    unsigned char *image;          // 指向图像数据的指针
    };
    
    // BMPLoader.cpp
    
    #include "BMPLoader.h"
    
    CBMPLoader::CBMPLoader(void)
    {
    // 初始化成员值为0
    image = NULL;
    imageWidth = 0;
    imageHeight = 0;
    }
    
    CBMPLoader::~CBMPLoader(void)
    {
    FreeImage();            // 释放图像数据占据的内存
    }
    
    // 装载一个位图文件
    bool CBMPLoader::LoadBitmap(const char *file)
    {
    FILE *pFile = NULL;           // 文件指针
    
    // 创建位图文件信息和位图文件头结构
    BITMAPINFOHEADER bitmapInfoHeader;
    BITMAPFILEHEADER header;
    
    unsigned char textureColors = 0;       // 用于将图像颜色从BGR变换到RGB
    
    // 打开文件,并检查错误
    pFile = fopen(file, "rb");
    if (pFile == NULL) return false;
    
    // 读入位图文件头信息
    fread(&header, sizeof(BITMAPFILEHEADER), 1, pFile);
    // 检查该文件是否为位图文件
    if (header.bfType != BITMAP_ID)
    {
       fclose(pFile);           // 若不是位图文件,则关闭文件并返回
       return false;
    }
    
    // 读入位图文件信息
    fread(&bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);
    // 保存图像的宽度和高度
    imageWidth = bitmapInfoHeader.biWidth;
    imageHeight = bitmapInfoHeader.biHeight;
    // 确保读取数据的大小
    if (bitmapInfoHeader.biSizeImage == NULL)
       bitmapInfoHeader.biSizeImage = bitmapInfoHeader.biWidth * bitmapInfoHeader.biHeight * 3;
    
    // 将指针移到数据开始位置
    fseek(pFile, header.bfOffBits, SEEK_SET);
    // 分配内存
    image = new unsigned char[bitmapInfoHeader.biSizeImage];
    // 检查内存分配是否成功
    if(!image)             // 若分配内存失败则返回
    {
       delete[] image;
       fclose(pFile);
       return false;
    }
    
    // 读取图像数据
    fread(image, 1, bitmapInfoHeader.biSizeImage, pFile);
    // 将图像颜色数据格式进行交换,由BGR转换为RGB
    for(int index = 0; index < (int)bitmapInfoHeader.biSizeImage; index+=3)
    {
       textureColors = image[index];
       image[index] = image[index + 2];
       image[index + 2] = textureColors;
    }
    
    fclose(pFile);            // 关闭文件
    return true;            // 成功返回
    }
    
    // 载入位图文件,并创建纹理
    bool CBMPLoader::Load(const char *fileName)
    {
    if (!LoadBitmap(fileName)) return false;
    // 生成纹理对象名称
    glGenTextures(1, &ID);
    // 创建纹理对象
    glBindTexture(GL_TEXTURE_2D, ID);
    // 控制滤波
    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);
    // 创建纹理
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, imageWidth, imageHeight, GL_RGB, GL_UNSIGNED_BYTE, image);
    return true;
    }
    
    // 释放内存
    void CBMPLoader::FreeImage()
    {
    // 释放分配的内存
    if(image)
    {
       delete []image;
       image = NULL;
    }
    }
    
    // TGALoader.h
    
    #pragma once
    #include "stdafx.h"
    
    class CTGALoader
    {
    public:
    CTGALoader(void);
    ~CTGALoader(void);
    
    bool LoadTGA(const char *file);        // 载入TGA文件
    void FreeImage();           // 释放内存
    bool Load(const char *fileName);       // 载入TGA文件为纹理
    
    GLuint ID;             // 生成纹理的ID号
    int imageWidth;            // 图像宽度
    int imageHeight;           // 图像高度
    unsigned char *image;          // 指向图像数据的指针
    unsigned int type;           // 图象类型GL_RGB 或GL_RGBA
    };
    
    // TGALoader.cpp
    
    #include "TGALoader.h"
    
    CTGALoader::CTGALoader(void)
    {
    // 设置为默认值
    image = NULL;
    type = 0;
    ID = -1;
    imageWidth = 0;
    imageHeight = 0;
    }
    
    CTGALoader::~CTGALoader(void)
    {
    FreeImage();            // 释放内存
    }
    
    // 载入TGA文件
    bool CTGALoader::LoadTGA(const char *file)
    {
    FILE *pfile;
    unsigned char tempColor;         // 用于交换颜色分量
    unsigned char bitCount;          // 每象素的bit位数
    int colorMode;            // 颜色模式
    long tgaSize;            // TGA文件大小
    unsigned char unCompressHeader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                    // 未压缩TGA文件头
    unsigned char tgaHeader[12];        // 文件头
    unsigned char header[6];         // 文件头前6个字节
    
    // 检查文件名是否为空
    if (file == NULL) return false;
    
    // 打开文件
    pfile = fopen(file, "rb");
    if (pfile == NULL) 
       return false;
    
    // 读取文件头前12个字节
    fread(tgaHeader, 1, sizeof(tgaHeader), pfile);
    
    // 比较文件是否为未压缩文件
    if(memcmp(unCompressHeader, tgaHeader, sizeof(unCompressHeader)) != 0)
    {
       MessageBox(NULL,"文件类型错误!","错误",MB_OK);
       fclose(pfile);
       return false;
    }
    
    // 读取6个字节
    fread(header, 1, sizeof(header), pfile);
    
    // 计算图像的宽度和高度
    imageWidth = header[1] * 256 + header[0];
    imageHeight = header[3] * 256 + header[2];
    
    // 获取每象素的bit位数
    bitCount = header[4];
    // 计算颜色模式和图像大小
    colorMode = bitCount / 8;
    tgaSize = imageWidth * imageHeight * colorMode;
    
    // 分配内存
    image = new unsigned char[sizeof(unsigned char) * tgaSize];
    // 读取数据
    fread(image, sizeof(unsigned char), tgaSize, pfile);
    
    // 将BGA格式转化为RGA格式
    for(long index = 0; index < tgaSize; index += colorMode)
    {
       tempColor = image[index];
       image[index] = image[index + 2];
       image[index + 2] = tempColor;
    }
    
    // 关闭文件
    fclose(pfile);
    
    // 设置图象类型
    if(colorMode == 3) type = GL_RGB;
    else type = GL_RGBA;
    
    return true;
    }
    
    // 载入TGA文件并创建纹理
    bool CTGALoader::Load(const char *fileName)
    {
    if (LoadTGA(fileName) == false) return false;
    
    // 生成纹理对象名称
    glGenTextures(1, &ID);
    // 创建纹理对象
    glBindTexture(GL_TEXTURE_2D, ID);
    // 控制滤波
    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);
    // 创建纹理
    gluBuild2DMipmaps(GL_TEXTURE_2D, type, imageWidth, imageHeight, type, GL_UNSIGNED_BYTE, image);
    
    return true;
    }
    
    void CTGALoader::FreeImage()
    {
    // 释放内存
    if(image)
    {
       delete []image;
       image = 0;
    }
    }
    
    // Texture.h
    
    #pragma once
    #include "glframe.h"
    #include "BMPLoader.h"
    #include "TGALoader.h"
    
    class Texture : public GLApplication
    {
    public:
    ~Texture(void);
    
    bool Init();            // 执行所有的初始化工作,如果成功函数返回true
    void Uninit();            // 执行所有的卸载工作
    void Update(DWORD milliseconds);       // 执行所有的更新操作,传入的参数为两次操作经过的时间,以毫秒为单位
    void Draw();            // 执行所有的绘制操作
    
    bool    LoadTexture();          // 载入纹理
    void    SetLight();           // 设置光源
    void    DrawSphere();          // 绘制球体
    void    DrawBox();           // 绘制木箱
    
    private:
    friend class GLApplication;         // 父类为它的一个友元类,可以用来创建程序的实例
    Texture(const char *class_name);       // 构造函数
    
    // 用户自定义的程序变量
    CBMPLoader texture1[6];          // 位图载入类
    CTGALoader texture2;          // TGA文件载入类
    float rot;             // 用于旋转物体
    GLUquadricObj *sphere;
    };
    
    // Texture.cpp
    
    #include "Texture.h"
    
    Texture::~Texture(void)
    {
    }
    
    // 创建一个程序的实例
    GLApplication * GLApplication::Create(const char *class_name)
    {
    Texture *test = new Texture(class_name);
    return reinterpret_cast<GLApplication *>(test);
    }
    
    // 构造函数
    Texture::Texture(const char *class_name) : GLApplication(class_name)
    {
    // 初始化用户自定义的程序变量
    rot = 0.0;
    }
    
    // 载入纹理数据
    bool Texture::LoadTexture()
    {
    CString str;
    // 载入位图文件
    for (int i = 0; i < 6; i++)
    {
       str.Format("data/%d.bmp", i);
       if (texture1[i].Load(str) == false)
       {
        MessageBox(NULL, "装载BMP文件失败!", "错误", MB_OK);
        return false;          // 如果载入失败则弹出对话框并返回失败
       
       }
    }
    // 载入TGA文件
    if (texture2.Load("data/map.tga") == false)     // 载入TGA文件
    {
       MessageBox(NULL, "装载TGA文件失败!", "错误", MB_OK); // 如果载入失败则弹出对话框
       return false;
    }
    
    // 启用纹理映射
    glEnable(GL_TEXTURE_2D);
    return true;
    }
    
    // 设置光源
    void Texture::SetLight()
    {
    // 定义光源的属性值
    GLfloat LightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f }; // 环境光参数
    GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; // 漫射光参数
    GLfloat LightSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; // 镜面光参数
    GLfloat LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f }; // 光源位置
    
    // 设置光源的属性值
    glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);    // 设置环境光
    glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);    // 设置漫射光
    glLightfv(GL_LIGHT1, GL_SPECULAR, LightSpecular);   // 设置漫射光
    glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);   // 设置光源位置
    
    // 启用光源
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT1);
    }
    
    // 初始化OpenGL
    bool Texture::Init()
    {
    // 载入纹理
    if (!LoadTexture()) 
    {
       MessageBox(NULL, "载入纹理失败!", "错误", MB_OK);
       return false;
    }
    
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    glClearDepth(1.0f);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_SMOOTH);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);   
    ResizeDraw(true);           // 改变OpenGL窗口大小,直接调用子类的函数
    
    sphere = gluNewQuadric();
    // 设置光源
    SetLight();
    return true;            // 成功返回
    }
    
    // 用户自定义的卸载函数
    void Texture::Uninit()         
    {
    // 用户自定义的卸载过程
    for (int i = 0; i < 6; i++)
    {
       texture1[i].FreeImage();        // 释放纹理图像占用的内存
       glDeleteTextures(1, &texture1[i].ID);     // 删除纹理对象
    }
    
    texture2.FreeImage();          // 释放纹理图像占用的内存
    glDeleteTextures(1, &texture2.ID);       // 删除纹理对象
    
    gluDeleteQuadric(sphere);
    }
    
    // 程序更新函数
    void Texture::Update(DWORD milliseconds)      
    {
    if (m_Keys.IsPressed(VK_ESCAPE) == true)     // 按ESC退出
       TerminateApplication();         
    if (m_Keys.IsPressed(VK_F1) == true)      // 按F1在窗口和全屏间切换
       ToggleFullscreen();         
    
    rot += milliseconds / 20.0f;
    }
    
    // 绘制球体
    void Texture::DrawSphere()
    {
    glPushMatrix();
    glTranslatef(2.0f, 0.0f, -10.0f);
    glRotatef(rot, 0.0f, 1.0f, 1.0f);
    
    // 指定纹理
    glBindTexture(GL_TEXTURE_2D, texture2.ID);
    gluQuadricOrientation(sphere, GLU_OUTSIDE);
    gluQuadricNormals(sphere, GLU_SMOOTH);
    gluQuadricTexture(sphere, GL_TRUE);
    gluSphere(sphere, 1.5, 50, 50);
    glPopMatrix();
    }
    
    // 绘制木箱
    void Texture::DrawBox()
    {
    // 设置材质属性
    GLfloat mat_ambient[] = { 0.8f, 0.8f, 0.8f, 1.0f };
    GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    
    glPushMatrix();
    glTranslatef(-2.0f, 0.0f, -8.0f);
    glRotatef(rot, 1.0f, 1.0f, 0.0f);
    
    // 选择纹理
    glBindTexture(GL_TEXTURE_2D, texture1[0].ID);
    glBegin(GL_QUADS);
    // 前侧面
    glNormal3f(0.0f, 0.0f, 1.0f);        // 指定法线指向观察者
    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
    glEnd();
    
    glBindTexture(GL_TEXTURE_2D, texture1[1].ID);
    glBegin(GL_QUADS);
    // 后侧面
    glNormal3f(0.0f, 0.0f,-1.0f);        // 指定法线背向观察者
    glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); 
    glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); 
    glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); 
    glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
    glEnd();
    
    glBindTexture(GL_TEXTURE_2D, texture1[2].ID);
    glBegin(GL_QUADS);
    // 顶面
    glNormal3f(0.0f, 1.0f, 0.0f);        // 指定法线向上
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); 
    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); 
    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); 
    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
    glEnd();
    
    glBindTexture(GL_TEXTURE_2D, texture1[3].ID);
    glBegin(GL_QUADS);
    // 底面
    glNormal3f(0.0f,-1.0f, 0.0f);        // 指定法线朝下
    glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); 
    glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); 
    glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); 
    glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
    glEnd();
    
    glBindTexture(GL_TEXTURE_2D, texture1[4].ID);
    glBegin(GL_QUADS);
    // 右侧面
    glNormal3f(1.0f, 0.0f, 0.0f);        // 指定法线朝右
    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); 
    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); 
    glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); 
    glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
    glEnd();
    
    glBindTexture(GL_TEXTURE_2D, texture1[5].ID);
    glBegin(GL_QUADS);
    // 左侧面
    glNormal3f(-1.0f, 0.0f, 0.0f);        // 指定法线朝左
    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); 
    glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); 
    glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); 
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
    glEnd();
    
    glPopMatrix();
    }
    
    // 绘制函数
    void Texture::Draw()
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    
    // 绘制过程
    DrawSphere();
    DrawBox();
    }

    望采纳,谢谢!

    点赞 评论

相关推荐