[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) тесселлятора?
 
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 измерения (нет, не par1, par2, я про аргументы другой функции) используются. Альфа тест отключается, а он нужен чтобы не было проблем с текстурами, у которых есть альфа канал, очевидно идет трансляция матрицы в экранную, а не world-space. Маска глубины ещё вырубается.
Если ты хочешь сменить дуло оружия - идешь в код модельки, дублируешь нужную часть модели, называешь по-другому, открываешь свою текстурку - вставляешь туда в свободный AABB(параллельный осям прямоугольник) свою текстуру, запоминаешь координаты. Для новой дублированной части модели указываешь эти uv-координаты, дальше при рендере передаешь аргумент типа boolean, если он включен - рендеришь 1 вариант нужной части модели с одной текстурой, если фолс - второй, который дублированный и с другой текстурой.
Городят тут велосипеды с нуля для рендера одной чертовой текстуры, которые будут всё неэпически тормозить.
 
Если тебе надо именно заменить текстуру у дула - нет.
Если тебе надо нарисовать, например, дым от дула спереди - тут надо ловить именно рендер оружия.
Там узнаешь координаты своего дула, прибавляешь к ним высоту\ширину\длину - получаешь конечную точку дула. Там уже играйся с координатами и рисуй quad через Tesselator, без всяких готовых методов. Ну и uv-координаты задать не забудь.
Лучше всего, если нужная текстура будет в текстуре оружия. Это сократит количество glBindTexture, а это ОЧЕНЬ дорогая операция в плане производительности. Особенно если на экране будет рендериться большое количество этого оружия.
 
я примерно так это и представляю, но  у меня тесселятор от первого лица ничего не рисует. Толи я какие-то координаты неправильно задаю. Не совсем понимаю, что такое UV-координаты.
 
BlackCrafter написал(а):
Не совсем понимаю, что такое UV-координаты.
timaxa007 написал(а):
par7 - x в 2D пространстве на текстуре для текстурирования 3D модели.
par9 - y в 2D пространстве на текстуре для текстурирования 3D модели.
Типа я не правильно объяснил, типа нужен пример, чтобы понять.
Типа модель это X, Y, Z, U и V.
 
Хорошо, попробуем метод вопрос-ответ.
Тесселлятор надо юзать в классе модели или в классе рендера?
 
с позицией разобрался. Но теперь рендерится невнятный объект произвольной формы без текстуры
 
Так, а почему текстура получается перевернутая? Как ее вертеть?
Если делаю GL11.glRotatef() с любыми аргументами, то объект, нарисованный тесселлятором, вообще пропадает с экрана.
 
Потому что сначала надо смещать матрицу в нужную позицию, а потом поворачивать. Не наоборот.
Это не числа умножать, от порядка перемножения матриц результат меняется.
Если текстура перевернутая - glScalef(-1, 1, 1); знак минус ставишь туда, какую ось надо развернуть. У тебя всего 3 варианта, попробуй. Только потом вернуть матрицу не забудь, чтобы остальной рендер не распи~лило.
 
Имеется ввиду glTranslatef(), glScalef(), а потом нарисовать тесселлятором?
если делаю glScalef(1,-1,1) текстура пропадает. Остальной рендер норм.
 
Имеется ввиду, сначала ты вычисляешь позицию, применяешь матрицу смещения (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);

И потом идет отрисовка.
 
Сорян что туплю но у меня в рендере не появляется текстура на экране может я туплю вот код
Код:
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]

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