zoukankan      html  css  js  c++  java
  • 关于Opengl中将24位BMP图片加入�一个alpha通道并实现透明的问题

    #include <windows.h>
    #include <GL/glut.h>
    #include <GL/glaux.h>
    #include <stdio.h>

    #pragma comment( lib, "opengl32.lib" )// 链接时使用OpenGL32.lib
    #pragma comment( lib, "glu32.lib" )// 链接时使用GLu32.lib 
    #pragma comment( lib, "glaux.lib" ) // 链接时使用GLaux.lib

    HWND hWnd;
    HDC hDC;
    HGLRC hRC=NULL;//定义渲染环境
    HINSTANCE hInstance;//得到程序的样例
    RECT rect;

    int sw = 600;
    int sh = 600;

    GLfloat aspect;
    GLfloat x1=0.0;
    GLfloat y1=0.0;
    GLfloat xrot;// X轴旋转
    GLfloat yrot;// Y轴旋转
    GLfloat z=8.0;// 移入屏幕的深度
    GLfloat x=0.0;
    GLfloat y=0.0;

    int LastXPos;
    int LastYPos;

    bool IsLBDown;
    bool light;//光源-开/关
    bool lp;//L键是否按下? 

    GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0 }; //环境光的值
    GLfloat LightDiffuse[]= { 1.0, 1.0, 1.0, 1.0 }; //散射光的值
    GLfloat LightPosition[]={ 0.0, 0.0, 2.0, 1.0 }; //光照位置

    GLubyte Pixel; 

    GLuint texture[8];//纹理的存储空间

    AUX_RGBImageRec *TextureImage[8];//为纹理创建存储空间

    int LoadGLTextures(int i,char *FileName)//调用Bitmap并转换成纹理
    {
    unsigned char *m_ucpData;
      unsigned int x,y,width,height;
    unsigned char tempRGB;
    unsigned char *buffer;
    FILE *fp;
    int Status=FALSE;//状态确定
    //-------------------------------读取位图,检查错误。假设位图不存在则退出
    if(TextureImage[i]=auxDIBImageLoad(FileName))
    {
    width=TextureImage[i]->sizeX; 
    height=TextureImage[i]->sizeY;
    Status=TRUE;//将Status设为TRUE
    fp=fopen(FileName,"a+b");
    if(!fp){
    fclose(fp);
    return false;
    }
    //----------------------------读取图片RGB信息
    m_ucpData=(unsigned char *)malloc(width*height*3);
    fseek(fp,54,SEEK_SET);//指针跳过文件头移动到指定位置
    fread(m_ucpData,sizeof(unsigned char),width*height*3,fp);//从指定位置读数据
    for (int imageIdx = 0; imageIdx < (width*height*3); imageIdx+=3)
    {
    tempRGB = m_ucpData[imageIdx];
    m_ucpData[imageIdx] = m_ucpData[imageIdx + 2];
    m_ucpData[imageIdx + 2] = tempRGB;
    }
    //-----------------------------将RGB改动成RGBA
    buffer = (unsigned char *)malloc(width*height*4);
    for(x=0,y=0; x<(width*height*3); x+=3,y+=4)
    {
    buffer[y] = m_ucpData[x];
    buffer[y+1] = m_ucpData[x+1];
    buffer[y+2] = m_ucpData[x+2];
    if(m_ucpData[x]==255 && m_ucpData[x+1]==255 && m_ucpData[x+2]==255)
    {
    buffer[y+3] = 0;
    }
    else
    buffer[y+3] = 1;
    }
    //改动过的RGBA内容回写到TextureImage[i]
    TextureImage[i]->data = (unsigned char *)realloc(TextureImage[i]->data,width*height*4);
    for(int a=0;a<width*height*4;a++)
    {
    TextureImage[i]->data[a] = buffer[a];
    if((a+1)%4==1)
    {
    int u=TextureImage[i]->data[a];
    }
    }

    glGenTextures(1, &texture[i]);//命名一个纹理
    glBindTexture(GL_TEXTURE_2D, texture[i]);//创建纹理对象
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//制定纹理的包装形式,指定颜色线形过滤
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); //MipMapped过滤
    gluBuild2DMipmaps(GL_TEXTURE_2D,3,width,height,GL_RGBA,GL_UNSIGNED_BYTE,TextureImage[i]->data);//把纹理缩放到适合大小 
    }
    else
    {
    if (TextureImage[i])//纹理是否存在
    {
    if (TextureImage[i]->data)
    {
    free(TextureImage[i]->data);//释放纹理图象所占用内存
    }
    else free(TextureImage[i]);//释放图象结构
    }
    else return Status;
    }
    fclose(fp);
      delete buffer;
    return Status;
    }
    void SceneInit(int w, int h)
    {
    LoadGLTextures(1,"obj_1.bmp");

    glEnable(GL_TEXTURE_2D);

    glEnable(GL_ALPHA_TEST); //透明部分測试
    glAlphaFunc(GL_GREATER,0.5); 

    glEnable(GL_BLEND);//启用混合
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

    glShadeModel(GL_SMOOTH);//同意平滑着色
    glClearColor( 0.0, 0.0, 0.0, 0.0);
    }
    void SceneResizeViewport(GLsizei w, GLsizei h)
    {
    if(h==0) 
    {
    h=1;
    }
    aspect = (GLfloat)w/(GLfloat)h;
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);//选择投影矩阵
    glLoadIdentity();//重置
    gluPerspective( 45.0, aspect, 0.1f, 100.0 );//设置透视,以45度角
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    }

    void SceneShow(GLvoid)//这里进行全部的画图工作
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清屏和清除深度缓冲区
    glLoadIdentity();//重置当前Modelview矩阵
    gluLookAt(x,y,z,x1,y1,-2.0,0.0,1.0,0.0);

      glBindTexture(GL_TEXTURE_2D, texture[1]);  
    glBegin(GL_QUADS);
    glNormal3f( 0.0, 0.0, 1.0);
    glTexCoord2f(1.0, 0.0); glVertex3f(-0.5, -1.0, 2.0);
    glTexCoord2f(1.0, 1.0); glVertex3f(-0.5, 0.0, 2.0);
    glTexCoord2f(0.0, 1.0); glVertex3f( 0.5, 0.0, 2.0);
    glTexCoord2f(0.0, 0.0); glVertex3f( 0.5, -1.0, 2.0);
    glEnd();

    glFlush();
    }
    //创建OPENGL窗体
    void EnableOpenGL()
    {
    PIXELFORMATDESCRIPTOR pfd;
    int iFormat;

    hDC = GetDC( hWnd );

    ZeroMemory( &pfd, sizeof( pfd ) );
    pfd.nSize = sizeof( pfd );
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW |
    PFD_SUPPORT_OPENGL |
    PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 32;
    pfd.cDepthBits = 32;
    pfd.iLayerType = PFD_MAIN_PLANE;

    iFormat = ChoosePixelFormat( hDC, &pfd );

    SetPixelFormat( hDC, iFormat, &pfd );

    hRC = wglCreateContext( hDC );
    wglMakeCurrent( hDC, hRC );
    }
    void DisableOpenGL()
    {
    wglMakeCurrent( NULL, NULL );
    wglDeleteContext( hRC );
    ReleaseDC( hWnd, hDC );
    }
    LRESULT CALLBACK WndProc( HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam )
    {
    switch ( message )
    {
    case WM_CREATE:  
    GetWindowRect(hWnd, &rect);
    sw = rect.right - rect.left;
    sh = rect.bottom - rect.top;
    SceneResizeViewport(sw, sh);
    return 0;
    case WM_SIZE://改变窗体的尺寸
    GetWindowRect(hWnd, &rect);
    sw = rect.right - rect.left;
    sh = rect.bottom - rect.top;
    if(sw>0 && sh>0)
    SceneResizeViewport(sw, sh);
    return 0;
    default:
    return DefWindowProc( hWnd,message, wParam, lParam );
    }
    }
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
    {
      WNDCLASS wc;
    MSG msg;
    bool bQuit = false;
    wc.style = CS_OWNDC;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
    wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "Name";
    RegisterClass( &wc );
    hWnd = CreateWindow("Name","Animation Tech_Base on 2D Images",
    WS_TILEDWINDOW | WS_VISIBLE,
    GetSystemMetrics( SM_CXSCREEN )/2-sw/2,
    GetSystemMetrics( SM_CYSCREEN )/2-sh/2,
    sw,sh,NULL,NULL,hInstance,NULL );
    ChangeDisplaySettings(NULL, 0);
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
    EnableOpenGL();
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
    SceneInit(sw, sh);
    GetWindowRect(hWnd, &rect);
    sw = rect.right - rect.left;
    sh = rect.bottom - rect.top;
    if(sw>0 && sh>0)
    SceneResizeViewport(sw, sh);
    while ( !bQuit )
    {
    if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
    if ( msg.message == WM_QUIT )
    bQuit = true;
    else 
    {
    TranslateMessage( &msg );
    DispatchMessage( &msg );
    }
    else
    {
    // OpenGL 动画
    SceneShow();
    SwapBuffers(hDC);//重绘函数
    }
    }
    //关闭,退出程序
    DisableOpenGL();
    ShowWindow (hWnd, SW_HIDE);
    DestroyWindow( hWnd );
    ChangeDisplaySettings(NULL, 0);
    return msg.wParam;
    return 0;

    }


    这是程序源码,在LoadGLTextures()函数里面
    已经对图片的每一个象素进行读取,加入�alpha通道,并回写到缓存里面,但是最后调用输出图片的时候却没有实现
    debug的时候确定每一个象素点的alpha通道都按要求改动了...
    请问大侠们我的问题到底出在哪里了?


  • 相关阅读:
    Atitit.ati orm的设计and架构总结 适用于java c# php版
    Atitit.ati dwr的原理and设计 attilax 总结 java php 版本
    Atitit.ati dwr的原理and设计 attilax 总结 java php 版本
    Atitit. 软件设计 模式 变量 方法 命名最佳实践 vp820 attilax总结命名表大全
    Atitit. 软件设计 模式 变量 方法 命名最佳实践 vp820 attilax总结命名表大全
    Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结
    Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结
    atitit.基于  Commons CLI 的命令行原理与 开发
    atitit.基于  Commons CLI 的命令行原理与 开发
    atitit.js 与c# java交互html5化的原理与总结.doc
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/3820951.html
Copyright © 2011-2022 走看看