2014-12-27 67 views
0

我開始使用opengl紋理,一切都運行良好。現在我正在嘗試加載bmp,並使用glEnable(GL_BLEND)使白色部分透明;和glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);C++ OpenGL位圖透明度問題

這是我的源代碼:

float kSpeedForw=0.0f; 
GLuint  texture[1]; 
CCamera g_Camera;         
GLfloat  xrot = 0;        
GLfloat  yrot = 0;       
GLfloat  zrot = 0;       
bool g_bFullScreen = true;        
HWND g_hWnd;          
RECT g_rRect;           
HDC g_hDC;           
HGLRC g_hRC;           
HINSTANCE g_hInstance;         
float jump = -0.1; 
GLfloat LightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f }; 
GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; 
GLfloat LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f }; 
void Init(HWND hWnd) 
{ 
glEnable(GL_TEXTURE_2D);       // Enable Texture Mapping 
glShadeModel(GL_SMOOTH);       // Enable Smooth Shading 
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);    // Black Background 
glClearDepth(1.0f);         // Depth Buffer Setup 
glEnable(GL_DEPTH_TEST);       // Enables Depth Testing 
glDepthFunc(GL_LEQUAL);        // The Type Of Depth Testing To Do 
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations 

glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);  // Setup The Ambient Light 
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);  // Setup The Diffuse Light 
glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); // Position The Light 
glEnable(GL_LIGHT1);        // Enable Light One 

glColor4f(1.0f, 1.0f, 1.0f, 0.5);     // Full Brightness. 50% Alpha 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
g_hWnd = hWnd;          
GetClientRect(g_hWnd, &g_rRect);     
InitializeOpenGL(g_rRect.right, g_rRect.bottom); 
g_Camera.PositionCamera(0, 1.5f, 6, 0, 1.5f, 5, 0, 1, 0); 
ShowCursor(false);      
} 
GLuint LoadTexture(const char * filename) 
{ 

glEnable(GL_TEXTURE_2D); 
GLuint texture; 

int width, height; 

unsigned char * data; 

FILE * file; 

file = fopen(filename, "rb"); 
if (file == NULL) return 0; 
if (filename=="Data/weed.bmp"){ 
    width = 200; 
    height = 200; 
} 
if (filename == "Data/gun.bmp"){ 
    width = 300; 
    height = 300; 
} 
data = (unsigned char *)malloc(width * height * 3); 
fread(data, width * height * 3, 1, file); 
fclose(file); 

for (int i = 0; i < width * height; ++i) 
{ 
    int index = i * 3; 
    unsigned char B, R; 
    B = data[index]; 
    R = data[index + 2]; 

    data[index] = R; 
    data[index + 2] = B; 

} 
if (filename == "Data/weed.bmp"){ 
    glGenTextures(1, &texture); 
    glBindTexture(GL_TEXTURE_2D, texture); 
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); 


    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); 
    free(data); 
} 
if (filename == "Data/gun.bmp"){ 
    glGenTextures(1, &texture); 
    glBindTexture(GL_TEXTURE_2D, texture); 
    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, 3,width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); 

} 


return texture; 
} 


WPARAM MainLoop() // main function 
{ 
MSG msg; 
Init(g_hWnd); 
glClearColor(0, 0, 255, 0); 
while (1)           
{             
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
    { 
     if (msg.message == WM_QUIT)     
      break; 
     TranslateMessage(&msg);     
     DispatchMessage(&msg);      
    } 
    else if (LockFrameRate(60))     
    { 
     g_Camera.SetViewByMouse();     
     kSpeedForw = 0; 
    if (jump > -0.1)jump-=0.01; 

     CheckForMovement();      


     g_Camera.MoveCamera(kSpeedForw, jump); 
     RenderScene();        
    } 
    } 

DeInit(); 
return(msg.wParam);        
} 
void RenderScene() 
{ 
glMatrixMode(GL_PROJECTION); 
glPopMatrix(); 
glMatrixMode(GL_MODELVIEW); 
glPopMatrix(); 
glDisable(GL_BLEND); 
glEnable(GL_SMOOTH); 
glEnable(GL_DEPTH_TEST); 
glEnable(GL_TEXTURE_2D); 

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glLoadIdentity();         
gluLookAt(g_Camera.m_vPosition.x, g_Camera.m_vPosition.y, g_Camera.m_vPosition.z, 
g_Camera.m_vView.x, g_Camera.m_vView.y, g_Camera.m_vView.z, 
g_Camera.m_vUpVector.x, g_Camera.m_vUpVector.y, g_Camera.m_vUpVector.z); 


GLuint texture; 
texture = LoadTexture("Data/weed.bmp"); 
glBindTexture(GL_TEXTURE_2D, texture); 
glBegin(GL_QUADS);        
float i = 0; 
glColor3f(1,1,1); 
glTexCoord2f(0.0f, 0.0f); 
glVertex3f(-10 + i/5, 0, 10 - i/5); 


glTexCoord2f(50.0f, 0.0f); 
glVertex3f(-10 + i/5, 0, -10 + i/5); 


glTexCoord2f(50.0f, 50.0f); 
glVertex3f(10 - i/5, 0, -10 + i/5); 


glTexCoord2f(0.0f, 50.0f); 
glVertex3f(10 - i/5, 0, 10 - i/5); 
glEnd();        
////////////////////////////////////////////////////////////HUD 
glDisable(GL_LIGHTING); 
glDisable(GL_TEXTURE_2D); 
glDisable(GL_DEPTH_TEST); 
glDisable(GL_SMOOTH); 
glEnable(GL_BLEND);   // Turn Blending On 

int vPort[4]; 

glGetIntegerv(GL_VIEWPORT, vPort); 

glMatrixMode(GL_PROJECTION); 
glPushMatrix(); 
glLoadIdentity(); 

glOrtho(0, vPort[2], 0, vPort[3], -1, 1); 
glMatrixMode(GL_MODELVIEW); 
glPushMatrix(); 
glLoadIdentity(); 

GLuint ruka; 
ruka = LoadTexture("Data/gun.bmp"); 
glBindTexture(GL_TEXTURE_2D, ruka); 
glBegin(GL_QUADS); 


glTexCoord2f(0.0f, 0.0f); 
glVertex2f(0, 0); 

glTexCoord2f(1.0f, 0.0f); 
glVertex2f(450,0); 

glTexCoord2f(1.0f, 1.0f); 
glVertex2f(450,450); 

glTexCoord2f(0.0f, 1.0f); 
glVertex2f(0,450); 
glEnd(); 



SwapBuffers(g_hDC); 
} 

的代碼可以很好地用於加載和渲染平臺(weed.bmp),也加載和呈現槍罰款。但gun.bmp的很大一部分是白色的。我希望能讓這部分透明。我也希望增加更多的HUD功能,這也需要部分透明。

我gun.bmp文件:https://drive.google.com/file/d/0BxxlNcAI0eh9cHZGd1ZfMTFwYmM/view?usp=sharing

如果你知道這個問題的解決方案,請張貼。謝謝

+0

我真的很想知道你希望white _magically_通過啓用'GL_BLEND'變得透明。 – derhass 2014-12-27 16:00:07

+0

我試着加載一個帶有alpha通道的32位bmp,並加載爲GL_RGBA,但它直接崩潰了。我不知道我是否在這裏錯過了一些東西,但如果是這樣,請向我解釋一下。我會非常感謝。 – user3000140 2014-12-27 16:05:56

+0

你應該使用一個實際的圖像加載庫(或一個較不容易混淆的文件擴展名)。我覺得這裏的「.bmp」文件實際上並不是* Device Independent Bitmap *。 DIB格式有一個複雜的頭,你必須處理,你也必須考慮4個字節的每行對齊(這裏不是一個問題,因爲200 * 3和300 * 3都可以被4除盡而沒有餘數)。 – 2014-12-27 16:25:09

回答

0

你加載圖像爲GL_RGB,你希望GL_RGBA有一個alpha通道。 此外,您需要一個32位位圖(8位/通道×4通道= 32位)。

+0

謝謝。其實,我曾嘗試過,但它導致了immediete崩潰 – user3000140 2014-12-27 15:54:44

+0

您必須使用32位位圖並讀取'width * height * 4'字節。 – kiwixz 2014-12-27 17:10:41

+0

是的,我確實使用了一個32位的位圖。它被加載爲GL_RGBA並被保存爲alpha通道。 – user3000140 2014-12-27 17:29:39