সত্তা সিস্টেম এবং রেন্ডারিং


11

ওকি, আমি এতক্ষণ যা জানি; সত্তায় এমন একটি উপাদান রয়েছে (ডেটা-স্টোরেজ) যা তথ্য ধারণ করে; - জমিন / স্প্রাইট - শেডার - ইত্যাদি etc

এবং তারপরে আমার কাছে একটি রেন্ডারার সিস্টেম রয়েছে যা এই সমস্ত আঁকায়। তবে আমি যা বুঝতে পারি না তা হ'ল রেন্ডারারকে কীভাবে ডিজাইন করা উচিত। প্রতিটি "ভিজ্যুয়াল টাইপ" এর জন্য আমার একটি উপাদান থাকা উচিত। শেডার ছাড়া একটি উপাদান, শেডার সহ একটি, ইত্যাদি?

এটি করার জন্য "সঠিক উপায়" কি সম্পর্কে কিছু ইনপুট দরকার। দেখার জন্য টিপস এবং সমস্যাগুলি।


2
জিনিসগুলিকে খুব জেনারিক না করার চেষ্টা করুন। শ্যাডারের উপাদান সহ একটি সত্তা থাকা এবং স্প্রাইট উপাদান নয় এটি আশ্চর্যজনক বলে মনে হবে, তাই শ্যাডারটি স্প্রাইট উপাদানটির অংশ হওয়া উচিত । স্বাভাবিকভাবে আপনার তখন কেবল একটি রেন্ডারিং সিস্টেমের প্রয়োজন হবে।
জোনাথন কনেল

উত্তর:


8

এটি উত্তর দেওয়া একটি কঠিন প্রশ্ন কারণ একটি সত্তা উপাদান সিস্টেমটি কীভাবে গঠন করা উচিত সে সম্পর্কে প্রত্যেকের নিজস্ব ধারণা। আমি যা করতে পারি তা হ'ল আমার পক্ষে আমার পক্ষে সবচেয়ে দরকারী বলে কিছু জিনিস আপনার সাথে ভাগ করে নেওয়া।

সত্তা

আমি ইসিএসের কাছে ফ্যাট-ক্লাসের পদ্ধতি গ্রহণ করি, সম্ভবত আমি প্রোগ্রামিংয়ের চূড়ান্ত পদ্ধতিগুলি অত্যন্ত অদক্ষ (মানব উত্পাদনশীলতার দিক থেকে) খুঁজে পাই। সে লক্ষ্যে, আমার কাছে একটি সত্তা হ'ল আরও বিবিধ শ্রেণীর দ্বারা উত্তরাধিকার সূত্রে প্রাপ্ত বিমূর্ত শ্রেণি। সত্তার বেশ কয়েকটি ভার্চুয়াল বৈশিষ্ট্য এবং একটি সহজ পতাকা রয়েছে যা আমাকে বলে যে এই সত্তার অস্তিত্ব থাকা উচিত কিনা। একটি রেন্ডার সিস্টেম সম্পর্কে আপনার প্রশ্নের তুলনায় তাই Entityদেখতে দেখতে দেখতে এটি হ'ল :

public abstract class Entity {
    public bool IsAlive = true;
    public virtual SpatialComponent   Spatial   { get; set; }
    public virtual ImageComponent     Image     { get; set; }
    public virtual AnimationComponent Animation { get; set; }
    public virtual InputComponent     Input     { get; set; }
}

উপাদান

উপাদান "মূঢ়" এ যে, তারা না না বা জানেন কিছু। তাদের অন্যান্য উপাদানগুলির সাথে কোনও রেফারেন্স নেই, এবং তাদের সাধারণত কোনও ফাংশন নেই (আমি সি # তে কাজ করি, তাই আমি গেটার / সেটারগুলি পরিচালনা করার জন্য বৈশিষ্ট্যগুলি ব্যবহার করি - যদি তাদের ফাংশন থাকে তবে তারা তাদের থাকা ডেটা পুনরুদ্ধারের আশেপাশে থাকে)।

সিস্টেম

সিস্টেমগুলি "বোকা" কম, তবে এখনও বোবা অটোমেটন। তাদের সামগ্রিক সিস্টেমের কোনও প্রসঙ্গ নেই, অন্যান্য সিস্টেমে কোনও রেফারেন্স নেই এবং কয়েকটি বাফার ছাড়া তাদের কোনও পৃথক প্রক্রিয়াজাতকরণের প্রয়োজন হতে পারে এমন কোনও ডেটা রাখেন না। সিস্টেমের উপর নির্ভর করে এটির একটি বিশেষজ্ঞ Update, বা Drawপদ্ধতি বা কিছু ক্ষেত্রে উভয় ক্ষেত্রে থাকতে পারে।

ইন্টারফেস

ইন্টারফেসগুলি আমার সিস্টেমে একটি মূল কাঠামো। কোনটি কী Systemপ্রক্রিয়া করতে পারে এবং কোনটি Entityসক্ষম। রেন্ডারিংয়ের জন্য প্রাসঙ্গিক ইন্টারফেসগুলি হ'ল: IRenderableএবং IAnimatable

ইন্টারফেসগুলি সহজভাবে সিস্টেমকে জানায় যে কোন উপাদানগুলি উপলব্ধ। উদাহরণস্বরূপ, রেন্ডারিং সিস্টেমে সত্তার বাউন্ডিং বাক্স এবং চিত্রটি আঁকতে হবে। আমার ক্ষেত্রে, এটি হবে SpatialComponentএবং ImageComponent। সুতরাং এটির মতো দেখাচ্ছে:

public interface IRenderable {
    SpatialComponent Component { get; }
    ImageComponent   Image     { get; }
}

রেন্ডারিং সিস্টেম

সুতরাং কীভাবে রেন্ডারিং সিস্টেম একটি সত্তা আঁকবে? এটি আসলে বেশ সহজ, সুতরাং আমি আপনাকে ধারণা দেওয়ার জন্য কেবল স্ট্রিপড ডাউন ক্লাসটি দেখাব:

public class RenderSystem {
    private SpriteBatch batch;
    public RenderSystem(SpriteBatch batch) {
        this.batch = batch;
    }
    public void Draw(List<IRenderable> list) {
        foreach(IRenderable obj in list) {
            this.batch.draw(
                obj.Image.Texture,
                obj.Spatial.Position,
                obj.Image.Source,
                Color.White);
        }
    }
}

ক্লাসের দিকে তাকানো, রেন্ডার সিস্টেম এমনকি একটি Entityকী তা জানে না । এটি সম্পর্কে যা কিছু জানে IRenderableসেগুলি আঁকার জন্য কেবল তাদের একটি তালিকা দেওয়া হয়।

কিভাবে এটি সব কাজ করে

আমি কীভাবে নতুন গেমের অবজেক্ট তৈরি করি এবং কীভাবে সিস্টেমে তাদের ফিড করব তা বুঝতে এটি সহায়তা করতে পারে।

সত্তা তৈরি করা হচ্ছে

সমস্ত গেমের অবজেক্টস সত্তা থেকে উত্তরাধিকার সূত্রে প্রাপ্ত এবং কোনও প্রয়োগযোগ্য ইন্টারফেস যা গেমের অবজেক্টটি কী করতে পারে তা বর্ণনা করে। স্ক্রিনে অ্যানিমেটেড সমস্ত কিছুর মতো দেখতে:

public class MyAnimatedWidget : Entity, IRenderable, IAnimatable {}

সিস্টেমগুলি খাওয়ানো

আমি একক তালিকায় গেম জগতের সমস্ত সত্ত্বার তালিকা রেখেছি List<Entity> gameObjects। প্রতিটি ফ্রেম, আমি তারপরে সেই তালিকাটি পর্যালোচনা করি এবং ইন্টারফেসের ধরণের উপর ভিত্তি করে অবজেক্টের রেফারেন্সগুলি অনুলিপি করি, যেমন List<IRenderable> renderableObjects, এবং List<IAnimatable> animatableObjects। এই পদ্ধতিতে, যদি বিভিন্ন সিস্টেমে একই সত্তা প্রক্রিয়া করার প্রয়োজন হয় তবে তারা পারে। তারপরে আমি কেবল সেই তালিকাগুলিকে প্রতিটি সিস্টেম Updateবা Drawপদ্ধতিতে হস্তান্তর করি এবং সিস্টেমগুলি তাদের কাজটি করতে দেয়।

অ্যানিমেশন

অ্যানিমেশন সিস্টেমটি কীভাবে কাজ করে তা আপনি জানতে আগ্রহী হতে পারেন। আমার ক্ষেত্রে আপনি আইনিমেটেবল ইন্টারফেস দেখতে চাইতে পারেন:

public interface IAnimatable {
    public AnimationComponent Animation { get; }
    public ImageComponent Image         { get; set; }
}

এখানে লক্ষ্য করার মূল বিষয়টি হ'ল ইন্টারফেসের ImageComponentদিকটি IAnimatableকেবল পঠনযোগ্য নয়; এটি একটি সেটর আছে

আপনি যেমন অনুমান করতে পারেন, অ্যানিমেশন উপাদানটি সবেমাত্র অ্যানিমেশন সম্পর্কিত ডেটা রাখে; ফ্রেমের একটি তালিকা (যা চিত্রের উপাদানগুলি), বর্তমান ফ্রেম, প্রতি সেকেন্ডে ফ্রেমের অঙ্কন করতে হবে, শেষ ফ্রেম বর্ধনের পরে বিচ্ছিন্ন সময় এবং অন্যান্য বিকল্পসমূহ।

অ্যানিমেশন সিস্টেমটি উপস্থাপনা সিস্টেম এবং চিত্রের উপাদানগুলির সম্পর্কের সুযোগ নেয়। এটি সহজেই সত্তার চিত্রের উপাদানটি পরিবর্তন করে কারণ এটি অ্যানিমেশনের ফ্রেমটিকে বাড়িয়ে তোলে। এইভাবে, অ্যানিমেশনটি উপস্থাপনের মাধ্যমে পরোক্ষভাবে উপস্থাপন করা হয়।


আমার সম্ভবত লক্ষ্য করা উচিত যে আমি সত্যিই জানিনা যে লোকেরা কোনও সত্তা-উপাদান সিস্টেমকে কল করছে এটির কাছাকাছি কিনা । একটি রচনা-ভিত্তিক নকশা বাস্তবায়নের প্রয়াসে আমি নিজেকে এই প্যাটার্নে পড়ে যেতে দেখলাম।
সাইফার

মজাদার! আমি আপনার সত্তার জন্য বিমূর্ত শ্রেণিতে খুব আগ্রহী নই তবে আইরেন্ডেবল ইন্টারফেসটি একটি ভাল ধারণা!
জোনাথন কনেল

5

আমি যে ধরণের সিস্টেমে কথা বলছি তা দেখতে এই উত্তরটি দেখুন ।

উপাদানটি কী আঁকতে হবে এবং কীভাবে আঁকতে হবে তার বিশদ থাকতে হবে। রেন্ডারিং সিস্টেম সেই বিশদগুলি নেবে এবং উপাদানটির দ্বারা নির্দিষ্ট পদ্ধতিতে সত্তাটি আঁকবে। কেবলমাত্র যদি আপনি উল্লেখযোগ্যভাবে পৃথক অঙ্কন প্রযুক্তি ব্যবহার করেন তবে আপনার পৃথক শৈলীর জন্য পৃথক উপাদান থাকতে পারে।


3

উপাদানগুলিতে যুক্তি পৃথক করার মূল কারণ হ'ল ডেটার একটি সেট তৈরি করা যখন কোনও সত্তার সাথে মিলিত হয়ে তারা দরকারী, পুনরায় ব্যবহারযোগ্য আচরণ তৈরি করে। উদাহরণস্বরূপ, একটি পদার্থবিজ্ঞান এবং রেন্ডারকম্পোন্টে একটি সত্ত্বাকে পৃথক করা অর্থপূর্ণ হয়ে ওঠে কারণ এটি সম্ভবত যে সমস্ত সত্তার পদার্থবিজ্ঞান থাকবে না এবং কিছু সংস্থার স্প্রাইট নাও থাকতে পারে।

আপনার প্রশ্নের উত্তর দেওয়ার জন্য আপনাকে আপনার আর্কিটেকচারটি দেখে নিজের কাছে দুটি প্রশ্ন জিজ্ঞাসা করতে হবে:

  1. টেক্সচার ছাড়াই শেডার থাকার অর্থ কি?
  2. টেক্সচার থেকে শেডারকে আলাদা করা কি আমাকে কোড ডুপ্লিকেশন এড়াতে অনুমতি দেবে?

কোনও উপাদানকে বিভক্ত করার সময় এই প্রশ্নটি জিজ্ঞাসা করা জরুরী, যদি 1 এর উত্তরটি হ্যাঁ হয় তবে আপনার কাছে সম্ভবত দুটি পৃথক উপাদান তৈরির জন্য ভাল প্রার্থী রয়েছে, একটি শ্যাডারযুক্ত এবং টেক্সচারযুক্ত একটি। ২ এর উত্তর সাধারণত পজিশনের মতো উপাদানগুলির জন্য হ্যাঁ যেখানে একাধিক উপাদান অবস্থান ব্যবহার করতে পারে।

উদাহরণস্বরূপ, পদার্থবিজ্ঞান এবং অডিও উভয়ই একই পজিশনটি ব্যবহার করতে পারে, তারপরে উভয় উপাদানই ডুপ্লিকেট পজিশনগুলি সংরক্ষণ করে আপনি তাদেরকে একটি পজিশন কম্পোনেন্টে রিফ্যাক্ট করেন এবং পদার্থবিজ্ঞান / অডিওকম্পোন্ট ব্যবহারকারী সত্তাগুলিরও একটি পজিশন কম্পোনেন্ট থাকতে হবে require

আপনি আমাদের যে তথ্য দিয়েছেন তার উপর ভিত্তি করে আপনার রেন্ডার কমপোয়েন্টটি টেক্সচার কম্পোনেন্টে ভাগ করার পক্ষে ভাল প্রার্থী এবং শেডারের অংশটি টেক্সচারের উপর সম্পূর্ণ নির্ভরশীল এবং অন্য কিছুই নয় বলে মনে হয়।

ধরে নিই যে আপনি টি মেশিনের অনুরূপ কিছু ব্যবহার করছেন : সত্তা সিস্টেমগুলি সি ++ তে একটি রেন্ডার কম্পোনেন্ট এবং রেন্ডার সিস্টেমের একটি নমুনা বাস্তবায়ন দেখতে এরকম কিছু দেখবে:

struct RenderComponent {
    Texture* textureData;
    Shader* shaderData;
};

class RenderSystem {
    public:
        RenderSystem(EntityManager& manager) :
            m_manager(manager) {
            // Initialize Window, rendering context, etc...
        }

        void update() {
            // Get all the entities with RenderComponent
            std::vector<RenderComponent>& components = m_manager.getComponents<RenderComponent>();

            for(auto component = components.begin(); entity != components.end(); ++components) {
                // Do something with the texture
                doSomethingWithTexture(component->textureData);

                // Do something with the shader if it's not null
                if(component->shaderData != nullptr) {
                    doSomethingWithShader(component->shaderData);
                }
            }
        }
    private:
        EntityManager& m_manager;
}

এটা সম্পূর্ণ ভুল। উপাদানগুলির পুরো বিন্দুটি হ'ল তাদের সত্তা থেকে আলাদা করা, সন্ধানের জন্য সন্ধানের মাধ্যমে সিস্টেমগুলি অনুসন্ধানের ব্যবস্থা করা নয়। রেন্ডার সিস্টেমগুলি তাদের নিজস্ব ডেটা সম্পূর্ণরূপে নিয়ন্ত্রণ করা উচিত। পিএস লুপগুলিতে স্ট্যান্ড :: ভেক্টর (বিশেষত উদাহরণস্বরূপ ডেটা সহ) রাখবেন না, এটি ভয়াবহ (ধীর) সি ++।
সাপ 5

@ সাপ 5 আপনি উভয় ক্ষেত্রেই সঠিক। আমি কোডটি আমার মাথার উপরের অংশে টাইপ করেছি এবং কিছু সমস্যা ছিল, সেগুলি দেখানোর জন্য ধন্যবাদ। আমি প্রভাবিত কোডটি কম ধীর হতে এবং সত্তা সিস্টেমের আইডিয়ামগুলি সঠিকভাবে ব্যবহার করতে স্থির করেছি।
জ্যাক উডস

2
@ সাপ 5 আপনার যখন এমন একটি সিস্টেম থাকে যা একই সত্তার একাধিক উপাদান ব্যবহার করতে চায় এমন একটি সুবিধা যখন উদাহরণস্বরূপ এমন একটি পদার্থবিজ্ঞান যা পজিশন কম্পোনেন্ট এবং পদার্থবিজ্ঞান ব্যবহার করতে চায়। অন্যান্য সিস্টেমগুলি সম্ভবত পজিশনটি চাইবে এবং একটি পজিশন কম্পোনেন্ট রেখে আপনার সদৃশ ডেটা নেই। প্রাথমিকভাবে এটি উপাদানগুলি কীভাবে যোগাযোগ করে তা সমস্যা সমাধান করে।
জ্যাক উডস

5
@ স্নাপ 5 প্রশ্নটি ইসি সিস্টেমটি কীভাবে তৈরি করা উচিত বা এটির পারফরম্যান্স সম্পর্কে নয়। প্রশ্নটি রেন্ডার সিস্টেম স্থাপন সম্পর্কে। ইসি সিস্টেম গঠনের একাধিক উপায় রয়েছে, এখানে একে অপরের পারফরম্যান্সের বিষয়ে ধরা পড়বেন না। ওপি সম্ভবত আপনার উত্তরগুলির মধ্যে দুটি তুলনায় সম্পূর্ণ আলাদা ইসি কাঠামো ব্যবহার করছে। এই উত্তরে প্রদত্ত কোডটি কেবল উদাহরণটি আরও ভালভাবে দেখানোর জন্য বোঝানো হয়েছে, এটির অভিনয়ের জন্য সমালোচনা করা উচিত নয়। যদি প্রশ্নটি পারফরম্যান্সের বিষয়ে হয় তবে এটি উত্তরটি "দরকারী নয়" করে তুলবে, তবে তা নয়।
মাইকেলহাউস

2
আমি সাইফারের চেয়ে এই উত্তরটিতে নকশাকৃত নকশাকে বেশি পছন্দ করি। এটি আমি ব্যবহার করি এমনটির সাথে খুব মিল। ক্ষুদ্রতর উপাদানগুলি আরও ভাল ইমো, এমনকি যদি তাদের কেবল একটি বা দুটি ভেরিয়েবল থাকে। তাদের একটি সত্তার একটি দিকটি সংজ্ঞায়িত করা উচিত, যেমন আমার "ড্যামেজেবল" উপাদানটিতে 2, সম্ভবত 4 ভেরিয়েবল (প্রতিটি স্বাস্থ্য এবং বর্মের জন্য সর্বাধিক এবং বর্তমান) থাকে। এই মন্তব্যগুলি দীর্ঘ হচ্ছে, আপনি আরও আলোচনা করতে চাইলে চ্যাটে চলে আসুন ।
জন ম্যাকডোনাল্ড

2

পিটফল # 1: ছাড়পত্রযুক্ত কোড। আপনার বাস্তবায়িত প্রতিটি জিনিসের সত্যই আপনার প্রয়োজন কিনা তা ভেবে দেখুন কারণ আপনাকে বেশ কিছু সময়ের জন্য এটির সাথে থাকতে হবে।

পিটফল # 2: অনেকগুলি অবজেক্ট। আমি অনেকগুলি অবজেক্ট (প্রতিটি ধরণের, উপ টাইপ এবং যাই হোক না কেনের জন্য একটি) সিস্টেম ব্যবহার করব না কারণ এটি কেবল স্বয়ংক্রিয় প্রক্রিয়াজাতকরণকে আরও শক্ত করে তোলে। আমার মতে, প্রতিটি বস্তুর একটি নির্দিষ্ট বৈশিষ্ট্য সেট (একটি বৈশিষ্ট্যের বিপরীতে) নিয়ন্ত্রণ করা অনেক বেশি সুন্দর। উদাহরণস্বরূপ, রেন্ডারিং (টেক্সচার উপাদান, শেডার উপাদান) অন্তর্ভুক্ত প্রতিটি বিট ডেটার জন্য উপাদান তৈরি করা খুব বিভক্ত - আপনার সাধারণত সমস্ত উপাদান একসাথে থাকা দরকার, আপনি কি সম্মত হবেন না?

পিটফল # 3: খুব কঠোর বাহ্যিক নিয়ন্ত্রণ। শেডার / টেক্সচার অবজেক্টগুলিতে নাম পরিবর্তন করা পছন্দ করুন কারণ বস্তুগুলি রেন্ডার / টেক্সচারের ধরণ / শেডার ফর্ম্যাট / যেকোনো কিছুতে পরিবর্তন করতে পারে। নামগুলি হ'ল সাধারণ শনাক্তকারী - এগুলির মধ্যে কী তৈরি করা যায় তা সিদ্ধান্ত নেওয়ার বিষয়টি রেন্ডারারের হাতে। একদিন আপনি প্লেইন শেডারের পরিবর্তে উপকরণ পেতে চাইতে পারেন (উদাহরণস্বরূপ ডেটা থেকে শেডার, টেক্সচার এবং মিশ্রন মোডগুলি যোগ করুন)। একটি পাঠ্য-ভিত্তিক ইন্টারফেস সহ, এটি কার্যকর করা অনেক সহজ।

রেন্ডারারের হিসাবে, এটি একটি সহজ ইন্টারফেস হতে পারে যা উপাদানগুলির দ্বারা তৈরি বস্তুগুলি তৈরি করে / ধ্বংস করে / রক্ষণাবেক্ষণ / রেন্ডার করে। এর সবচেয়ে আদিম উপস্থাপনাটি এরকম কিছু হতে পারে:

class Renderer {
    function Draw() { ... }
    function AddSprite( ... ) { ... return sprite; }
    function RemoveSprite( sprite ) { ... }
    ...
};

এটি আপনাকে আপনার উপাদানগুলি থেকে এই জিনিসগুলি পরিচালনা করার অনুমতি দেয় এবং এগুলি আপনাকে যেভাবে চান সেভাবে রেন্ডার করার জন্য এগুলি যথেষ্ট পরিমাণে রাখে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.