2014-12-27 2 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

'GL_BLEND'를 사용하여 흰색 _magically_이 투명 해지면 어떻게 될지 정말 궁금합니다. – derhass

+0

알파 채널이있는 32 비트 bmp를로드하고 GL_RGBA로로드하려고했지만 immedietely 충돌했습니다. 여기에 뭔가 빠졌는지 모르겠다. 그렇다면 나에게 설명해주세요. 나는 가장 감사 할 것입니다. – user3000140

+0

이 이미지를 위해 실제 이미지 로딩 라이브러리를 사용해야합니다 (혼란스럽지 않은 파일 확장자). 나는 당신의 ".bmp"파일이 실제로는 장치 독립 비트 맵 *이 아니라는 인상을받습니다. DIB 형식에는 처리해야 할 복잡한 헤더가 있으며 4 바이트 단위로 정렬해야합니다 (200 * 3 및 300 * 3은 모두 4로 나눌 수 있으므로 나머지는 고려하지 않음). –

답변

0

이미지를 GL_RGB로로드하면 GL_RGBA에 알파 채널이 필요합니다. 또한 32 비트 비트 맵 (8 비트/채널 × 4 채널 = 32 비트)이 필요합니다.

+0

감사합니다. 실제로, 나는 그것을 시도했지만 immediete crash가 발생했습니다. – user3000140

+0

32 비트 비트 맵을 사용하고'width * height * 4' 바이트를 읽어야합니다. – kiwixz

+0

예, 저는 32 비트 비트 맵을 사용했습니다. GL_RGBA로로드되어 알파 채널로 저장되었습니다. – user3000140