Форум программистов, компьютерный форум, киберфорум
Java: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
-12 / 1 / 0
Регистрация: 11.02.2017
Сообщений: 246

Ошибка в текстурах

31.03.2020, 10:16. Показов 1346. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пытаюсь разобраться в примере создания текстуры. Вылезает ошибка:
Code
1
org.lwjgl.system.MemoryUtil.memAddress(MemoryUtil.java:740)
Code
1
java.lang.NullPointerException
на последней строке. В чем проблема? Не судите строго, только изучаю
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public Texture(ByteBuffer imageData) {
        try (MemoryStack stack = stackPush()) {
            IntBuffer w = stack.mallocInt(1);
            IntBuffer h = stack.mallocInt(1);
            IntBuffer avChannels = stack.mallocInt(1);
 
            // Decode texture image into a byte buffer
            ByteBuffer decodedImage = stbi_load_from_memory(imageData, w, h, avChannels, 4);
 
            this.width = w.get();
            this.height = h.get();
 
            // Create a new OpenGL texture 
            this.id = glGenTextures();
            // Bind the texture
            glBindTexture(GL_TEXTURE_2D, this.id);
 
            // Tell OpenGL how to unpack the RGBA bytes. Each component is 1 byte size
            glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            // Upload the texture data
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this.width, this.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, decodedImage);
            // Generate Mip Map
            glGenerateMipmap(GL_TEXTURE_2D);
            
            stbi_image_free(decodedImage);
        }
    }
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
31.03.2020, 10:16
Ответы с готовыми решениями:

Шумы в текстурах
Как убрать шумы в текстурах на нереальном движке 4?

Сетка на текстурах
Здравствуйте! Обратил внимание, что на дальних текстурах видна квадратная сетка, горизонтальные и вертикальные полосы, на ближних...

Застревания в текстурах QGraphicsPixmapItem
Всем привет. Пишу примитивную игрушку. По полю ездит танк, отстреливается от танков врагов. Сейчас у меня этап создания стен и самое...

5
Модератор
Эксперт Java
 Аватар для alecss131
2880 / 1384 / 411
Регистрация: 11.08.2017
Сообщений: 4,413
Записей в блоге: 2
31.03.2020, 13:14
А позиция буфера (который imageData) перед этим "сброшена" в 0? то есть вызван ли метод flip()?
И после такой настройки всегда стоит вызывать glBindTexture(GL_TEXTURE_2D, 0); как минимум чтобы случайно не испортить текстуру. Ну или использовать DSA из opengl 4.5+
0
-12 / 1 / 0
Регистрация: 11.02.2017
Сообщений: 246
31.03.2020, 14:03  [ТС]
Не понял. Так? Отрисовывается чёрная фигура:-)
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private static ByteBuffer loadTextureToByteBuffer(String path) {
        ByteBuffer image;
        try (MemoryStack stack = MemoryStack.stackPush()) {
            IntBuffer w = stack.mallocInt(1);
            IntBuffer h = stack.mallocInt(1);
            IntBuffer comp = stack.mallocInt(1);
 
            stbi_set_flip_vertically_on_load(true);
            image = stbi_load(path, w, h, comp, 4);
            if (image == null) {
                System.out.println("Ошибка загрузки файла текстуры! "
                                           + System.lineSeparator() + stbi_failure_reason());
            }
            image.flip();
        }
        return image;
    }
сюда
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public Texture(ByteBuffer imageData) {
        try (MemoryStack stack = stackPush()) {
            IntBuffer w = stack.mallocInt(1);
            IntBuffer h = stack.mallocInt(1);
            IntBuffer avChannels = stack.mallocInt(1);
 
            // Decode texture image into a byte buffer
            ByteBuffer decodedImage = stbi_load_from_memory(imageData, w, h, avChannels, 4);
 
            this.width = w.get();
            this.height = h.get();
 
            // Create a new OpenGL texture 
            this.id = glGenTextures();
            // Bind the texture
            glBindTexture(GL_TEXTURE_2D, this.id);
 
            // Tell OpenGL how to unpack the RGBA bytes. Each component is 1 byte size
            glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            // Upload the texture data
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this.width, this.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, decodedImage);
            // Generate Mip Map
            glGenerateMipmap(GL_TEXTURE_2D);
            glBindTexture(GL_TEXTURE_2D, 0);
            stbi_image_free(decodedImage);
        }
    }
0
Модератор
Эксперт Java
 Аватар для alecss131
2880 / 1384 / 411
Регистрация: 11.08.2017
Сообщений: 4,413
Записей в блоге: 2
31.03.2020, 14:23
Откуда картинку грузите? Если просто с диска то используйте просто stbi_load(fileName, w, h, channels, 4);, а если из ресурсов то тут stb не поможет, надо руками создать ByteBuffer и из него уже грузить используя stbi_load_from_memory(imageData, w, h, avChannels, 4);
А то выходит вы пытаетесь загрузить изображение уже из загруженного изображения, это если применить сначала первый код, а потом второй. То есть выходы у методов stbi_load и stbi_load_from_memory идентичны и представляют собой массив чисел на каждый пиксель, первый грузит из файла а второй из памяти (по сути тупо скопированное изображение из файла в память БЕЗ ОБРАБОТКИ).
Если использовать stbi_load_from_memory то картинку в память можно загрузить например так:
Java
1
2
3
4
5
6
7
8
9
byte[] data = Files.ReadAllBytes(new File(name).toPath());
ByteBuffer buf = memAlloc(data.length);
buf.put(data).flip();
ByteBuffer texture = stbi_load_from_memory(buf, w, h, c, STBI_rgb_alpha);
width = w.get(0);
height = h.get(0);
memFree(buf);
...
stbi_image_free(texture);
Для загрузки из ресурсов такие способы не подойдут, надо брать InputStream и руками читать оттуда байты в массив. Я для этого использую либу commons-io bи код получается таким
Java
1
2
3
4
5
byte[] data = IOUtils.resourceToByteArray(name);
ByteBuffer buf = memAlloc(data.length);
buf.put(data).flip();
ByteBuffer texture = stbi_load_from_memory(buf, w, h, c, STBI_rgb_alpha);
...
И еще совет, не стоит бездумно распоряжаться этими буферами, они не очищаются сборщиком мусора (так как расположены вне кучи), происходит утечка памяти их стоит руками чистить сразу после использования (если больше не нужны)
0
-12 / 1 / 0
Регистрация: 11.02.2017
Сообщений: 246
31.03.2020, 14:37  [ТС]
Имеется ввиду этот вариант?
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public static ByteBuffer ioResourceToByteBuffer(String resource, int bufferSize) throws IOException {
        ByteBuffer buffer;
 
        Path path = Paths.get(resource);
        if (Files.isReadable(path)) {
            try (SeekableByteChannel fc = Files.newByteChannel(path)) {
                buffer = MemoryUtil.memAlloc((int) fc.size() + 1);
                while (fc.read(buffer) != -1) ;
            }
        } else {
            try (
                InputStream source = Texture.class.getResourceAsStream(resource);
                ReadableByteChannel rbc = Channels.newChannel(source)) {
                buffer = MemoryUtil.memAlloc(bufferSize);
 
                while (true) {
                    int bytes = rbc.read(buffer);
                    if (bytes == -1) {
                        break;
                    }
                    if (buffer.remaining() == 0) {
                        buffer = resizeBuffer(buffer, buffer.capacity() * 2);
                    }
                }
            }
        }
 
        buffer.flip();
        return buffer;
    }
    
    private static ByteBuffer resizeBuffer(ByteBuffer buffer, int newCapacity) {
        ByteBuffer newBuffer = BufferUtils.createByteBuffer(newCapacity);
        buffer.flip();
        newBuffer.put(buffer);
        return newBuffer;
    }
0
Модератор
Эксперт Java
 Аватар для alecss131
2880 / 1384 / 411
Регистрация: 11.08.2017
Сообщений: 4,413
Записей в блоге: 2
31.03.2020, 15:06
Лучший ответ Сообщение было отмечено EugeneV как решение

Решение

Он, но он имхо слишком громоздкий
Вот так я гружу изображения, вариант на 3 версии
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import static org.lwjgl.stb.STBImage.*;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.system.MemoryUtil.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL12.GL_CLAMP_TO_EDGE;
import static org.lwjgl.opengl.GL30.glGenerateMipmap;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.apache.commons.io.IOUtils;
import org.lwjgl.system.MemoryStack;
 
public class Texture {
    private int width;
    private int height;
    private int id;
    
    public Texture(String name) {
        try (MemoryStack stack = stackPush()) {
            IntBuffer w = stack.mallocInt(1);
            IntBuffer h = stack.mallocInt(1);
            IntBuffer c = stack.mallocInt(1);
            byte[] data = IOUtils.resourceToByteArray(name);
            ByteBuffer buf = memAlloc(data.length);
            buf.put(data).flip();
            ByteBuffer texture = stbi_load_from_memory(buf, w, h, c, STBI_rgb_alpha);
            width = w.get(0);
            height = h.get(0);
            memFree(buf);
            id = createTexture(texture, width, height);
            stbi_image_free(texture);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    protected int createTexture(ByteBuffer buf, int width, int height) {
        int textureId = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, textureId);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
        glGenerateMipmap(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, 0);
        return textureId;
    }
    
    public int getWidth() {
        return this.width;
    }
 
    public int getHeight() {
        return this.height;
    }
 
    public void bind() {
        glBindTexture(GL_TEXTURE_2D, id);
    }
    
    public void unbind() {
        glBindTexture(GL_TEXTURE_2D, 0);
    }
 
    public int getId() {
        return id;
    }
    
    public void cleanUp() {
        glDeleteTextures(id);
    }
}

Вариант на 4.5 версии с dsa
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import static org.lwjgl.stb.STBImage.*;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.system.MemoryUtil.*;
import static org.lwjgl.opengl.GL45.*;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.apache.commons.io.IOUtils;
import org.lwjgl.system.MemoryStack;
 
public class Texture {
    private int width;
    private int height;
    private int id;
    
    public Texture(String name) {
        try (MemoryStack stack = stackPush()) {
            IntBuffer w = stack.mallocInt(1);
            IntBuffer h = stack.mallocInt(1);
            IntBuffer c = stack.mallocInt(1);
            byte[] data = IOUtils.resourceToByteArray(name);
            ByteBuffer buf = memAlloc(data.length);
            buf.put(data).flip();
            ByteBuffer texture = stbi_load_from_memory(buf, w, h, c, STBI_rgb_alpha);
            width = w.get(0);
            height = h.get(0);
            memFree(buf);
            id = createTexture(texture, width, height);
            stbi_image_free(texture);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private int createTexture(ByteBuffer buf, int width, int height) {
        int textureId = glCreateTextures(GL_TEXTURE_2D);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        glTextureParameteri(textureId, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTextureParameteri(textureId, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTextureParameteri(textureId, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
        glTextureParameteri(textureId, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTextureStorage2D(textureId, 1, GL_RGBA8, width, height);
        glTextureSubImage2D(textureId, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buf);
        glGenerateTextureMipmap(textureId);
        return textureId;
    }
    
    public int getWidth() {
        return this.width;
    }
 
    public int getHeight() {
        return this.height;
    }
 
    public void bind() {
        glBindTexture(GL_TEXTURE_2D, id);
    }
    
    public void unbind() {
        glBindTexture(GL_TEXTURE_2D, 0);
    }
 
    public int getId() {
        return id;
    }
    
    public void cleanUp() {
        glDeleteTextures(id);
    }
}

Основная разница в том что использование dsa ближе к ооп и более безопасно, нечто похожее можно сделать и с геометрией
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
31.03.2020, 15:06
Помогаю со студенческими работами здесь

О текстурах в среде Dev C++
Раскажите пожалуйста подробнее о загрузке текстур и наложениние их на 3d-объекты в OpenGl.

C++ Сглаживание, белые края на круглых текстурах с альфоканалом
glBindTexture(GL_TEXTURE_2D, tSmallTWave); glEnable(GL_TEXTURE_2D); glColor4f(1.0,1.0,1.0,wTornado.alpha); //Малое торнадо (Волны)...

Неправильный цвет в текстурах при работе с FBO
Товарищи, помогите разобраться, пожалуйста в проблеме: при построении карты строится мозаика 3х3 из 9 текстур с использованием FBO, видна в...

При продолжительной игры в GTA V начинают появляться редкие полосы в текстурах или падает видеодрайвер
Здравствуйте. Расскажу все сначала. Недавно, при продолжительной игры (часа 2-3) в GTA V (Единственное во что играю), начинали появляться...

"Полоски" на текстурах в играх, GTX 1060 6gb
Доброго времени суток. Недавно купил новую видеокарту GTX 1060 6gb, в некоторых играх наблюдаю "артефакты" на текстурах подобно...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru