PNG, загруженный с SDL_image с ошибками glTexImage2D - PullRequest
0 голосов
/ 10 ноября 2018

Не думаю, что это проблема с загружаемым изображением. Разрешение изображения составляет 256x256, так что это не сила 2 вопроса. Я смотрел на другие segfaults, которые люди получили с glTexImage2D, и segfault все еще не может исчезнуть. Извините, что код не написан на C / C ++ (я тоже не думаю, что это проблема), но его все равно должно быть легко понять.

let surface = sdlimage.load("image.png") # equivalent to IMG_Load call in C
if surface.isNil:
  echo "Image couldn't be loaded: ", sdl2.getError()
  quit 1

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_BLEND)

var tex: cuint
glGenTextures(1, addr tex)
glBindTexture(GL_TEXTURE_2D, tex)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
glPixelStorei(GL_UNPACK_ROW_LENGTH, surface.pitch)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA.GLint, surface.w.GLsizei, surface.h.GLsizei, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface.pixels) # segfault

UPDATE:

Мне удалось сделать так, чтобы он не стал segfault благодаря ответу user1118321 (я проверил формат пикселя и увидел, что SDL использует «индексированный» формат, который, как я видел, другой пользователь сказал, был проблемой, когда они сами исправили эту проблему. Кажется, вроде создания новой поверхности - правильное решение), но теперь на экране ничего не отображается. Он черный, когда я установил glClearColor на черный, и белый, когда я установил glClearColor на белый.

Обновлен код загрузки изображения:

let surface = sdlimage.load("image.png")
if surface.isNil:
  echo "Image couldn't be loaded: ", sdl2.getError()
  quit 1

var w = surface.w # may need to make this the next power of two
var h = surface.h # and this
var bpp: cint
var Rmask, Gmask, Bmask, Amask: uint32
if not pixelFormatEnumToMasks(SDL_PIXELFORMAT_ABGR8888, bpp,
  Rmask, Gmask, Bmask, Amask):
  quit "pixel format enum to masks " & $sdl2.getError()

let newSurface = createRGBSurface(0, w, h, bpp,
  Rmask, Gmask, Bmask, Amask)

discard surface.setSurfaceAlphaMod(0xFF)
discard surface.setSurfaceBlendMode(BlendMode_None)

blitSurface(surface, nil, newSurface, nil)

var tex: cuint
glGenTextures(1, addr tex)
glBindTexture(GL_TEXTURE_2D, tex)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, 4, w.GLsizei, h.GLsizei, 0, GL_RGBA, GL_UNSIGNED_BYTE, newSurface.pixels)

Код рендеринга изображения:

glUseProgram(shaderProgram)
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(0.0, 0.0, -7.0)
glColor3f(1.0, 1.0, 1.0)
glBegin(GL_QUADS)
glTexCoord2i(0, 0)
glVertex3f(-0.5, -1.9, 0.0)
glTexCoord2i(1, 0)
glVertex3f(0.5, -1.9, 0.0)
glTexCoord2i(0, 1)
glVertex3f(-0.5, -1.4, 0.0)
glTexCoord2i(1, 1)
glVertex3f(0.5, -1.4, 0.0)
glEnd()

Если шейдеры как-то связаны с этим, вот мой вершинный шейдер:

#version 330 core
in vec4 data;
out vec3 ourColor;
void main() {
  gl_Position = vec4(data.x, data.y, data.z, 1.0);
  ourColor = vec3(data.w, data.w, data.w);
}

И фрагмент шейдера:

#version 330 core
precision highp float;
in vec3 ourColor;
out vec4 color;
void main() {
  color = vec4(ourColor, 1.0);
}

1 Ответ

0 голосов
/ 11 ноября 2018

Вы должны проверить glGetError(), чтобы увидеть, есть ли какие-либо ошибки OpenGL. Вы также должны проверить surface.pixelFormat, чтобы увидеть, есть ли у вас 4 байта на пиксель в вашем изображении. Если это просто данные RGB, а не RGBA, то glTexImage2D() будет считывать данные конца изображения и, вероятно, завершится с ошибкой сегментации.

...