Шейдеры GLSL [ч.2 - Добавление в игру] [upd: ч.2.5 - логирование ошибок]

Шейдеры GLSL [ч.2 - Добавление в игру] [upd: ч.2.5 - логирование ошибок]

Icosider

Kotliner
Администратор
3,603
99
664
Уже было по этому поводу (но автор так и не подправил):

Ждём.
Ну ок, без б.

Царский подгон:
Java:
package ru.ivasik.sg.client.program;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

@SideOnly(Side.CLIENT)
public final class ShaderProgram
{
    private IUniforms uniforms;
    private int program, fsh, vsh;
    private IAttributes attributes;

    public ShaderProgram(String fsh, String vsh) throws IOException
    {
        if (fsh != null)
            this.fsh = loadShader(read(fsh + ".frag"), GL20.GL_FRAGMENT_SHADER);

        if (vsh != null)
            this.vsh = loadShader(read(vsh + ".vert"), GL20.GL_VERTEX_SHADER);

        this.program = GL20.glCreateProgram();

        if (fsh != null)
            GL20.glAttachShader(program, this.fsh);

        if (vsh != null)
            GL20.glAttachShader(program, this.vsh);

        if (attributes != null)
            attributes.add();

        GL20.glLinkProgram(program);

        if (fsh != null)
            GL20.glDetachShader(program, this.fsh);

        if (vsh != null)
            GL20.glDetachShader(program, this.vsh);

        GL20.glValidateProgram(program);

        if (uniforms != null)
            uniforms.add();
    }

    public ShaderProgram(String fav) throws IOException
    {
        this(fav, fav);
    }

    public void setAttributes(IAttributes attributes)
    {
        this.attributes = attributes;
    }

    public void setUniforms(IUniforms uniforms)
    {
        this.uniforms = uniforms;
    }

    public void addAttribute(int id, String name)
    {
        GL20.glBindAttribLocation(program, id, name);
    }

    public int getUniform(String name)
    {
        return GL20.glGetUniformLocation(program, name);
    }

    public void start()
    {
        GL20.glUseProgram(program);
    }

    public void stop()
    {
        GL20.glUseProgram(0);
    }

    private int loadShader(String line, int type)
    {
        int id = GL20.glCreateShader(type);
        GL20.glShaderSource(id, line);
        GL20.glCompileShader(id);

        if (GL20.glGetShaderi(id, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE)
            System.err.println("Compilation error: " + GL20.glGetShaderInfoLog(id, Short.MAX_VALUE));
        
        return id;
    }

    private String read(String fileName) throws IOException
    {
        StringBuilder str = new StringBuilder();
        ResourceLocation rs = new ResourceLocation("modid", "shaders/" + fileName);
        InputStream ir = Minecraft.getMinecraft().getResourceManager().getResource(rs).getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(ir, "UTF-8"));
        String line;

        while ((line = reader.readLine()) != null)
            str.append(line).append("\n");
        
        return str.toString();
    }

    public interface IAttributes
    {
        void add();
    }

    public interface IUniforms
    {
        void add();
    }
}
 
2,505
81
397
int fsh, vsh - не пригодятся никогда.
Нехватает dispose метода (вдруг пригодится).
Зачем ты всунул IAttributes и IUniforms, если не повесил на них никакой логики? Да и в таком виде выглядят довольно странно. Даже не представляю, как их можно будет использовать.
getUniform по имени тоже не очень. Круто, когда ShaderProgram вытаскивает локации юниформов из мапы, а если в мапе нет, то достает из огл. Аналогично с локациями атрибутов.
А еще, кроме этих двух шейдеров есть еще несколько, а твоя программа их не поддерживает. Я для красоты сбора программы написал ShaderCompiler, который выглядит покрасивее и может переиспользовать шейдер в новой программе. И сбор превращается примерно в такое:
Java:
ShaderProgram program = new ShaderProgram();
ShaderCompiler.begin(program)
              .linkVertexShader("Код шейдера")
              .linkFragmentShader(new ResourceLocation("modid", "shader.fs"))
              .linkShader("Код шейдера", GL32.GL_GEOMETRY_SHADER)
              .compile();
 

Icosider

Kotliner
Администратор
3,603
99
664
int fsh, vsh - не пригодятся никогда.
Нехватает dispose метода (вдруг пригодится).
Зачем ты всунул IAttributes и IUniforms, если не повесил на них никакой логики? Да и в таком виде выглядят довольно странно. Даже не представляю, как их можно будет использовать.
getUniform по имени тоже не очень. Круто, когда ShaderProgram вытаскивает локации юниформов из мапы, а если в мапе нет, то достает из огл. Аналогично с локациями атрибутов.
А еще, кроме этих двух шейдеров есть еще несколько, а твоя программа их не поддерживает. Я для красоты сбора программы написал ShaderCompiler, который выглядит покрасивее и может переиспользовать шейдер в новой программе. И сбор превращается примерно в такое:
Java:
ShaderProgram program = new ShaderProgram();
ShaderCompiler.begin(program)
              .linkVertexShader("Код шейдера")
              .linkFragmentShader(new ResourceLocation("modid", "shader.fs"))
              .linkShader("Код шейдера", GL32.GL_GEOMETRY_SHADER)
              .compile();
Так, 1.Слив кода, этого будет достаточно чтобы хотя б заюзать шейдеры.
2.По поводу интерфейсов, чисто под себя делал, логика все же былам там, для паблика вырезал ее, да можно и без них обойтись. 3.По поводу шейдеров, не преследовал цели писать под все 4 типа. Я ж тебе вроде в скайпе или дискорде писал. А так да, если кто захочет допишет эту программу или с нуля свою пусть пишет. Опять же, код для паблика.
 
1,990
18
105
Тащемта использовать GL11 - абсолютная норма. Матрицы, конечно, нужно реализовывать самостоятельно, но только для Core Profile.

А использовать экстеншены почем зря, когда есть соответствующий функционал в ядре - не норма. Просто потому что всегда есть маленький шанс того, что на какой-то видеокарте не поддерживается или совершенно иначе работает та же функция с соотв.суффиксом.
OpenGL Extension - OpenGL Wiki
In some cases, there are differences between extension and the core function. GLSL's extension version (ARB_shader_objects) was rather different from the core 2.0 functionality.

Никто ж не заставляет вылизывать код в рабочих примерах до идеала - это и не нужно, просто такие вещи из разряда вредных советов.
 

Icosider

Kotliner
Администратор
3,603
99
664
Эт ты кому?)
 
Последнее редактирование модератором:
1,990
18
105
:unsure:
:unsure:
Предыдущему комментатору
 
1,015
9
102
А какое имя должно у быть у uniform, что бы туда передавался цвет из openGL? Так же я пытаюсь передать значение в uniform, но вылетает post render 1282 Invalid operation

Java:
int uniformID = ARBShaderObjects.glGetUniformLocationARB(ModShaders.blackWhite, "resolution");
ARBShaderObjects.glUniform2fARB(uniformID, mc.displayWidth, mc.displayHeight);
ARBShaderObjects.glUseProgramObjectARB(ModShaders.blackWhite);
icon.draw();
ARBShaderObjects.glUseProgramObjectARB(0);

P.S. А как рисовать текстуру на полигоне адекватно. Т.е. что бы координаты были относительно полигона, а не экрана
 
Последнее редактирование:
2,505
81
397
Про трансформацию позиции ответил в твоей созданной теме.

Цвет можно достать из gl_Color.

И это атрибут вершины. Почитай получше про атрибуты и юниформы, а то похоже ты не очень понял.
 

deleted.user

Мошенник
321
43
Все это безумно круто, гайд тоже хорош, ссылка на ботанию (тоже самое в кофше есть), а вот фактического примера, как у @AustereTony в его гайдах - нет, за это все ж минус.
 

CMTV

Основатель
Администратор
1,304
4
601
Можешь скинуть код с примером сюда. А он может добавить в статью с сохранением авторства.
 

CMTV

Основатель
Администратор
1,304
4
601
Еще вариант. Можешь создать отдельный ресурс с подробными пояснениями. Тоже хорошо будет.
 
Сверху