2011-02-02 2 views
1

D 프로그래밍 언어로 SDL과 OpenGL을 사용하여 2D 게임을 작성하고 있습니다. 지금은 단순히 텍스처 매핑 된 쿼드를 화면에 렌더링하려고 시도합니다. 문제는 전체 텍스처 매핑 부분이 제대로 작동하지 않는 것입니다. 분명히로드하는 텍스처에도 (0이 아닌 텍스처 번호가 지정되고, glGetError가 0이 아닌 값을 반환하지는 않지만), 쿼드는 glColor에서 마지막으로 설정된 색상으로 렌더링되어 텍스처를 완전히 무시합니다.OpenGL 텍스처 맵핑이 고집스럽게 작동하지 않습니다.

this question을 포함하여 텍스처 매핑이 실패하는 일반적인 이유를 찾지 못했습니다. 로드되는 이미지 파일은 유효한 2의 거듭 제곱 크기 인 64x64입니다.

거의 완전히 C 스타일의 SDL 및 OpenGL 호출이기 때문에 두려워하지 마십시오.

SDL 초기화 코드 :

if (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) == -1 || 
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0) == -1) 
    throw new Exception("An OpenGL attribute could not be set!"); 

uint videoFlags = SDL_OPENGL | SDL_HWSURFACE | SDL_ANYFORMAT; 

if (threadsPerCPU() > 1) 
    videoFlags |= SDL_ASYNCBLIT; 

SDL_Surface* screen = SDL_SetVideoMode(800, 600, 32, videoFlags); 

if (screen == null) 
    throw new Exception("SDL_SetVideoMode failed!"); 

OpenGL을 초기화 코드 :

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glOrtho(0., 800, 600, 0., 0., 1.); 
glMatrixMode(GL_MODELVIEW); 

glDisable(GL_DEPTH_TEST); 
glDisable(GL_LIGHTING); 

glEnable(GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

glEnable(GL_TEXTURE_2D); 

glClearColor(0.f, 0.f, 0.f, 0.f); 

텍스처 로딩 코드 :

SDL_Surface* s = IMG_Load(toStringz("hello.png")); 

if (s == null) 
    throw new Exception("Image file could not be loaded!"); 

uint texFormat; 

switch (s.format.BytesPerPixel) 
{ 
case 4: 
    texFormat = (s.format.Rmask == 0x000000ff ? GL_RGBA : GL_BGRA); 
    break; 
case 3: 
    texFormat = (s.format.Rmask == 0x000000ff ? GL_RGB : GL_BGR); 
    break; 
default: 
    throw new Exception("Bad pixel format!"); 
    break; 
} 

if ((s.w & (s.w - 1)) != 0) 
    throw new Exception("Width must be a power of 2!"); 
if ((s.h & (s.h - 1)) != 0) 
    throw new Exception("Height must be a power of 2!"); 

uint glName; 

glGenTextures(1, &glName); 

glBindTexture(GL_TEXTURE_2D, glName); 
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
glTexImage2D(GL_TEXTURE_2D, 0, s.format.BytesPerPixel, s.w, s.h, 0, 
    texFormat, GL_UNSIGNED_BYTE, s.pixels); 

SDL_FreeSurface(s); 

렌더링 코드 :

glClear(GL_COLOR_BUFFER_BIT); 

glBegin(GL_QUADS); 
    glColor4ub(255, 255, 255, 255); 
    glBindTexture(GL_TEXTURE_2D, glName); 
    glTexCoord2i(0, 0); glVertex2i(0, 0); 
    glTexCoord2i(1, 0); glVertex2i(64, 0); 
    glTexCoord2i(1, 1); glVertex2i(64, 64); 
    glTexCoord2i(0, 1); glVertex2i(0, 64); 
glEnd(); 

SDL_GL_SwapBuffers(); 

내 프로그램은 D를 위해 SDL 및 OpenGL 바인딩을 제공하는 Derelict2 라이브러리를 사용합니다.

정확하게 여기에 무슨 문제가 있습니까?

편집 :

http://www.opengl.org/wiki/Common_Mistakes#Creating_a_Texture

내가 전에 glTexImage2D를 호출하거나 다른 나의 질감이 기술적으로 불완전에 몇 가지 매개 변수를 설정하는 데 필요한 : 미래 참고로, 여기 내 문제의 해결책입니다.

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
+0

glTexImage의 세 번째 매개 변수 인 "format"은 픽셀 당 바이트가 아닙니다. 역사적으로 값 1, 2, 3, 4는 OpenGL-1.0에 의해 수용되었습니다. OpenGL-1 이후.1 이후 형식 매개 변수는 숫자 형식이 실제 형식과 관련이없는 GL_RGBA, GL_RGB 등과 같이 잘 정의 된 토큰 만 받아들입니다. – datenwolf

+0

"OpenGL 초기화"개념을 잊어 버리십시오. 그렇습니다. 텍스처와 물건을로드합니다.하지만 실제 응용 프로그램에서는 이것이 한 번은 아니지만 필요할 때마다 발생합니다. 투영, 투명 색상, 뷰포트 등 모든 렌더링 상태는 렌더링 절차에서 필요하기 바로 전에 설정해야합니다. "OpenGL 초기화 코드"섹션에있는 모든 내용은 "렌더링 코드"섹션의 시작 부분에 속합니다. – datenwolf

+0

@datenwolf : 점 찍었습니다. 귀하의 첫 번째 의견에 관해서는, 내가 사용하고있는 문서는 구형이어야합니다. 그래서 대신 OpenGL enum 값 중 하나를 사용하도록 호출을 업데이트 할 것입니다. 두 번째 주석에 관해서는, 내 특정 응용 프로그램이 장면의 한 관점 만 사용하기 때문에 (즉, 정적 2D보기이므로) 프로젝션, 뷰포트 등과 같은 것들을 초기화 코드에 넣는 것이 내 응용 프로그램에서 적절하다고 생각합니다. 하드웨어 가속 2D 드로잉을 할 수 있습니다.) 나는 당신의 요점을 확실히 본다. – jgottula

답변

7

일반적인 실수 중 하나는 불완전한 질감을 만들거나 사용하는 것입니다 (here 참조). 어떤 밉맵 생성을 표시하지 않습니다 또한

glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR/*or GL_NEAREST*/); 
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*or GL_NEAREST*/); 

과 :

코드는 어떤 호출을 표시하지 않습니다.

텍스처가 불완전한 것과 관련된 문제 일 수 있습니다.

+0

와우, 네 말이 맞아. 연결된 페이지에 나열된 4 개의 선을 추가 한 후에 텍스처가 완전히 의도 한대로 렌더링됩니다. 저를 올바른 방향으로 이끌어 주셔서 감사합니다! – jgottula

+0

glGetError가 glTexImage2D 뒤에 아무 것도 나타내지 않은 이유가 궁금합니다. 아마도 사용 가능한 오류 코드는 이런 종류의 것을 다루지 않을 것입니다. 어쨌든 적어도 지금은 무언가가 작동하고 있으므로 나중에 밉맵이나 다른 수정에 대해 걱정할 수 있습니다. – jgottula

+0

hm, glTexImage2D는 텍스처를 생성하는 데 사용되는 오류를 표시하거나 감지 할 수 없으며 프로세스 중에는 불완전한 텍스처에 대해 '합법적'입니다. 아마도 'glBindTexture'는 이것을 오류로 감지 할 수 있지만 쉐이더처럼 밉맵 0에서만 텍스처를 샘플링하면 쉐이더처럼 작동하지 않을 수 있습니다. 일단이 문제로 여러 번 물린 적이 있다면 익숙해집니다.) – rotoglup

0

당신이 paintGL 기능에 glOrtho(0., 800, 600, 0., 0., 1.); 필요하지 않습니다 : 그 전화가 속임수를 썼는지 바로 전에 다음과 같은 네 가지 라인을 추가?

+0

확실히 화면상의 흰색 사각형이 나오기 때문에 이것이 아닌지 확실히 확인하십시오. glOrtho 문제는 장면의 위치/방향과 관련된 문제일까요? 맞습니까? – jgottula

1

막연한 이론이 있습니다. 시계 방향이 아닌 시계 반대 방향으로 정점 그리기를 시도해 보셨습니까?

glTexCoord2i(0, 0); glVertex2i(0, 0); 
glTexCoord2i(0, 1); glVertex2i(0, 64); 
glTexCoord2i(1, 1); glVertex2i(64, 64); 
glTexCoord2i(1, 0); glVertex2i(64, 0); 
+0

방금 ​​방향 변경으로 다시 컴파일되었습니다. 같은 거래. : – jgottula

+0

거기에 glBindTexture 호출에 대한 텍스처로드 코드 (적어도있는 위치에)? glTexImage2D 호출 후에 갈 것이라고 생각 했어? 그것은 OpenGL 함께 일한 이후로 꽤 오래되었습니다. – Xono

+0

@ xono :'glBindTexture' 호출은 OpenGL 상태 머신에게 "우리는이 텍스처로 작업 중"이라고 말하고, glTexImage2D 호출은 현재 바인드 된 텍스처에 적용되어야한다는 것을 암묵적으로 이해합니다. 만약 내가 틀렸다면, 물론. – jgottula

0

GL_COLOR_MATERIAL을 사용 설정 하시겠습니까? 잠시 동안 고정 기능 파이프 라인을 사용하지는 않았지만 그렇게 할 수도 있다고 생각합니다.

+0

'glEnable (GL_COLOR_MATERIAL)'을 내 init 코드에 추가했지만 불행히도 도움이되지 않습니다. – jgottula