Перейти в начало страницы

Здравствуйте, гость ( Авторизация | Регистрация )

Gameru.net останавливает работу в связи с вторжением армии РФ в Украину. Следите за дальнейшими анонсами.
Support Gameru!
7 страниц V  « < 4 5 6 7 >  
Тема закрытаНачать новую тему
> Разработка игрового движка с нуля, как создать игровой движок
Молния в вакууме
сообщение 27.12.2017, 18:46
Сообщение #101


Почти Игроман
*********

Репутация:   187  
Группа: Участник
Сообщений: 647
Награды: 4
Регистрация: 05.05.2007




Вставить ник Цитировать выделенное в форуму быстрого ответа


refuse, это что, для каждой текстуры нужен будет такой скрипт? Я в своём движке думаю сделать больше похоже на сталкерский: у каждой модели есть список текстур и "шейдер" ( конечно, у меня там FFP =) ). В каждой стадии шейдера хранится индекс текстуры из этого списка. Таким образом можно уменьшить количество переключений состояния, т.к. текстуры можно менять отдельно.
Перейти в начало страницы
 
autistic
сообщение 27.12.2017, 21:36
Сообщение #102


Геймер
******

Репутация:   86  
Группа: Участник
Сообщений: 128
Награды: 4
Регистрация: 05.05.2012




Вставить ник Цитировать выделенное в форуму быстрого ответа


Цитата(saas @ 27.12.2017, 20:46) *
это что, для каждой текстуры нужен будет такой скрипт?

Немного сложнее. Каждый скрипт будет описывать некую схему в виде определенного набора констант, на основании этой схемы будут компилироваться шейдера. Из этого набора констант будут вычисляться хеши которым будут сопоставлены скомпилированные шейдера, и при парсинге следующего материала ему будет назначен уже скомпилированный шейдер, если материал с подобной структурой уже был загружен. В самом скрипте материала используемый шейдер явно не будет указываться.
Glsl шейдер будет всего один, но он будет порезан на секции заключенные в блоки #ifdef ... #elif ... #else, перед компиляцией шейдера строка с исходным кодом шейдера будет добавляться к строке с заголовком, в котором и будут объявлены соответствующие дефайны. Этот заголовок будет строиться при парсинге материала и из него же будет вычисляться хеш.
Вместе с этим каждый материал будет содержать наборы значений констант, а кроми этого он может быть мультипроходным (привет шкурке, которая отрисовывается в несколько проходов) и состоять из нескольких стейджей для которых могут быть использованы разные шейдера.
Сложновато? smile.gif Я тоже так думаю, полагаю на реализацию все новогодние каникулы уйдут (в перерывах между пьянством) если не больше >_<

Цитата(saas @ 27.12.2017, 20:46) *
Я в своём движке думаю сделать больше похоже на сталкерский: у каждой модели есть список текстур и "шейдер"

В описанном тобой варианте этот список хранится не в отдельном файле с материалом, а непосредственно в файле модели, вот и вся разница. Причем у некоторых моделей эти параметры могут совпадать, а выделение материала в отдельную сущность позволяет их переиспользование. Ну и как вариант, впоследствии, когда появится редактор, можно будет скрипт материала записывать непосредственно в файл модели.


Цитата(saas @ 27.12.2017, 20:46) *
Таким образом можно уменьшить количество переключений состояния, т.к. текстуры можно менять отдельно.

Сортировку я представляю себе примерно так: при сортировке оперируют более мелкими сущностями которые получаются в результате дробления материалов и моделей на кусочки геометрии, текстуры, шейдера трансформации, и объединения их в рендер таргеты, которые помещаются в очередь отрисовки в определенном порядке. Но до этого еще ой как далеко и много другой работы предстоит проделать laugh.gif


--------------------
nop
Перейти в начало страницы
 
Молния в вакууме
сообщение 28.12.2017, 04:33
Сообщение #103


Почти Игроман
*********

Репутация:   187  
Группа: Участник
Сообщений: 647
Награды: 4
Регистрация: 05.05.2007




Вставить ник Цитировать выделенное в форуму быстрого ответа


Цитата(refuse @ 27.12.2017, 21:36) *
Сложновато?

Да, и в правду сложновато.

Но всё-таки, для каждой текстуры свои константы. Это же сколько лишней информации может быть. А если что-то поменять в этих константах потребуется для набора аналогичных текстур? Может добавить возможность наследования настроек из материала-шаблона?
Перейти в начало страницы
 
Tron
сообщение 28.12.2017, 05:53
Сообщение #104


Игровой Эксперт
***************

Репутация:   407  
Группа: Участник
Сообщений: 2394
Награды: 5
Регистрация: 19.01.2009




Вставить ник Цитировать выделенное в форуму быстрого ответа


У меня JSON используется, формат примерно на твой похож.

Pass
{
Shader ...
Defines ...

{
Diffuse ....
Specular ...
Metallness ...
... ...
PBR PARAMS{ ... }
Bump params {...}
}
}

Вообще по хорошему еще бы дописать добавить сразу RT, что бы рендер сам подстраивался под материал
Перейти в начало страницы
 
autistic
сообщение 08.01.2018, 17:03
Сообщение #105


Геймер
******

Репутация:   86  
Группа: Участник
Сообщений: 128
Награды: 4
Регистрация: 05.05.2012




Вставить ник Цитировать выделенное в форуму быстрого ответа


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

P.S. потер собственный флуд, дабы не загромождать тему бесполезной информацией.


--------------------
nop
Перейти в начало страницы
 
RayTwitty
сообщение 08.01.2018, 18:22
Сообщение #106


Игровой Бог
**********************

Репутация:   648  
Группа: Участник
Сообщений: 5354
Награды: 9
Регистрация: 24.09.2010




Вставить ник Цитировать выделенное в форуму быстрого ответа


Любое начинание это конечно хорошо, да и вам самим решать в любом случае, но не попахивает ли это все велосипедом? Чем потенциальный движок будет отличаться от существующих аналогов? Не думаете ли вы, что все эти этапы проектирования архитектуры были уже пройдены многими разработчиками и в итоге получится примерно тоже самое?


--------------------
Перейти в начало страницы
 
jamakasi
сообщение 08.01.2018, 18:34
Сообщение #107


Доктор Игровых Наук
*******************

Репутация:   544  
Группа: Участник
Сообщений: 3657
Награды: 9
Регистрация: 12.07.2007




Вставить ник Цитировать выделенное в форуму быстрого ответа


Цитата(refuse @ 08.01.2018, 17:03) *
слишком долго будут парситься материалы и компилироваться шейдера

Сделай кэширование, первое обращение к нему и он компилится, в последующем берется из кэша, так делают очень многие. Дабы избавиться от парсинга можно тоже уйти к унификации путем компиляции в малый бинарный формат по одному из 2х путей:
1) Компилятор из твоих json во что то бинарное для снижения размеров и времени загрузки\парсинга. Далее простой компилятор который берет некий уровень, пробегает по всем материалам и составляет список. Дальше по этому списку делаешь 1 файл со всеми материалами. Далее этот файл разово грузится вместе с уровнем и выгружается при смене уровня.
2) Решение в лоб, делаешь список материалов уровня, и перед загрузкой делаешь их компил. Этакий прекэшинг тупой.

Касательно решения возможного вопроса "а если материалы настраивать то надо сначало чистить кэш что не удобно", тут уже тоже все придумано как то так:
- нужно загрузить материал Х
- считаем sha(любой удобный быстрый алгоритм, хоть мд5) материала
- смотрим в %TEMP%\YouGame\cache\хэш
- если есть берем его, нет значит компилим\рекомпилим и сохраняем в кэш

PS компиляция шейдера на целевой точка игрока это очень хорошо на самом деле.

Сообщение отредактировал jamakasi - 08.01.2018, 18:35
Перейти в начало страницы
 
Tron
сообщение 08.01.2018, 20:19
Сообщение #108


Игровой Эксперт
***************

Репутация:   407  
Группа: Участник
Сообщений: 2394
Награды: 5
Регистрация: 19.01.2009




Вставить ник Цитировать выделенное в форуму быстрого ответа


Цитата(refuse @ 08.01.2018, 17:03) *
Начал реализовывать задуманную систему материалов и в процессе понял, что такая система не должна использоваться в движке, слишком долго будут парситься материалы и компилироваться шейдера.

ShaderCache в помощь

Цитата(jamakasi @ 08.01.2018, 18:34) *
Цитата(refuse @ 08.01.2018, 17:03) *
слишком долго будут парситься материалы и компилироваться шейдера

Сделай кэширование, первое обращение к нему и он компилится, в последующем берется из кэша, так делают очень многие. Дабы избавиться от парсинга можно тоже уйти к унификации путем компиляции в малый бинарный формат по одному из 2х путей:
1) Компилятор из твоих json во что то бинарное для снижения размеров и времени загрузки\парсинга. Далее простой компилятор который берет некий уровень, пробегает по всем материалам и составляет список. Дальше по этому списку делаешь 1 файл со всеми материалами. Далее этот файл разово грузится вместе с уровнем и выгружается при смене уровня.
2) Решение в лоб, делаешь список материалов уровня, и перед загрузкой делаешь их компил. Этакий прекэшинг тупой.

Касательно решения возможного вопроса "а если материалы настраивать то надо сначало чистить кэш что не удобно", тут уже тоже все придумано как то так:
- нужно загрузить материал Х
- считаем sha(любой удобный быстрый алгоритм, хоть мд5) материала
- смотрим в %TEMP%\YouGame\cache\хэш
- если есть берем его, нет значит компилим\рекомпилим и сохраняем в кэш

PS компиляция шейдера на целевой точка игрока это очень хорошо на самом деле.

И очень плохо на самом деле, если капнуть глубже.
Берем SPIR-V/HLSL, генерируем байт-код. Упаковываем этот байт-код и отдаем пользователю. PROOOFIIIT!

В случае с чистым GLSL, то только вариант парсинга прокатит. Можно сделать кэширование, но оно совсем не безупречно работает.

1) Генерация шейдерного кэша, происходит при первом обращении.
2) Если обновился драйвер - шейдерный кэш устаревает, необходима перегенерация.

Либо использовать трюк с конвертацией HLSL байт-кода в GLSL
Перейти в начало страницы
 
autistic
сообщение 08.01.2018, 20:25
Сообщение #109


Геймер
******

Репутация:   86  
Группа: Участник
Сообщений: 128
Награды: 4
Регистрация: 05.05.2012




Вставить ник Цитировать выделенное в форуму быстрого ответа


Цитата(RayTwitty @ 08.01.2018, 20:22) *
Любое начинание это конечно хорошо, да и вам самим решать в любом случае, но не попахивает ли это все велосипедом? Чем потенциальный движок будет отличаться от существующих аналогов? Не думаете ли вы, что все эти этапы проектирования архитектуры были уже пройдены многими разработчиками и в итоге получится примерно тоже самое?

Я планирую создать некий Фреймворк с конечной целью сделать какую-нибудь игру. Конечно, можно было бы взять какое-нибудь готовое решение и сконцентрироваться на создании именно игры, но мне этот вариант не подходит по нескольким причинам:
1. Мне интересно не игру делать, интересен сам процесс ее создания, т.е. кодить и придумывать архитектурные решения самостоятельно.
2. Использование сторонней технологии предполагает 80-90% нудной рутины и лишь 10-20% творческой работы. Этого добра мне хватает на основной работе.
В общем считайте что это хобби, некоторые читают книги после работы, некоторые в качалку ходят, а я вот велосипед строю smile.gif

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

Upd.
Вот результаты моих экспериментов с убершейдером:

shader.h
Код
namespace Engine
{
    class Shader
    {
    public:
        virtual ~Shader() {}

        virtual void Compile(const String &shaderName, bool isDynamic) = 0;

        virtual void Draw(GraphicsShapePtr shape) = 0;

        virtual void SetWorldViewProj(const Matrix4 &worldViewProj) = 0;
    };

    Shader *GetShader();
}


shader.cpp
Код
const char geomVertexShader[] =
"\
layout(location = 1) in vec4 vertexPosition;\n\
layout(location = 2) in vec4 vertexNormal;\n\
layout(location = 3) in vec4 vertexTangent;\n\
layout(location = 4) in vec4 vertexBinormal;\n\
layout(location = 5) in vec2 vertexTexcoords;\n\
layout(location = 6) in uint bones;\n\
layout(location = 7) in vec4 weights;\n\
out vec2 texCoords;\n\
uniform mat4 worldViewProj;\n\
void main()\n\
{\n\
    gl_Position = worldViewProj * vertexPosition;\n\
    texCoords = vertexTexcoords;\n\
}\n\
\0";

const char geomFragmentShader[] =
"\
in vec2 texCoords;\n\
out vec4 color;\n\
#ifdef DIFFUSE_MAP\n\
uniform sampler2D diffuseMap;\n\
#endif\n\
void main()\n\
{\n\
#ifdef DIFFUSE_MAP\n\
    color = texture(diffuseMap, texCoords);\n\
#else\n\
    color = vec4(1.0, 1.0, 1.0, 1.0);\n\
#endif\n\
}\n\
\0";

namespace Engine
{
    // Shader parameters
    const String tagDiffuseMap = "DiffuseMap";

    // Macro definitions
    const String tagDiffuseMapMacro = "DIFFUSE_MAP";
    const String tagDynamicMacro = "DYNAMIC";

    struct ShaderDataHolder
    {
        ShaderDataHolder(const ShaderDataHolder &) = delete;
        ShaderDataHolder &operator = (const ShaderDataHolder &) = delete;

        ShaderDataHolder()
            : gpuProgramId(INVALID_GPU_PROGRAM_ID)
        {
        }

        ShaderDataHolder(GpuProgramId gpuProgramId)
            : gpuProgramId(gpuProgramId)
        {
        }

        ~ShaderDataHolder()
        {
            if (gpuProgramId != INVALID_GPU_PROGRAM_ID)
                GetRenderer()->DestroyGpuProgram(gpuProgramId);
        }

        GpuProgramId gpuProgramId;
    };

    using ShaderDataHolderPtr = std::shared_ptr<ShaderDataHolder>;
    using ShaderDataMap = std::unordered_map<String, ShaderDataHolderPtr>;

    struct Material
    {
        TexturePtr diffuseMap;
    };

    using MaterialPtr = std::shared_ptr<Material>;
    using MaterialMap = std::unordered_map<String, MaterialPtr>;

    template <class AssociativeContainer_T, class Key_T>
    bool HasEntry(const AssociativeContainer_T &container, const Key_T &key)
    {
        auto elementIt = container.find(key);
        if (elementIt != container.end())
            return true;

        return false;
    }

    template <class Key_T, class Val_T>
    bool GetEntry(const std::unordered_map<Key_T, Val_T> &container, const Key_T &key, Val_T &value)
    {
        auto elementIt = container.find(key);
        if (elementIt == container.end())
            return false;

        value = elementIt->second;
        return true;
    }

    class ShaderImpl : public Shader
    {
    public:
        ShaderImpl()
        {
            worldViewProj.SetIdentity();
            staticShaders.reserve(MAX_SHADER_DATAS);
            dynamicShaders.reserve(MAX_SHADER_DATAS);
        }

        virtual void Compile(const String &shaderName, bool isDynamic) override
        {
            if (shaderName.empty()) {
                //TODO: log error
                return;
            }

            if ((isDynamic && HasEntry(dynamicShaders, shaderName))
                || (!isDynamic && HasEntry(staticShaders, shaderName))) {
                //TODO: log warning
                return;
            }

            ByteArray source;
            if (!LoadFileSource(shaderName + ".shader", source)) {
                //TODO: log error
                return;
            }

            ScriptPtr shaderScript = ParseScript(shaderName, source);
            if (!shaderScript) {
                //TODO: log error
                return;
            }

            String shaderIdentifierStr;
            const String shaderBase = MakeShaderBase(shaderScript, isDynamic, shaderIdentifierStr);
            const String vertexShaderStr = String(shaderBase) + geomVertexShader;
            const String fragmentShaderStr = String(shaderBase) + geomFragmentShader;

            ByteArray vertexShaderSrc(vertexShaderStr.begin(), vertexShaderStr.end());
            ByteArray fragmentShaderSrc(fragmentShaderStr.begin(), fragmentShaderStr.end());
            GpuProgramId gpuProgramId = GetRenderer()->CreateGpuProgram(vertexShaderSrc, fragmentShaderSrc);

            if (gpuProgramId == INVALID_GPU_PROGRAM_ID) {
                //TODO: log error
                return;
            }

            if (!ParseMaterial(shaderScript, ))

            auto shaderData = std::make_shared<ShaderDataHolder>(gpuProgramId);
            if (isDynamic)
                dynamicShaders[shaderIdentifierStr] = shaderData;
            else
                staticShaders[shaderIdentifierStr] = shaderData;
        }

        virtual void Draw(GraphicsShapePtr shape) override
        {
            ShaderDataHolderPtr shaderData;
            bool isDynamic = IsDynamicShape(*shape);
            if ((isDynamic && !GetEntry(dynamicShaders, shape->shaderName, shaderData))
            || (!isDynamic && !GetEntry(staticShaders, shape->shaderName, shaderData))) {
                //TODO: log warning
                return;
            }

            if (shaderData != currentShaderData) {
                currentShaderData = shaderData;
                GetRenderer()->BindGpuProgram(shaderData->gpuProgramId);
                if (shaderData->diffuseMap)
                    GetRenderer()->BindHardwareTexture(shaderData->diffuseMap->GetHardwareTexture(), DIFFUSE_MAP);

                GetRenderer()->SetGpuProgramConstant(shaderData->gpuProgramId, "worldViewProj", worldViewProj);
            }

            GetRenderer()->DrawHardwareBuffer(shape->hardwareBufferId);
        }

        virtual void SetWorldViewProj(const Matrix4 &worldViewProj) override
        {
            this->worldViewProj = worldViewProj;
            if (currentShaderData) {
                GetRenderer()->SetGpuProgramConstant(
                    currentShaderData->gpuProgramId, "worldViewProj", worldViewProj);
            }
        }

    private:
        bool LoadFileSource(const String &fileName, ByteArray &source) const
        {
            FilePtr file = GetFileSystem()->OpenFileRead(fileName);
            if (!file)
                return false;

            const size_t fileSize = file->GetSize();
            if (fileSize == 0)
                return false;

            source.resize(fileSize);
            file->Read(&source[0], source.size());
            return true;
        }

        String MakeMacroDefinition(const String &macroName, const String &macroDefinition) const
        {
            return String("#ifndef ") + macroName + '\n'
                + String("#define ") + macroName + ' ' + macroDefinition + '\n'
                + String("#endif") + "\n\n";
        }

        String MakeShaderBase(ScriptPtr shaderScript, bool isDynamic, String &usedDefinesString) const
        {
            String result = "#version 330\n\n";
            const String separator = ";";

            if (isDynamic) {
                result += MakeMacroDefinition(tagDynamicMacro, "1");
                usedDefinesString += tagDynamicMacro + separator;
            }

            if (shaderScript->HasValue(tagDiffuseMap)) {
                result += MakeMacroDefinition(tagDiffuseMapMacro, "1");
                usedDefinesString += tagDiffuseMapMacro + separator;
            }

            return result;
        }

        bool IsDynamicShape(const GraphicsShape &shape) const
        {
            switch (shape.vertexFormat) {
            case VA_BONES:
            case VA_SKINNED_W2:
            case VA_SKINNED_W3:
            case VA_SKINNED_W4:
            case VA_SKINNED_W1:
                return true;
            }

            return false;
        }

        bool ParseMaterial(ScriptPtr shaderScript, Material &material) const
        {
            const String diffuseMapName = shaderScript->GetString(tagDiffuseMap);
            if (!diffuseMapName.empty())
                material.diffuseMap = GetTextureManager()->GetTexture(diffuseMapName);

            return true;
        }

    private:
        static const int MAX_SHADER_DATAS = 128;

        Matrix4 worldViewProj;

        ShaderDataMap staticShaders;
        ShaderDataMap dynamicShaders;

        ShaderDataHolderPtr currentShaderData;
    };

    Shader *GetShader()
    {
        static ShaderImpl shader;
        return &shader;
    }
}


Я планировал сделать отдельный кэш для GLSL программ на основе unordered_map, а в качестве ключа использовать строку с перечислением использованных дефайнов, отсортированных в алфавитном порядке.

Сообщение отредактировал refuse - 08.01.2018, 20:51


--------------------
nop
Перейти в начало страницы
 
Tron
сообщение 08.01.2018, 22:52
Сообщение #110


Игровой Эксперт
***************

Репутация:   407  
Группа: Участник
Сообщений: 2394
Награды: 5
Регистрация: 19.01.2009




Вставить ник Цитировать выделенное в форуму быстрого ответа


Цитата
Я планировал сделать отдельный кэш для GLSL программ на основе unordered_map, а в качестве ключа использовать строку с перечислением использованных дефайнов, отсортированных в алфавитном порядке.

Зачем так усложнять? Если этот кеш нигде храниться не будет. Используй id шейдера/программы и все

Тебе именно охото в рендер вкатиться? - просто взял бы какой-нибудь рендер фреймворк и не парился.
Перейти в начало страницы
 
autistic
сообщение 08.01.2018, 23:08
Сообщение #111


Геймер
******

Репутация:   86  
Группа: Участник
Сообщений: 128
Награды: 4
Регистрация: 05.05.2012




Вставить ник Цитировать выделенное в форуму быстрого ответа


Цитата(Tron @ 09.01.2018, 00:52) *
Зачем так усложнять? Если этот кеш нигде храниться не будет. Используй id шейдера/программы и все

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

Цитата(Tron @ 09.01.2018, 00:52) *
Тебе именно охото в рендер вкатиться? - просто взял бы какой-нибудь рендер фреймворк и не парился

Да, мне интересно самому во всех тонкостях разбираться.


--------------------
nop
Перейти в начало страницы
 
autistic
сообщение 13.01.2018, 03:05
Сообщение #112


Геймер
******

Репутация:   86  
Группа: Участник
Сообщений: 128
Награды: 4
Регистрация: 05.05.2012




Вставить ник Цитировать выделенное в форуму быстрого ответа


Реализовал зачатки системы материалов (или скорее шейдерную систему, если такое название вообще применимо). За основу все-таки взял убершейдер. Система пока ничего не умеет делать, т.к. мне пока самому непонятно какие параметры должны быть у шейдера и как их организовать, так что в текущем виде скрипт шейдера имеет только один параметр:
Код
{
    // Diffuse map
    DiffuseMap = cat_diff;
}


Следующим этапом планирую реализовать отложенное затенение и углубляться потихонечку в тонкости шейдерных эффектов.

P.S. Ну и напоследок немного котика с отключенным буфером глубины smile.gif


Кстати, код тестового приложения заметно сократился:
+
Код
#include <engine/model.h>
#include <engine/platform.h>
#include <engine/renderer.h>
#include <engine/shader.h>

int main()
{
    Engine::Platform *platform = Engine::GetPlatform();
    if (!platform->CreateMainWindow())
        return -1;

    Engine::Renderer *renderer = Engine::GetRenderer();
    Engine::ModelManager *modelManager = Engine::GetModelManager();
    Engine::ModelPtr teapot = modelManager->GetModel("teapot");

    Engine::Matrix4 rotation(Engine::Matrix3(M_PI * 0.25f, M_PI * 0.1f, 0));

    Engine::Matrix4 proj, view, model, modelViewProj;
    view.SetIdentity();
    proj.SetPerspective(1.3f, 1.78f, 0.1f, 100000.0f);
    model.SetTranslation(Engine::Vector3(-0.35, -0.3f, -1.5f));
    modelViewProj = rotation * model * proj;


    Engine::Shader *shader = Engine::GetShader();
    shader->Compile("cat", false);
    shader->SetWorldViewProj(modelViewProj);

    platform->SetMainWindowSize(1280, 720, false);
    renderer->SetViewport(1280, 720);

    for (;;) {
        if (!platform->UpdateMainWindow()) {
            break;
        }

        shader->Draw(teapot->GetGraphicsShapes()[0]);
    }
}


--------------------
nop
Перейти в начало страницы
 
autistic
сообщение 14.01.2018, 21:47
Сообщение #113


Геймер
******

Репутация:   86  
Группа: Участник
Сообщений: 128
Награды: 4
Регистрация: 05.05.2012




Вставить ник Цитировать выделенное в форуму быстрого ответа


Снова размышлял над тем какую бы игру можно было бы сделать используя собственный графический движок, подумал про про бильярд. 3-х мерное окружение с качественными текстурами и освещением + честная физика + мультиплеер.
Я уже даже прикинул какой стек технологий можно использовать:
В качестве фронтенда мобильное приложение, скажем под андроид, естественно с использованием самописного движка.
В качестве бэкенда самописный сервер на С++, который будет осуществлять авторизацию, регистрацию, матчмейкинг и соблюдение игровых правил (определение очередности хода, подсчет очков и т.д).
Также предусмотреть самописный REST, скажем на php, для предоставления некоего АПИ для внешних сервисов (регистрация с сайта/форума, осуществление внутриигровых покупок и т.п.)
В качестве БД PostgreSQL или MySQL Server.
Вобщем фантазирую smile.gif
Единственной серьезной проблемой является тот факт, что идея не нова и стор должен быть забит похожими играми.
Примеры:
https://play.google.com/store/apps/details?id=com.xs.pooltd
https://itunes.apple.com/ca/app/3d-pool-gam...1175740795?mt=8


--------------------
nop
Перейти в начало страницы
 
shurabich
сообщение 14.01.2018, 22:18
Сообщение #114


Мастер Игры
************

Репутация:   120  
Группа: Участник
Сообщений: 1387
Награды: 4
Регистрация: 29.04.2009




Вставить ник Цитировать выделенное в форуму быстрого ответа


Цитата(refuse @ 14.01.2018, 21:47) *
Единственной серьезной проблемой является тот факт, что идея не нова и стор должен быть забит похожими играми.
Примеры:
https://play.google.com/store/apps/details?id=com.xs.pooltd
https://itunes.apple.com/ca/app/3d-pool-gam...1175740795?mt=8


В основном все делают пул по идее. А как насчет русского бильярда? А вообще на NES был Lunar Ball... занятная игрушка, в которой можно было менять гравитацию, а сами столы имели причудливую форму. Было бы прикольно что то такое увидеть в 3D. wink_old.gif
https://www.youtube.com/watch?v=bHilCMWwBYI


--------------------
"Лови отвальную, фраер."
Перейти в начало страницы
 
solitary.wandere...
сообщение 14.01.2018, 22:38
Сообщение #115


Опытный Геймер
*******

Репутация:   9  
Группа: Участник
Сообщений: 161
Регистрация: 23.12.2017




Вставить ник Цитировать выделенное в форуму быстрого ответа


Цитата(refuse @ 14.01.2018, 21:47) *
Снова размышлял над тем какую бы игру можно было бы сделать используя собственный графический движок, подумал про про бильярд. 3-х мерное окружение с качественными текстурами и освещением + честная физика + мультиплеер.
Я уже даже прикинул какой стек технологий можно использовать:
В качестве фронтенда мобильное приложение, скажем под андроид, естественно с использованием самописного движка.
В качестве бэкенда самописный сервер на С++, который будет осуществлять авторизацию, регистрацию, матчмейкинг и соблюдение игровых правил (определение очередности хода, подсчет очков и т.д).
Также предусмотреть самописный REST, скажем на php, для предоставления некоего АПИ для внешних сервисов (регистрация с сайта/форума, осуществление внутриигровых покупок и т.п.)
Вобщем фантазирую smile.gif
Единственной серьезной проблемой является тот факт, что идея не нова и стор должен быть забит похожими играми.


Я тут по-быстрому накидал один вариант:


Сообщение отредактировал solitary.wanderer94 - 14.01.2018, 22:43
Перейти в начало страницы
 
shurabich
сообщение 15.01.2018, 00:21
Сообщение #116


Мастер Игры
************

Репутация:   120  
Группа: Участник
Сообщений: 1387
Награды: 4
Регистрация: 29.04.2009




Вставить ник Цитировать выделенное в форуму быстрого ответа


Кстати, раз форум по большей части сталкеру посвящен, да и что то уникальное хочется сделать, то было бы прикольно увидеть бильярд в Зоне. Как раз столики на старом Баре были, да вот в игре не использовались... Ну а что? Было бы здорово: сталкеры играют в бильярд, фоном слышны анекдоты и музыка... атмосферно и действительно уникально. wink.gif



--------------------
"Лови отвальную, фраер."
Перейти в начало страницы
 
solitary.wandere...
сообщение 15.01.2018, 00:27
Сообщение #117


Опытный Геймер
*******

Репутация:   9  
Группа: Участник
Сообщений: 161
Регистрация: 23.12.2017




Вставить ник Цитировать выделенное в форуму быстрого ответа


Цитата(shurabich @ 15.01.2018, 00:21) *
Как раз столики на старом Баре были, да вот в игре не использовались...

Наверно разрабы их специально для модеров оставили


Сообщение отредактировал solitary.wanderer94 - 15.01.2018, 00:27
Перейти в начало страницы
 
autistic
сообщение 21.01.2018, 23:22
Сообщение #118


Геймер
******

Репутация:   86  
Группа: Участник
Сообщений: 128
Награды: 4
Регистрация: 05.05.2012




Вставить ник Цитировать выделенное в форуму быстрого ответа


Реализованы основы техники отложенного затенения, пока только geometry pass. Собственно затенение (lightning pass) будет добавлено позже.
Содержимое G-Buffer'а с котиком (цвет, текстурные координаты, нормали, позиции соответственно)



Следующим этапом планирую добавить источники света и собственно затенение.

P.S. Кстати, столкнулся с таким странным поведением OpenGL - не получается изменить размер RT в большую сторону. В меньшую - пожалуйста, а в большую конечный результат обрезается вот таким образом


Думаю пока что с этим делать. Мб кто-то знает как пофиксить?


--------------------
nop
Перейти в начало страницы
 
Tron
сообщение 22.01.2018, 05:30
Сообщение #119


Игровой Эксперт
***************

Репутация:   407  
Группа: Участник
Сообщений: 2394
Награды: 5
Регистрация: 19.01.2009




Вставить ник Цитировать выделенное в форуму быстрого ответа


Размер буфера фиксирован же, вроде как. Насколько мне помнится не больше 4 текстур.
Перейти в начало страницы
 
Takke
сообщение 22.01.2018, 07:49
Сообщение #120


Продвинутый геймер
********

Репутация:   38  
Группа: Участник
Сообщений: 392
Награды: 4
Регистрация: 11.04.2015




Вставить ник Цитировать выделенное в форуму быстрого ответа


Оффтоп
Цитата(shurabich @ 15.01.2018, 02:21) *
Было бы здорово: сталкеры играют в бильярд, фоном слышны анекдоты и музыка... атмосферно и действительно уникально.

Я прям представил эту божественную анимацию и мне на секунду стало страшно biggrin.gif
Перейти в начало страницы
 

7 страниц V  « < 4 5 6 7 >
Тема закрытаНачать новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 02.05.2024, 19:07