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通道都按要求改动了...
    请问大侠们我的问题到底出在哪里了?


  • 相关阅读:
    氚云CRM产品的详细介绍
    关于氚云PasS的介绍
    氚云tERP介绍
    转: Photon 3.4 Changed Logs ..
    DelphiXE5 Flappy Bird 复制版
    mono developer 无法启动 可以试试如下插件包.
    Happening in delphi world
    string manipulation in game development-C # in Unity
    Comparing Xamarin and Delphi XE5 to Xcode for Cross Platform Mobile App Development
    混用Application.LoadLevel 和 PhotonNetwork.LoadLevel
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4033192.html
Copyright © 2011-2022 走看看