Загрузка текстуры с использованием функции OIL OIL и OpenGL

У меня есть функция для загрузки текстуры из изображения JPEG с использованием SOIL.

До сих пор я загружал текстуру с SOIL_load_image() функция, а затем поставка изображения в OpenGL с помощью glTexImage2D (см. код ниже). Тем не мение! Мои текстуры перевернуты, поэтому я хотел использовать SOIL_load_OGL_texture() вместо этого и поставьте SOIL_FLAG_INVERT_Y чтобы перевернуть изображения. Моя проблема заключается в том, что я получаю необработанное исключение на SOIL_load_OGL_texture() функция.

Код является почти копией из документации, поэтому я не понимаю, почему возникает эта ошибка?

(ПРИМЕЧАНИЕ: я мог инвертировать текстуры в моем вершинном шейдере, но я бы хотел использовать SOIL.)

По старому

int width;
int height;

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);

image = SOIL_load_image(filename, &width, &height, 0, SOIL_LOAD_RGB);

if (image == NULL) {
std::cout << "An error occurred while loading image." << std::endl;
exit(EXIT_FAILURE);
}
std::cout << "Loaded first texture image" << std::endl;

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);

Что я сейчас пытаюсь

GLuint image;

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);

image = SOIL_load_OGL_texture(
filename,
SOIL_LOAD_RGB,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_INVERT_Y
);

if (image == 0)
cerr << "SOIL loading error: '" << SOIL_last_result() << "' (" << "res_texture.png" << ")" << endl;

И ошибка

Unhandled exception at 0x0F5427FF (msvcr110d.dll) in AnotherTutorial.exe: 0xC0000005: Access violation reading location 0x00000000.

3

Решение

Похоже, что нет никакого ответа на использование SOIL, поэтому я опубликую свое решение:

В вершинном шейдере я делаю:

Texcoord = vec2(texcoord.x, 1.0-texcoord.y);
gl_Position = proj * view * model * vec4( position, 1.0 );

1.0-texcoord.y инвертирует ось Y изображения. Не как чистое решение, но оно работает.

1

Другие решения

void loadTexture(GLuint* texture, char* path){
*texture = SOIL_load_OGL_texture(filename,
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_MULTIPLY_ALPHA
);
if(*textre == NULL){
printf("[Texture loader] \"%s\" failed to load!\n", filename);
}
}

void drawTexturedRect(int x, int y, int w, int h, GLuint texture){
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
glBegin(GL_QUADS);
glColor3f(255,255,255);
glTexCoord2f(0,0);
glVertex2f(x,y);
glTexCoord2f(1,0);
glVertex2f(x+w,y);
glTexCoord2f(0,1);
glVertex2f(x,y+h);
glTexCoord2f(1,1);
glVertex2f(x+w,y+h);
glTexCoord2f(0,1);
glVertex2f(x,y+h);
glEnd();
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
}

И тогда вы можете сделать:

// At initialization
GLuint texture;
loadTexture(&texture, "filename.png");

// Drawing part
drawTexturedRect(25,25,256,256,texture);

Это то, что я лично использую, и это прекрасно работает. Я использую Visual Studio 2012 в сочетании с SDL и SOIL.

1

SOIL_load_image вернусь unsigned char* да, массив, содержащий данные вашего изображения.

Затем вы будете нормально передавать эти данные gl с помощью glGenerateTextures, назначить идентификаторы текстуры, вызов glTexImage2D,

SOIL_load_OGL_texture возвращает идентификатор текстуры, так что вы можете сделать это вместо этого:

texture[0] = SOIL_load_OGL_texture(...)

если ваша цель — загрузить текстуры 0,1,2.

Что касается инвертирования y, самое простое и невесомое решение — перевернуть координаты текстуры в glTexCoord, но это зависит от того, что вы делаете. Если вы загружаете ресурсы как единовременную операцию или тому подобное, это не повредит, за исключением некоторого времени запуска, которое, вероятно, не стоит упоминать. Но если вы загружаете ресурсы динамически через основной цикл, когда это необходимо, то инвертирующий флаг y (и любой другой флаг) может снизить производительность из-за дополнительной обработки всей вашей программы.

Одно большое преимущество использования SOIL_load_image является то, что вы можете получить ширину, высоту и номер канала из исходного изображения, которое SOIL_load_OGL_texture не предоставляет.

Если это поможет, SOIL_load_OGL_texture произойдет сбой через некоторое время при загрузке изображений RGB как RGB, но работает нормально все время с SOIL_LOAD_RGBA, это может быть решением вашей проблемы.

Мне все еще легче с SOIL_load_image, Я надеюсь, что все это поможет. Также проверьте исходный код SOIL, который поставляется с почвой, чтобы увидеть, что происходит.

0

В основном в команде

SOIL_load_image(filename, &width, &height, 0, SOIL_LOAD_RGB);

0 (NULL), который вы передаете, является указателем на каналы, установленные библиотекой, поэтому, конечно, когда библиотека пытается получить к ней доступ, у вас есть:

Необработанное исключение в 0x0F5427FF (msvcr110d.dll) в
AnotherTutorial.exe: 0xC0000005: место чтения нарушения прав доступа
0x00000000

Попробуйте объявить переменную и использовать ее:

int channels;
SOIL_load_image(filename, &width, &height, &channels, SOIL_LOAD_RGB);
0

Ни одно из решений выше не работает для меня.
У меня сейчас такая же проблема, как у следующего:

SOIL_load_OGL_texture Unhandled exception at xxxxxx (msvcr120d.dll)

После прочтения решения на http://www.idevgames.com/forums/thread-10281.html,
я изменил свой путь с «относительного пути» на «абсолютный путь».

Кстати, так как я китаец, мне нужно убедиться, что путь ВСЕ АНГЛИЙСКИЙ без символов ascii.

Например:

Я меняю свой код с

SOIL_load_OGL_texture("my_texture.bmp",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_MULTIPLY_ALPHA
);

в

SOIL_load_OGL_texture("D:\temp_20160926\ConsoleApplication20\ConsoleApplication19\my_texture.bmp",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_MULTIPLY_ALPHA
);

И это решит мою проблему отлично.

Я думаю, что это ошибка / ограничение в почве. Но вы можете избежать этого, определив абсолютный путь, как я делаю здесь.

Надеюсь, что это может помочь вам тоже.

0
По вопросам рекламы [email protected]