glVertexAttribPointer স্পষ্টতা


94

আমি নিশ্চিত হয়েছি যে আমি এটি সঠিকভাবে বুঝতে পেরেছি (আমি এসও চ্যাটে জিজ্ঞাসা করব, তবে এটি সেখানে মারা গেছে!):

আমরা একটি ভার্টেক্স অ্যারে পেয়েছি, যা আমরা এটি আবদ্ধ করে "কারেন্ট" তৈরি করি
তারপরে আমরা একটি বাফার পেয়েছি, যা আমরা একটি টার্গেটের সাথে আবদ্ধ
করি তারপরে আমরা glBufferData সেই টার্গেটটি পূরণ করি যার মাধ্যমে মূলত সেই লক্ষ্যটিকে আবদ্ধ করা হয়, যা আমাদের বাফারকে আবশ্যক করে তোলে ie
এবং তারপরে আমরা কল করি glVertexAttribPointerযা ডেটা কীভাবে নির্ধারণ করা হয়েছে তা বর্ণনা করে - ডেটা যা আবদ্ধ হয় তা GL_ARRAY_BUFFER এবং এই বিবরণীটি আমাদের মূল ভার্টেক্স অ্যারেতে সংরক্ষণ করা হয়

(1) আমার বোঝা কি সঠিক? ডকুমেন্টেশন সবকিছু কেমন সম্পর্ক সম্পর্কে সামান্য বিক্ষিপ্ত হয়।

(২) কোনও ধরণের ডিফল্ট ভার্টেক্স অ্যারে রয়েছে? কারণ আমি ভুলে গেছি / বাদ দিয়েছি glGenVertexArraysএবং glBindVertexArrayএবং আমার প্রোগ্রামটি এটি ছাড়া ভালভাবে কাজ করেছে।


সম্পাদনা: আমি একটি পদক্ষেপ মিস ... glEnableVertexAttribArray

(3) সেই সময়ে ভার্টেক্স অ্যারেটির সাথে বাঁধা glVertexAttribPointerভার্টেক্স অ্যাট্রিব কি বলা হয় এবং তারপরে glEnableVertexAttribArrayবর্তমানে ভার্টেক্স অ্যারে আবদ্ধ কিনা তা বিবেচনা না করে আমরা যে কোনও সময় সেই বৈশিষ্ট্যটিকে সক্ষম / অক্ষম করতে পারি ?

অথবা (3 খ) সেই সময়ে ভার্টেক্স অ্যারেটির সাথে বাঁধা ভার্টেক্স অ্যাট্রিব glEnableVertexAttribArrayকি বলা হয় এবং এইভাবে আমরা glEnableVertexAttribArrayযখন বিভিন্ন ভার্টেক্স অ্যারে আবদ্ধ হয় তখন বিভিন্ন সময়ে ফোন করে একই ভার্টেক্স অ্যাট্রিবি যুক্ত করতে পারি?

উত্তর:


212

কিছু পরিভাষা কিছুটা বন্ধ:

  • Vertex Arrayহ'ল একটি অ্যারে (সাধারণত একটি float[]) যাতে ভার্টেক্স ডেটা থাকে। এটি কোনও কিছুর সাথে আবদ্ধ হওয়ার দরকার নেই। কোনও Vertex Array Objectবা ভিএওর সাথে বিভ্রান্ত হওয়ার দরকার নেই , যা আমি পরে যাব
  • একটি Buffer Object, সাধারণত Vertex Buffer Objectशिरোখণ্ডগুলি সংরক্ষণ করার সময় হিসাবে উল্লেখ করা হয় , বা সংক্ষেপে ভিবিও, আপনি কেবল এটিকে ডাকছেন Buffer
  • ভার্টেক্স অ্যারেতে কোনও কিছুই সংরক্ষণ করা যায় না, glVertexAttribPointerঠিক একইভাবে কাজ করে glVertexPointerবা glTexCoordPointerকাজ করে, কেবলমাত্র নামযুক্ত বৈশিষ্ট্যের পরিবর্তে, আপনাকে এমন একটি নম্বর সরবরাহ করতে হবে যা আপনার নিজস্ব বৈশিষ্ট্য নির্দিষ্ট করে। আপনি এই মান হিসাবে পাস indexglVertexAttribPointerপরের বার আপনি যখন ফোন করবেন glDrawArraysবা বলবেন তখন আপনার সমস্ত কল কাত হয়ে থাকবে glDrawElements। আপনার যদি কোনও ভিএও আবদ্ধ থাকে তবে ভিএও আপনার সমস্ত বৈশিষ্ট্যের জন্য সেটিংস সংরক্ষণ করবে।

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

  1. শেডারে এটি ব্যবহার করার আগে আপনাকে অবশ্যই কোনও বৈশিষ্ট্য সক্ষম করতে হবে। উদাহরণস্বরূপ, আপনি যদি একটি শেডারকে শীর্ষে প্রান্ত পাঠাতে চান তবে আপনি সম্ভবত এটি প্রথম অ্যাট্রিবিউট হিসাবে প্রেরণ করতে যাচ্ছেন, ০. সুতরাং আপনাকে রেন্ডার করার আগে আপনাকে এটিটি সক্ষম করতে হবে glEnableVertexAttribArray(0);
  2. এখন যে কোনও অ্যাট্রিবিউট সক্ষম হয়েছে, আপনাকে এটি ব্যবহার করতে চলেছে ডেটা নির্ধারণ করতে হবে। এটি করার জন্য আপনাকে আপনার ভিবিও - কে আবদ্ধ করতে হবে glBindBuffer(GL_ARRAY_BUFFER, myBuffer);
  3. এবং এখন আমরা বৈশিষ্ট্যটি সংজ্ঞায়িত করতে পারি - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);। প্যারামিটারের ক্রম: 0 আপনি যে বৈশিষ্ট্যটি সংজ্ঞায়িত করছেন এটি হ'ল 3 প্রতিটি প্রতিটি শীর্ষবিন্দুর আকার, GL_FLOATপ্রকার, GL_FALSEপ্রতিটি অনুভূমিককে স্বাভাবিক না করার অর্থ, শেষ 2 টি শূন্যের অর্থ দাঁড়াচ্ছে যে শীর্ষে কোনও স্ট্রাইড বা অফসেট নেই।
  4. এটি দিয়ে কিছু আঁকুন - glDrawArrays(GL_TRIANGLES, 0, 6);
  5. আপনি যে পরবর্তী জিনিসটি আঁকবেন তাতে অ্যাট্রিবিউট 0 ব্যবহার করতে পারে না (বাস্তবে এটি হবে তবে এটি একটি উদাহরণ), সুতরাং আমরা এটিকে অক্ষম করতে পারি - glDisableVertexAttribArray(0);

glUseProgram()কলগুলিতে এটি মোড়ানো এবং আপনার কাছে একটি রেন্ডারিং সিস্টেম রয়েছে যা শেডারগুলির সাথে সঠিকভাবে কাজ করে। তবে আসুন আমরা বলি যে আপনার কাছে 5 টি আলাদা আলাদা অ্যাট্রিবিউটস, শীর্ষকোষ, টেক্সকর্ডস, নরমালগুলি, রঙ এবং লাইটম্যাপ স্থানাঙ্ক রয়েছে। প্রথমত, আপনি glVertexAttribPointerএই বৈশিষ্ট্যের প্রতিটিটির জন্য একক কল করবেন এবং আপনাকে সমস্ত বৈশিষ্ট্য আগেই সক্ষম করতে হবে। আসুন বলে দিন যে আপনি 0-4 বৈশিষ্ট্যগুলি সংজ্ঞায়িত করেছেন কারণ আমি তাদের তালিকাভুক্ত করেছি। আপনি তাদের সকলকে এমনভাবে সক্ষম করবেন:

for (int i = 0; i < 5; i++)
    glEnableVertexAttribArray(i);

এবং তারপর আপনি প্রতিটি অ্যাট্রিবিউট জন্য বিভিন্ন VBOs জুড়তে অনুমতি (যদি না আপনি তাদের সব এক VBO এবং ব্যবহার অফসেট / দীর্ঘ স্টোর) হবে, তাহলে আপনি 5 বিভিন্ন করতে হবে glVertexAttribPointerকল থেকে glVertexAttribPointer(0,...);থেকে glVertexAttribPointer(4,...);যথাক্রমে lightmap স্থানাঙ্ক থেকে ছেদচিহ্ন জন্য।

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

প্রতিটি কল করার সময় টার্গেট করা Vertex Array Objectসমস্ত glVertexAttribPointerকল এবং ভিবিওগুলির স্থিতি সংরক্ষণ করতে এ বা ভিএও ব্যবহৃত হয় glVertexAttribPointer

আপনি কল দিয়ে একটি তৈরি করুন glGenVertexArrays। আপনার প্রয়োজনীয় সমস্ত কিছু ভিএওতে সঞ্চয় করতে, এটির সাথে আবদ্ধ করুন glBindVertexArray, তারপরে একটি সম্পূর্ণ ড্র কল করুন । সমস্ত ড্র বাইন্ড কলগুলি ভিএও-র দ্বারা আটকানো এবং সংরক্ষণ করা হয়। আপনি VAO এর সাথে আনবাইন্ড করতে পারেনglBindVertexArray(0);

এখন আপনি যখন বস্তুটি আঁকতে চান, আপনাকে সমস্ত ভিবিও বাইন্ড বা glVertexAttribPointerকলগুলি পুনরায় কল করতে হবে না , আপনাকে কেবল ভিএও-কে আবদ্ধ করতে হবে glBindVertexArrayতারপরে কল করুন glDrawArraysঅথবা glDrawElementsআপনি ঠিক একই জিনিসটি আঁকবেন যদিও আপনি এই সমস্ত পদ্ধতি কল করছিল। আপনি সম্ভবত পরে VAO আনবাইন্ড করতে চান।

আপনি একবার ভিএও-কে বাঁধাই করলে, সমস্ত রাজ্য আপনার ভিএও-কে আবদ্ধ করার আগে এটি কেমন ছিল তা ফিরিয়ে দেয়। আমি নিশ্চিত নই যে ভিএও আবদ্ধ থাকাকালীন আপনার যে পরিবর্তনগুলি করা হয়েছে তা রক্ষা করা হয়েছে, তবে এটি পরীক্ষা প্রোগ্রামের সাহায্যে সহজেই বের করা যায়। আমার ধারণা আপনি glBindVertexArray(0);"ডিফল্ট" ভিএও-র সাথে বাধ্যতামূলক হিসাবে ভাবতে পারেন ...


আপডেট: কেউ আসল ড্র কলটির প্রয়োজনীয়তা আমার নজরে এনেছে। যেমনটি দেখা যাচ্ছে, ভিএও সেট আপ করার সময় আপনাকে কেবল সমস্ত বন্ডিং স্টাফের জন্য একটি সম্পূর্ণ ড্র কল করতে হবে না। কেন আমি আগে এটি প্রয়োজনীয় মনে করেছিলাম তা জানেন না, তবে এটি এখন ঠিক।


10
"একটি ভার্টেক্স বাফার অবজেক্ট, বা ভিবিও (কখনও কখনও কেবল একটি বাফার অবজেক্ট হিসাবে পরিচিত)" এটি "কখনও কখনও" বলা হয় কারণ এটিকেই বলা হয়। এটি কেবল একটি বাফার অবজেক্ট, অন্য কোনও বাফার অবজেক্টের থেকে আলাদা নয় যা আপনি ইউনিফর্ম ব্লক, পিক্সেল স্থানান্তর, প্রতিক্রিয়া রূপান্তর বা অন্য কোনও ব্যবহারের জন্য ব্যবহার করতে পারেন। ওপেনজিএল স্পেস কখনই কোনও কিছুইকে "ভার্টেক্স বাফার অবজেক্ট" হিসাবে উল্লেখ করে না ; এমনকি মূল এক্সটেনশন স্পেক এটিকে কখনও কল করে না।
নিকল বোলাস

4
দুর্দান্ত উত্তর। এটি লেখার জন্য সময় দেওয়ার জন্য ধন্যবাদ! একটি দম্পতি যদিও প্রশ্নগুলি অনুসরণ করে: (1) আপনি বলেছিলেন "আপনি রেন্ডার করার আগে, এবং গুনটি সংজ্ঞায়িত করার আগে আপনাকে এটিকে glEnableVertexAttribArray (0)" দিয়ে সক্ষম করতে হবে - আপনি কি নিশ্চিত যে কল করার আগে এটি সক্ষম করা দরকার glVertexAttribPointer? আমার পরীক্ষাগুলিতে, অর্ডারটি কিছু মনে হচ্ছে না। (২) যদি আমি আপনাকে সঠিকভাবে বুঝতে পারি তবে ভার্টেক্স অ্যাট্রিবিউটগুলি বিশ্বব্যাপী, এবং কেবল তাদের সক্ষম / অক্ষম রাষ্ট্রটি বর্তমানে আবদ্ধ ভিএওতে সংরক্ষণ করা হবে?
এমপেন

4
(1) আমি মনে করি না অর্ডার বিষয়গুলি, যতদিন না পর্যন্ত আপনি আগে এটি সক্রিয় করেছি না glDrawArraysবা glDrawElements। (2) হ্যাঁ প্রতিফলিত করার জন্য আমি পোস্টটি আপডেট করব, তবে এটি কেবল সঞ্চিত / অক্ষম রাষ্ট্র সংরক্ষণ করা নয়, এটি সমস্ত কলগুলির সাথে সম্পর্কিত - যা GL_ARRAY_BUFFER এর সাথে আবদ্ধ ছিল, টাইপ, স্ট্রাইড এবং অফসেট। মূলত এটি সমস্ত ভার্টেক্স অ্যাট্রিবিউটগুলি যেভাবে আপনি সেগুলি ভিএও দিয়ে সেট আপ করেছেন তার পরিবর্তনের জন্য এটি যথেষ্ট পরিমাণে সংরক্ষণ করছে।
রবার্ট রুহানি

4
হ্যাঁ, ভিএওগুলি আপনাকে একটি ভিএও বাঁধাইয়ের মাধ্যমে বেশিরভাগ অঙ্কন পদ্ধতির প্রতিস্থাপন করতে ডিজাইন করা হয়েছে। প্রতিটি সত্তার আলাদা ভিএও থাকতে পারে এবং এটি এখনও ঠিক কাজ করবে। আপনাকে এখনও ইউনিফর্ম আপডেট করতে হবে এবং যদিও আপনার নিজের টেক্সচারগুলি আবদ্ধ করতে হবে। এবং আপনাকে যেমন শ্যাটারের বৈশিষ্ট্যগুলি layout(location = x)শ্যাটারের মধ্যে বা glBindAttributeLocationশেডারটি সংকলন করার সময় বাছাইয়ের সাথে , আপনাকে যেমন বিশিষ্ট সূচকগুলির সাথে আবদ্ধ করতে হয় তেমন বৈশিষ্ট্য সূচকগুলিও আপনাকে ব্যবহার করতে হবে । উদাহরণ
রবার্ট রুহানি

8
নোট করুন যে আধুনিক ওপেনজিএলে আর কোনও ডিফল্ট ভার্টেক্স অ্যারে অবজেক্ট নেই, আপনাকে নিজের তৈরি করতে হবে অথবা আপনার অ্যাপ্লিকেশনটি সামনের দিকে সামঞ্জস্যপূর্ণ প্রসঙ্গে কাজ করবে না।

3

ডাকা হবে এমন API এর পরিভাষা এবং ক্রমটি আসলেই বিভ্রান্তিকর। আরও বিভ্রান্তিকর বিষয় হ'ল বিভিন্ন দিক - বাফার, জেনেরিক ভার্টেক্স অ্যাট্রিবিউট এবং শেডার অ্যাট্রিবিউট ভেরিয়েবল কীভাবে যুক্ত হয়। বেশ ভাল ব্যাখ্যার জন্য ওপেনজিএল-পরিভাষা দেখুন ।

আরও, লিঙ্কটি ওপেনজিএল-ভিবিও, শেডার, ভিএও প্রয়োজনীয় এপিআই কলগুলির সাথে একটি সাধারণ উদাহরণ দেখায়। এটি তাত্ক্ষণিক মোড থেকে প্রোগ্রামেবল পাইপলাইনে রূপান্তরকারীদের জন্য বিশেষত ভাল।

আশা করি এটা সাহায্য করবে.

সম্পাদনা: আপনি নীচের মন্তব্যগুলি থেকে দেখতে পাচ্ছেন, লোকেরা অনুমানগুলি করতে পারে এবং সিদ্ধান্তে ঝাঁপিয়ে পড়তে পারে। বাস্তবতাটি এটি প্রাথমিকভাবে বিভ্রান্তিকর।


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

4
এটি একটি নিখুঁত মন্তব্য তবে সম্পূর্ণ সঠিক নয়। যদি আপনি জেনেরিক গুণাবলী glVertexAttribPointer সংজ্ঞায়িত করতে ওপেনএল এপিআইয়ের দিকে নজর দেন , void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer)সনাক্তকারী হিসাবে উল্লেখ করা হয় index। প্রোগ্রামটির প্রসঙ্গে একই শনাক্তকারীকে locationএপিআই glGetAttribLocation বলা হয় ।
এপি-ওএসডি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.