关于Opengl中将24位BMP图片加入�一个alpha通道并实现透明的问题
生活随笔
收集整理的這篇文章主要介紹了
关于Opengl中将24位BMP图片加入�一个alpha通道并实现透明的问题
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
#include <windows.h>
#include <GL/glut.h>
#include <GL/glaux.h>
#include <stdio.h>
#pragma comment( lib, "opengl32.lib" )// 鏈接時(shí)使用OpenGL32.lib
#pragma comment( lib, "glu32.lib" )// 鏈接時(shí)使用GLu32.lib?
#pragma comment( lib, "glaux.lib" ) // 鏈接時(shí)使用GLaux.lib
HWND hWnd;
HDC hDC;
HGLRC hRC=NULL;//定義渲染環(huán)境
HINSTANCE hInstance;//得到程序的樣例
RECT rect;
int sw = 600;
int sh = 600;
GLfloat aspect;
GLfloat x1=0.0;
GLfloat y1=0.0;
GLfloat xrot;// X軸旋轉(zhuǎn)
GLfloat yrot;// Y軸旋轉(zhuǎn)
GLfloat z=8.0;// 移入屏幕的深度
GLfloat x=0.0;
GLfloat y=0.0;
int LastXPos;
int LastYPos;
bool IsLBDown;
bool light;//光源-開(kāi)/關(guān)
bool lp;//L鍵是否按下??
GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0 }; //環(huán)境光的值
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];//紋理的存儲(chǔ)空間
AUX_RGBImageRec *TextureImage[8];//為紋理創(chuàng)建存儲(chǔ)空間
int LoadGLTextures(int i,char *FileName)//調(diào)用Bitmap并轉(zhuǎn)換成紋理
{
unsigned char *m_ucpData;
? unsigned int x,y,width,height;
unsigned char tempRGB;
unsigned char *buffer;
FILE *fp;
int Status=FALSE;//狀態(tài)確定
//-------------------------------讀取位圖,檢查錯(cuò)誤。假設(shè)位圖不存在則退出
if(TextureImage[i]=auxDIBImageLoad(FileName))
{
width=TextureImage[i]->sizeX;?
height=TextureImage[i]->sizeY;
Status=TRUE;//將Status設(shè)為T(mén)RUE
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);//指針跳過(guò)文件頭移動(dòng)到指定位置
fread(m_ucpData,sizeof(unsigned char),width*height*3,fp);//從指定位置讀數(shù)據(jù)
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改動(dòng)成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;
}
//改動(dòng)過(guò)的RGBA內(nèi)容回寫(xiě)到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]);//命名一個(gè)紋理
glBindTexture(GL_TEXTURE_2D, texture[i]);//創(chuàng)建紋理對(duì)象
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//制定紋理的包裝形式,指定顏色線形過(guò)濾
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); //MipMapped過(guò)濾
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);//釋放紋理圖象所占用內(nèi)存
}
else free(TextureImage[i]);//釋放圖象結(jié)構(gòu)
}
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); //透明部分測(cè)試
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 );//設(shè)置透視,以45度角
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void SceneShow(GLvoid)//這里進(jìn)行全部的畫(huà)圖工作
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清屏和清除深度緩沖區(qū)
glLoadIdentity();//重置當(dāng)前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();
}
//創(chuàng)建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 動(dòng)畫(huà)
SceneShow();
SwapBuffers(hDC);//重繪函數(shù)
}
}
//關(guān)閉,退出程序
DisableOpenGL();
ShowWindow (hWnd, SW_HIDE);
DestroyWindow( hWnd );
ChangeDisplaySettings(NULL, 0);
return msg.wParam;
return 0;
#include <GL/glut.h>
#include <GL/glaux.h>
#include <stdio.h>
#pragma comment( lib, "opengl32.lib" )// 鏈接時(shí)使用OpenGL32.lib
#pragma comment( lib, "glu32.lib" )// 鏈接時(shí)使用GLu32.lib?
#pragma comment( lib, "glaux.lib" ) // 鏈接時(shí)使用GLaux.lib
HWND hWnd;
HDC hDC;
HGLRC hRC=NULL;//定義渲染環(huán)境
HINSTANCE hInstance;//得到程序的樣例
RECT rect;
int sw = 600;
int sh = 600;
GLfloat aspect;
GLfloat x1=0.0;
GLfloat y1=0.0;
GLfloat xrot;// X軸旋轉(zhuǎn)
GLfloat yrot;// Y軸旋轉(zhuǎn)
GLfloat z=8.0;// 移入屏幕的深度
GLfloat x=0.0;
GLfloat y=0.0;
int LastXPos;
int LastYPos;
bool IsLBDown;
bool light;//光源-開(kāi)/關(guān)
bool lp;//L鍵是否按下??
GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0 }; //環(huán)境光的值
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];//紋理的存儲(chǔ)空間
AUX_RGBImageRec *TextureImage[8];//為紋理創(chuàng)建存儲(chǔ)空間
int LoadGLTextures(int i,char *FileName)//調(diào)用Bitmap并轉(zhuǎn)換成紋理
{
unsigned char *m_ucpData;
? unsigned int x,y,width,height;
unsigned char tempRGB;
unsigned char *buffer;
FILE *fp;
int Status=FALSE;//狀態(tài)確定
//-------------------------------讀取位圖,檢查錯(cuò)誤。假設(shè)位圖不存在則退出
if(TextureImage[i]=auxDIBImageLoad(FileName))
{
width=TextureImage[i]->sizeX;?
height=TextureImage[i]->sizeY;
Status=TRUE;//將Status設(shè)為T(mén)RUE
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);//指針跳過(guò)文件頭移動(dòng)到指定位置
fread(m_ucpData,sizeof(unsigned char),width*height*3,fp);//從指定位置讀數(shù)據(jù)
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改動(dòng)成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;
}
//改動(dòng)過(guò)的RGBA內(nèi)容回寫(xiě)到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]);//命名一個(gè)紋理
glBindTexture(GL_TEXTURE_2D, texture[i]);//創(chuàng)建紋理對(duì)象
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//制定紋理的包裝形式,指定顏色線形過(guò)濾
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); //MipMapped過(guò)濾
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);//釋放紋理圖象所占用內(nèi)存
}
else free(TextureImage[i]);//釋放圖象結(jié)構(gòu)
}
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); //透明部分測(cè)試
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 );//設(shè)置透視,以45度角
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void SceneShow(GLvoid)//這里進(jìn)行全部的畫(huà)圖工作
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清屏和清除深度緩沖區(qū)
glLoadIdentity();//重置當(dāng)前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();
}
//創(chuàng)建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 動(dòng)畫(huà)
SceneShow();
SwapBuffers(hDC);//重繪函數(shù)
}
}
//關(guān)閉,退出程序
DisableOpenGL();
ShowWindow (hWnd, SW_HIDE);
DestroyWindow( hWnd );
ChangeDisplaySettings(NULL, 0);
return msg.wParam;
return 0;
}
這是程序源碼,在LoadGLTextures()函數(shù)里面
已經(jīng)對(duì)圖片的每一個(gè)象素進(jìn)行讀取,加入�alpha通道,并回寫(xiě)到緩存里面,但是最后調(diào)用輸出圖片的時(shí)候卻沒(méi)有實(shí)現(xiàn)
debug的時(shí)候確定每一個(gè)象素點(diǎn)的alpha通道都按要求改動(dòng)了...
請(qǐng)問(wèn)大俠們我的問(wèn)題到底出在哪里了?
轉(zhuǎn)載于:https://www.cnblogs.com/hrhguanli/p/3820951.html
總結(jié)
以上是生活随笔為你收集整理的关于Opengl中将24位BMP图片加入�一个alpha通道并实现透明的问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 调试端点没有效果
- 下一篇: 写在阿里去IOE一周年