[1.6.4] Рендерить текстуру или эффект вместе с моделью

Здравствуйте.
Сделал 3D-модель оружия. Рендерится правильно, ошибок нет. Необходимо в нужный момент подрисовывать текстуру в области дула. Например, текстуру огня или любую другую.
Пробовал так:
Код:
    public void render(Entity entity, float par2, float par3, float par4, float par5, float par6, float par7)
    {
        this.setRotationAngles(par2, par3, par4, par5, par6, par7,entity);

            float f6 = 2.0F;
            GL11.glPushMatrix();
            GL11.glScalef(1.0F / f6, 1.0F / f6, 1.0F / f6);
            GL11.glTranslatef(-0.4F, 31.0F * par7, 2.5F);
            GL11.glRotatef(210F, 0.4F, 0.0F, 0.5F);
            GL11.glRotatef(140F, -11.9F, 1.9F, 22.0F);
            
            this.bipedRightArm.render(par7);

            double x = entity.posX;
            double y = entity.posY;
            double z = entity.posZ;
            entity.worldObj.spawnParticle("fireworksSpark", x, y+1, z, 0.0d, 0.0d, 0.0d);
            GL11.glPopMatrix();
        }
    }
Код рендерит руку игрока, потом в другом классе рендерится модель валыны.
Имею две проблеммы:
Код:
            entity.worldObj.spawnParticle("fireworksSpark", x, y+1, z, 0.0d, 0.0d, 0.0d);
1) ничего, кроме fireworksSparks не спаунится.
2) не знаю, как вычислить нужную точку, относительно модели.
 
Скажите, что означают аргументы функции addVertexWithUV(par1, par3, par5, par7, par9) тесселлятора?
 

timaxa007

Модератор
5,831
409
672
BlackCrafter написал(а):
Скажите, что означают аргументы функции addVertexWithUV(par1, par3, par5, par7, par9) тесселлятора?
par1 - x в 3D пространстве на рендере.
par3 - y в 3D пространстве на рендере.
par5 - z в 3D пространстве на рендере.
par7 - x в 2D пространстве на текстуре для текстурирования 3D модели.
par9 - y в 2D пространстве на текстуре для текстурирования 3D модели.
Вроде как так.
 
Мне надо нарисовать текстуру рядом с моделью.
В инете пишут, что надо сделать что-то типа этого:
Код:
protected void renderPumpkinBlur(int par1, int par2)
 {
 GL11.glDisable(GL11.GL_DEPTH_TEST);
 GL11.glDepthMask(false);
 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
 GL11.glDisable(GL11.GL_ALPHA_TEST);
 this.mc.getTextureManager().bindTexture(pumpkinBlurTexPath);
 Tessellator tessellator = Tessellator.instance;
 tessellator.startDrawingQuads();
 tessellator.addVertexWithUV(0.0D, (double)par2, -90.0D, 0.0D, 1.0D);
 tessellator.addVertexWithUV((double)par1, (double)par2, -90.0D, 1.0D, 1.0D);
 tessellator.addVertexWithUV((double)par1, 0.0D, -90.0D, 1.0D, 0.0D);
 tessellator.addVertexWithUV(0.0D, 0.0D, -90.0D, 0.0D, 0.0D);
 tessellator.draw();
 GL11.glDepthMask(true);
 GL11.glEnable(GL11.GL_DEPTH_TEST);
 GL11.glEnable(GL11.GL_ALPHA_TEST);
 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
 }
но какие бы аргументы я ни подставлял, на экране вообще ничего не меняется.
 
2,955
12
ты хоть знаешь что нужно указывать в аргументах. Ширину и высоту экрана.
 
Знаю, но что бы я ни указывал, на экране ничего не рисуется.
Теперь от третьего лица где-то сбоку рисуется квадрат цвета неба. От первого лица ничего нет.
 
1,990
18
105
Лол, ну ты серьезно? Это функция для отрисовки текстуры на экране. После рендера всей сцены, понимаешь? Там даже в аргументах только 2 измерения (нет, не par1, par2, я про аргументы другой функции) используются. Альфа тест отключается, а он нужен чтобы не было проблем с текстурами, у которых есть альфа канал, очевидно идет трансляция матрицы в экранную, а не world-space. Маска глубины ещё вырубается.
Если ты хочешь сменить дуло оружия - идешь в код модельки, дублируешь нужную часть модели, называешь по-другому, открываешь свою текстурку - вставляешь туда в свободный AABB(параллельный осям прямоугольник) свою текстуру, запоминаешь координаты. Для новой дублированной части модели указываешь эти uv-координаты, дальше при рендере передаешь аргумент типа boolean, если он включен - рендеришь 1 вариант нужной части модели с одной текстурой, если фолс - второй, который дублированный и с другой текстурой.
Городят тут велосипеды с нуля для рендера одной чертовой текстуры, которые будут всё неэпически тормозить.
 
1,990
18
105
Если тебе надо именно заменить текстуру у дула - нет.
Если тебе надо нарисовать, например, дым от дула спереди - тут надо ловить именно рендер оружия.
Там узнаешь координаты своего дула, прибавляешь к ним высоту\ширину\длину - получаешь конечную точку дула. Там уже играйся с координатами и рисуй quad через Tesselator, без всяких готовых методов. Ну и uv-координаты задать не забудь.
Лучше всего, если нужная текстура будет в текстуре оружия. Это сократит количество glBindTexture, а это ОЧЕНЬ дорогая операция в плане производительности. Особенно если на экране будет рендериться большое количество этого оружия.
 
я примерно так это и представляю, но  у меня тесселятор от первого лица ничего не рисует. Толи я какие-то координаты неправильно задаю. Не совсем понимаю, что такое UV-координаты.
 

timaxa007

Модератор
5,831
409
672
BlackCrafter написал(а):
Не совсем понимаю, что такое UV-координаты.
timaxa007 написал(а):
par7 - x в 2D пространстве на текстуре для текстурирования 3D модели.
par9 - y в 2D пространстве на текстуре для текстурирования 3D модели.
Типа я не правильно объяснил, типа нужен пример, чтобы понять.
Типа модель это X, Y, Z, U и V.
 
Хорошо, попробуем метод вопрос-ответ.
Тесселлятор надо юзать в классе модели или в классе рендера?
 
с позицией разобрался. Но теперь рендерится невнятный объект произвольной формы без текстуры
 
Так, а почему текстура получается перевернутая? Как ее вертеть?
Если делаю GL11.glRotatef() с любыми аргументами, то объект, нарисованный тесселлятором, вообще пропадает с экрана.
 
1,990
18
105
Потому что сначала надо смещать матрицу в нужную позицию, а потом поворачивать. Не наоборот.
Это не числа умножать, от порядка перемножения матриц результат меняется.
Если текстура перевернутая - glScalef(-1, 1, 1); знак минус ставишь туда, какую ось надо развернуть. У тебя всего 3 варианта, попробуй. Только потом вернуть матрицу не забудь, чтобы остальной рендер не распи~лило.
 
Имеется ввиду glTranslatef(), glScalef(), а потом нарисовать тесселлятором?
если делаю glScalef(1,-1,1) текстура пропадает. Остальной рендер норм.
 
1,990
18
105
Имеется ввиду, сначала ты вычисляешь позицию, применяешь матрицу смещения (glTranslate) на неё, потом, если надо, glScalef, и только потом glRotatef. И то вращаться моделька будет не вокруг центра, а вокруг начальной точки. Если хочешь вращение посередине - делаешь glTranslate перед поворотом на половину длины\ширины\высоты модели, вращаешь, потом делаешь glTranslate половины длины\ширины\высоты, но уже назад. Т.е.
Код:
glTranslatef(posX+w/2, posY+h/2, posZ+w/2);
glRotatef(angle, multX, multY, multZ);
glTranslatef(-w/2, -h/2, -w/2);

И потом идет отрисовка.
 
61
0
Сорян что туплю но у меня в рендере не появляется текстура на экране может я туплю вот код
Код:
package divcraft.guns.render;

import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityClientPlayerMP;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.IItemRenderer;
import net.minecraftforge.client.model.AdvancedModelLoader;
import net.minecraftforge.client.model.IModelCustom;

import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;

import divcraft.guns.handler.KeyGuns;
import divcraft.guns.handler.TickGuns;
import divcraft.guns.items.ItemGun;
import divcraft.guns.model.Ruka;
import divcraft.guns.player.DivPlayer;
import divcraft.guns.utils.GunsLoader;

public class Ak74Render implements IItemRenderer {

    private IModelCustom model;
    protected Ruka Ruka;
    public EntityPlayer player;
    float speed;
    float scope;
    float shot;
    public int spoc;
    TickGuns tick = new TickGuns();

    public Ak74Render() {
        model = AdvancedModelLoader
                .loadModel("/assets/divstalker/models/ak74u.obj");
        Ruka = new Ruka();
    }

    @Override
    public boolean handleRenderType(ItemStack item, ItemRenderType type) {

        switch (type) {
        case EQUIPPED:
            return true;
        case EQUIPPED_FIRST_PERSON:
            return true;
        case ENTITY:
            return true;
        default:
            return false;
        }
    }

    @Override
    public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item,
            ItemRendererHelper helper) {
        return false;
    }

    @Override
    public void renderItem(ItemRenderType type, ItemStack item, Object... data) {
        switch (type) {

        case EQUIPPED_FIRST_PERSON: {
            EntityPlayer player = (EntityPlayer) data[1];

            if (player.isSprinting()) {

                speed += 0.05;
            } else {
                speed -= 0.05;

                if (Mouse.isButtonDown(1)) {
                    scope += 0.05;
                } else {
                    scope -= 0.05;
                }
                if (Mouse.isButtonDown(0)) {
                    shot += 0.05;
                } else {
                    shot -= 0.05;
                }
            }
            if (speed >= 1.0) {
                speed = 1;
            }
            if (speed <= 0) {
                speed = 0;
            }
            if (scope >= 1.0) {
                scope = 1;
            }
            if (scope <= 0) {
                scope = 0;
            }
            float ospeed = 1 - speed;
            float oscope = 1 - scope;
            float oshot = 1 - shot;

            GL11.glPushMatrix();

            TickGuns tick = new TickGuns();
            Minecraft.getMinecraft().renderEngine
                    .bindTexture(new ResourceLocation("divstalker",
                            "textures/ak74u.png"));
            if (Mouse.isButtonDown(1) && !player.isSprinting()) {

                float[] rot1 = { 18.0F, 0.0F, 0.0F, 1.0F };
                float[] rot2 = { 22.0F, 0.0F, 0.0F, 1F };
                float[] sc1 = { 0.07F, 0.07F, 0.07F };
                float[] sc2 = { 0.07F, 0.07F, 0.07F };
                float[] tr1 = { 0.5F, 0.6F, 0.35F };
                float[] tr2 = { 0.1F, 1F, 0.46F };

                GL11.glRotatef(45F, -0.95F, -1.9F, 1F);
                GL11.glRotatef(65F, -22F, 1.5F, 1F);
                GL11.glRotatef(rot1[0] * oscope + rot2[0] * scope, rot1[1]
                        * oscope + rot2[1] * scope, rot1[2] * oscope + rot2[2]
                        * scope, rot1[3] * oscope + rot2[3] * scope);
                GL11.glTranslatef(tr1[0] * oscope + tr2[0] * scope, tr1[1]
                        * oscope + tr2[1] * scope, tr1[2] * oscope + tr2[2]
                        * scope);
                GL11.glScalef(sc1[0] * oscope + sc2[0] * scope, sc1[1] * oscope
                        + sc2[1] * scope, sc1[2] * oscope + sc2[2] * scope);
                if (Mouse.isButtonDown(0)) {
                    if (((ItemGun) player.inventory.getCurrentItem().getItem()).curBullet != 0) {

                        if (tick.sload == 1) {
                            
                            GL11.glTranslatef(MathHelper.sin(-1F) * 1, 0.0F,
                                    0.0F);
                        }
                    }
                }

            } else {
                float[] tr1 = { 0.5F, 0.6F, 0.35F };
                float[] tr2 = { 0.8F, -0.1F, 0.35F };
                float[] rot1 = { 18.0F, 0.0F, 0.0F, 1.0F };
                float[] rot2 = { 100.0F, 0.0F, 0.0F, 1.0F };
                float[] sc1 = { 0.07F, 0.07F, 0.07F };
                float[] sc2 = { 0.05F, 0.05F, 0.05F };
                GL11.glRotatef(45F, -0.95F, -1.9F, 1F);
                GL11.glRotatef(65F, -22F, 1.5F, 0F);
                GL11.glRotatef(rot1[0] * ospeed + rot2[0] * speed, rot1[1]
                        * ospeed + rot2[1] * speed, rot1[2] * ospeed + rot2[2]
                        * speed, rot1[3] * ospeed + rot2[3] * speed);
                GL11.glTranslatef(tr1[0] * ospeed + tr2[0] * speed, tr1[1]
                        * ospeed + tr2[1] * speed, tr1[2] * ospeed + tr2[2]
                        * speed);
                GL11.glScalef(sc1[0] * ospeed + sc2[0] * speed, sc1[1] * ospeed
                        + sc2[1] * speed, sc1[2] * ospeed + sc2[2] * speed);
                if (Mouse.isButtonDown(0)) {
                    if (player.inventory.getCurrentItem() != null) {
                        if (player.inventory.getCurrentItem().getItem() == GunsLoader.ak74) {
                            if (((ItemGun) player.inventory.getCurrentItem()
                                    .getItem()).curBullet != 0) {

                                if (tick.sload == 1) {

                                    GL11.glTranslatef(MathHelper.sin(-1F) * 1,
                                            0.0F, 0.0F);
                                }
                            }
                        }
                    }
                }
            }
            if (KeyGuns.reload.isPressed()) {

            }
            float scale = 1.0F;
            model.renderAll();
            GL11.glPopMatrix();
            GL11.glPushMatrix();
            RenderBlocks rb = (RenderBlocks) data[0];
            EntityClientPlayerMP icon11 = (EntityClientPlayerMP) data[1];
            rb.minecraftRB.renderEngine.bindTexture(icon11.getLocationSkin());

            GL11.glRotatef(150F, 1.5F, -1F, -0.3F);
            GL11.glRotatef(65F, -10F, 1F, 0F);
            GL11.glRotatef(-10F, 30F, 10F, 0.05F);
            if (Mouse.isButtonDown(1) && !player.isSprinting()) {
                float[] tr11 = { -0.1F, -0.5F, -0.4F };
                float[] tr22 = { -0.1F, -0.9F, -0.4F };

                GL11.glTranslatef(tr11[0] * oscope + tr22[0] * scope, tr11[1]
                        * oscope + tr22[1] * scope, tr11[2] * oscope + tr22[2]
                        * scope);
            } else {

                GL11.glTranslatef(-0.1F, -0.5F, -0.4F);
                if (Mouse.isButtonDown(0)) {
                    if (player.inventory.getCurrentItem() != null) {
                        if (player.inventory.getCurrentItem().getItem() == GunsLoader.ak74) {
                            if (((ItemGun) player.inventory.getCurrentItem()
                                    .getItem()).curBullet != 0) {

                                if (tick.sload == 1) {

                                    GL11.glTranslatef(0.0F, 0.0F,
                                            MathHelper.sin(0.1F) * 1);
                                }
                            }
                        }
                    }
                }
            }
            float scale1 = 1.0F;
            GL11.glScalef(0.5F, 0.5F, 0.5F);
            Ruka.render((Entity) data[1], 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0625F);
            GL11.glPopMatrix();
            GL11.glPushMatrix();
            rb.minecraftRB.renderEngine.bindTexture(icon11.getLocationSkin());
            if (Mouse.isButtonDown(1) && !player.isSprinting()) {
                float[] rot11 = { 50F, -10F, 0F, -1.0F };
                float[] rot21 = { 70F, -10F, 0F, -1.0F };
                float[] rot12 = { 20F, 30F, 1F, 1.3F };
                float[] rot22 = { 20F, 30F, 1F, 1.3F };
                float[] tr11 = { -0.15F, -1.1F, 0.0F };
                float[] tr22 = { -0.15F, -1.15F, -0.3F };
                float[] sc11 = { 0.7F, 0.7F, 2.4F };
                float[] sc22 = { 0.7F, 0.7F, 2F };
                GL11.glRotatef(140F, 1.6F, -1.1F, -0.3F);
                GL11.glRotatef(rot11[0] * oscope + rot21[0] * scope, rot11[1]
                        * oscope + rot21[1] * scope, rot11[2] * oscope
                        + rot21[2] * scope, rot11[3] * oscope + rot21[3]
                        * scope);
                GL11.glRotatef(rot12[0] * oscope + rot22[0] * scope, rot12[1]
                        * oscope + rot22[1] * scope, rot12[2] * oscope
                        + rot22[2] * scope, rot12[3] * oscope + rot22[3]
                        * scope);
                GL11.glTranslatef(tr11[0] * oscope + tr22[0] * scope, tr11[1]
                        * oscope + tr22[1] * scope, tr11[2] * oscope + tr22[2]
                        * scope);
                GL11.glScalef(sc11[0] * oscope + sc22[0] * scope, sc11[1]
                        * oscope + sc22[1] * scope, sc11[2] * oscope + sc22[2]
                        * scope);
            } else {
                float[] rot11 = { 50F, -10F, 0F, -1.0F };
                float[] rot21 = { 65F, -10F, 0F, -1.0F };
                float[] rot12 = { 20F, 30F, 1F, 1.3F };
                float[] rot22 = { 0F, 30F, 1F, 1.3F };
                float[] tr11 = { -0.15F, -1.1F, 0.0F };
                float[] tr22 = { -0.15F, -1.2F, -0.5F };
                float[] sc11 = { 0.7F, 0.7F, 2.4F };
                float[] sc22 = { 0.6F, 0.6F, 0.6F };
                GL11.glRotatef(140F, 1.6F, -1.1F, -0.3F);
                GL11.glRotatef(rot11[0] * ospeed + rot21[0] * speed, rot11[1]
                        * ospeed + rot21[1] * speed, rot11[2] * ospeed
                        + rot21[2] * speed, rot11[3] * ospeed + rot21[3]
                        * speed);
                GL11.glRotatef(rot12[0] * ospeed + rot22[0] * speed, rot12[1]
                        * ospeed + rot22[1] * speed, rot12[2] * ospeed
                        + rot22[2] * speed, rot12[3] * ospeed + rot22[3]
                        * speed);
                GL11.glTranslatef(tr11[0] * ospeed + tr22[0] * speed, tr11[1]
                        * ospeed + tr22[1] * speed, tr11[2] * ospeed + tr22[2]
                        * speed);
                GL11.glScalef(sc11[0] * ospeed + sc22[0] * speed, sc11[1]
                        * ospeed + sc22[1] * speed, sc11[2] * ospeed + sc22[2]
                        * speed);
                if (Mouse.isButtonDown(0)) {
                    if (player.inventory.getCurrentItem() != null) {
                        if (player.inventory.getCurrentItem().getItem() == GunsLoader.ak74) {
                            if (((ItemGun) player.inventory.getCurrentItem()
                                    .getItem()).curBullet != 0) {

                                if (tick.sload == 1) {

                                    GL11.glTranslatef(0.0F, 0.0F,
                                            MathHelper.sin(0.05F) * 1);
                                }
                            }
                        }
                    }
                }

            }
            float scale2 = 1.0F;
            Ruka.render((Entity) data[1], 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0625F);
            GL11.glPopMatrix();
        }
        default:
            break;
        }
        switch (type) {
        case EQUIPPED: {
            GL11.glPushMatrix();
            Minecraft.getMinecraft().renderEngine
                    .bindTexture(new ResourceLocation("divstalker",
                            "textures/ak74u.png"));
            GL11.glRotatef(-55F, 1F, 0.2F, 0.1F);
            GL11.glRotatef(65F, -10F, 15F, -3F);
            GL11.glRotatef(-90F, 0F, 1F, 0.03F);

            GL11.glTranslatef(0.8F, 0.1F, -0.1F);
            float scale = 1.0F;
            GL11.glScalef(0.05F, 0.05F, 0.05F);
            model.renderAll();
            GL11.glPopMatrix();

        }
        default:
            break;
        }
        switch (type) {
        case ENTITY: {
            GL11.glPushMatrix();
            Minecraft.getMinecraft().renderEngine
                    .bindTexture(new ResourceLocation("divstalker",
                            "textures/ak74u.png"));
            GL11.glRotatef(65F, 2F, 0F, -0.2F);
            GL11.glRotatef(65F, -10F, 1F, 0F);
            GL11.glRotatef(0F, 0F, 3F, 0F);

            GL11.glTranslatef(-0F, -0.1F, -0.09F);
            float scale = 1.0F;
            GL11.glScalef(0.07F, 0.07F, 0.07F);

            model.renderAll();
            GL11.glPopMatrix();

        }
        default:
            break;
        }

    }

}
[merge_posts_bbcode]Добавлено: 18.06.2016 17:48:19[/merge_posts_bbcode]

Извиняюсь что такой корявый код -_-
 
1,976
68
220
Госпоади, люди, что вы всё велосипедируете, велосипедируете, да никак не вывелосипедирываете (прочитай это в три раза быстрее)? glRotate и glTranslate в этом случае вообще не нужны, как и glScale.
Координаты брать из вектора player.getLook(1.0F), прибавлять к ним нужное значение и так расставлять вершины. UV вообще просто - ставишь нули и единицы. И не забудь glDisable(GL_CULL_FACE), а то будет огонь односторонним. Ну и, конечно, не забывай включать свечение, а то будет у тебя бледный огонь в темноте.
 
Сверху