Я пишу 2D игры с использованием SDL и OpenGL на языке программирования D. На данный момент он просто пытается отобразить квадрат с отображением текстуры на экран. Проблема в том, что вся часть текстурирования не работает. Несмотря на то, что текстура явно загружается штрафом (получает ненулевой номер текстуры, не приводит к тому, что glGetError возвращает значения, отличные от нуля), квадрат отображается с последним цветом, установленным в glColor, полностью игнорируя текстуру.OpenGL текстурирование упорно отказывается работать
Я искал общие причины для сопоставления текстур с ошибкой, включая this question, но безрезультатно. Загружаемый файл изображения - 64x64, действительный размер в 2 раза.
Пожалуйста, не пугайтесь, потому что это в D-это почти полностью 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);
Texture загрузки Код:
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);
Rendering Код:
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();
Моя программа использует Derelict2, библиотеку, которая обеспечивает привязки SDL и OpenGL для D.
Любые идеи о том, что здесь происходит здесь?
Edit: На будущее, вот решение моей проблемы:
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);
3-й параметр glTexImage, «формат» IS NOT байтов на пиксель. Исторически значения 1, 2, 3, 4 были приняты OpenGL-1.0. Начиная с OpenGL-1.1 и далее параметр формата принимает только четко определенные токены, такие как GL_RGBA, GL_RGB и т. Д., Какое числовое значение не имеет отношения к фактическому формату. – datenwolf
Пожалуйста, забудьте о концепции «OpenGL initialization». Да, вы загружаете текстуры и прочее, но в любом реальном приложении это не одно время, но происходит по требованию. Все состояние рендеринга, то есть проекция, прозрачный цвет, область просмотра и т. Д., Должны быть установлены прямо до того, как они понадобятся в процедуре визуализации. Все материалы, которые вы разместили в разделе «Код инициализации OpenGL», относятся к началу раздела «Код визуализации». – datenwolf
@ datenwolf: Полученные очки. Что касается вашего первого комментария, документы, которые я использовал, должны быть устаревшими, поэтому я буду обновлять вызов, чтобы использовать одно из значений переименования OpenGL. Что касается второго комментария, я думаю, что в моем конкретном приложении уместно объединить такие вещи, как проекция, просмотр и т. Д. В код инициализации, но только потому, что мое конкретное приложение использует только одну перспективу сцены (просто статическое 2D-представление, Я могу сделать 2D-чертеж с аппаратным ускорением). Я определенно вижу вашу точку зрения. – jgottula