ความแตกต่างและความสัมพันธ์ระหว่าง glActiveTexture และ glBindTexture


137

จากสิ่งที่ฉันรวบรวมให้glActiveTextureตั้งค่า "หน่วยพื้นผิว" ที่ใช้งานอยู่ แต่ละหน่วยพื้นผิวสามารถมีเป้าหมายพื้นผิวได้หลายแบบ (โดยปกติคือ GL_TEXTURE_1D, 2D, 3D หรือ CUBE_MAP)

ถ้าฉันเข้าใจถูกต้องคุณต้องเรียกglActiveTextureเพื่อตั้งค่าหน่วยพื้นผิวก่อน (เริ่มต้นเป็นGL_TEXTURE0) แล้วคุณผูก "เป้าหมายพื้นผิว" (หนึ่งหรือมากกว่า) กับหน่วยพื้นผิวนั้น?

จำนวนหน่วยพื้นผิวที่ใช้ได้ขึ้นอยู่กับระบบ ฉันเห็น enums มากถึง 32 ในห้องสมุดของฉัน ฉันเดาว่าโดยพื้นฐานแล้วหมายความว่าฉันสามารถมีขีด จำกัด GPU น้อยกว่าของฉันได้ (ซึ่งฉันคิดว่าเป็น168) และ 32 พื้นผิวในหน่วยความจำ GPU ในคราวเดียว? ฉันเดาว่ามีขีด จำกัด เพิ่มเติมที่ฉันจะไม่เกินหน่วยความจำสูงสุดของ GPU (ประมาณ 1 GB)

ฉันเข้าใจความสัมพันธ์ระหว่างเป้าหมายพื้นผิวและหน่วยพื้นผิวอย่างถูกต้องหรือไม่ สมมติว่าฉันได้รับอนุญาต 16 ยูนิตและ 4 เป้าหมายแต่ละอันหมายความว่ามีที่ว่างสำหรับ 16 * 4 = 64 เป้าหมายหรือไม่ได้ผลเช่นนั้น?

ถัดไปคุณมักจะต้องโหลดพื้นผิว คุณสามารถทำได้ผ่านทางglTexImage2D. อาร์กิวเมนต์แรกซึ่งเป็นเป้าหมายพื้นผิว หากได้ผลเช่นglBufferDataนั้นเราจะผูก "ที่จับ" / "ชื่อพื้นผิว" กับเป้าหมายพื้นผิวเป็นหลักจากนั้นโหลดข้อมูลพื้นผิวลงในเป้าหมายนั้นและเชื่อมโยงโดยอ้อมกับจุดจับนั้น

เกี่ยวกับอะไรglTexParameter? เราต้องผูกเป้าหมายพื้นผิวแล้วเลือกเป้าหมายเดียวกันอีกครั้งเป็นอาร์กิวเมนต์แรก? หรือพื้นผิวเป้าหมายไม่จำเป็นต้องถูกผูกไว้ตราบเท่าที่เรามีหน่วยพื้นผิวที่ใช้งานอยู่ที่ถูกต้อง?

glGenerateMipmap ทำงานกับเป้าหมายด้วย ... เป้าหมายนั้นยังต้องผูกติดกับชื่อพื้นผิวเพื่อให้สำเร็จ?

จากนั้นเมื่อเราต้องการวาดวัตถุของเราด้วยพื้นผิวเราต้องเลือกทั้งหน่วยพื้นผิวที่ใช้งานอยู่แล้วจึงกำหนดเป้าหมายพื้นผิวหรือไม่? หรือเราเลือกหน่วยพื้นผิวจากนั้นเราสามารถดึงข้อมูลจาก 4 เป้าหมายที่เกี่ยวข้องกับหน่วยนั้นได้หรือไม่? นี่คือส่วนที่ทำให้ฉันสับสนจริงๆ

คำตอบ:


262

ทั้งหมดเกี่ยวกับวัตถุ OpenGL

โมเดลมาตรฐานสำหรับอ็อบเจ็กต์ OpenGL มีดังนี้

วัตถุมีสถานะ คิดว่าเป็นไฟล์struct. ดังนั้นคุณอาจมีวัตถุที่กำหนดไว้เช่นนี้:

struct Object
{
    int count;
    float opacity;
    char *name;
};

วัตถุมีค่าบางอย่างเก็บไว้ในนั้นและจะมีรัฐ วัตถุ OpenGL ก็มีสถานะเช่นกัน

กำลังเปลี่ยนสถานะ

ใน C / C ++ หากคุณมีอินสแตนซ์ประเภทObjectคุณจะเปลี่ยนสถานะดังต่อไปนี้: obj.count = 5;คุณจะอ้างอิงอินสแตนซ์ของวัตถุโดยตรงรับสถานะเฉพาะที่คุณต้องการเปลี่ยนแปลงและใส่ค่าลงไป

ใน OpenGL คุณจะไม่ทำสิ่งนี้

ด้วยเหตุผลเดิมที่ดีกว่าไม่ได้อธิบายไว้ในการเปลี่ยนสถานะของอ็อบเจ็กต์ OpenGL คุณต้องผูกมันกับบริบทก่อน สิ่งนี้ทำได้ด้วยบางส่วนจากการglBind*โทร

เทียบเท่า C / C ++ มีดังนี้:

Object *g_objs[MAX_LOCATIONS] = {NULL};    
void BindObject(int loc, Object *obj)
{
  g_objs[loc] = obj;
}

พื้นผิวมีความน่าสนใจ พวกเขาเป็นตัวแทนของกรณีพิเศษของการผูกมัด การglBind*เรียกจำนวนมากมีพารามิเตอร์ "target" สิ่งนี้แสดงถึงตำแหน่งที่แตกต่างกันในบริบท OpenGL ที่สามารถผูกวัตถุประเภทนั้นได้ ตัวอย่างเช่นคุณสามารถผูกอ็อบเจ็กต์ framebuffer สำหรับการอ่าน ( GL_READ_FRAMEBUFFER) หรือสำหรับการเขียน ( GL_DRAW_FRAMEBUFFER) สิ่งนี้มีผลต่อวิธีที่ OpenGL ใช้บัฟเฟอร์ นี่คือสิ่งที่locพารามิเตอร์ด้านบนแสดงถึง

พื้นผิวมีความพิเศษเนื่องจากเมื่อคุณผูกเข้ากับเป้าหมายเป็นครั้งแรกพวกเขาจะได้รับข้อมูลพิเศษ เมื่อคุณผูกพื้นผิวเป็นครั้งแรกGL_TEXTURE_2Dคุณกำลังตั้งค่าสถานะพิเศษในพื้นผิว คุณกำลังบอกว่าพื้นผิวนี้เป็นพื้นผิว 2 มิติ และจะเป็นพื้นผิว 2 มิติเสมอ สถานะนี้ไม่สามารถเปลี่ยนแปลงได้ตลอดไป ถ้าคุณมีพื้นผิวที่ถูกผูกไว้ครั้งแรกในฐานะที่GL_TEXTURE_2Dคุณต้องเสมอผูกเป็นGL_TEXTURE_2D; พยายามผูกมันเนื่องจากGL_TEXTURE_1Dจะทำให้เกิดข้อผิดพลาด (ขณะรันไทม์)

เมื่อวัตถุถูกผูกไว้แล้วสถานะของมันสามารถเปลี่ยนแปลงได้ สิ่งนี้ทำได้ผ่านฟังก์ชันทั่วไปเฉพาะสำหรับวัตถุนั้น พวกเขาก็ใช้ตำแหน่งที่แสดงถึงวัตถุที่จะแก้ไขเช่นกัน

ใน C / C ++ จะมีลักษณะดังนี้:

void ObjectParameteri(int loc, ObjectParameters eParam, int value)
{
  if(g_objs[loc] == NULL)
    return;

  switch(eParam)
  {
    case OBJECT_COUNT:
      g_objs[loc]->count = value;
      break;
    case OBJECT_OPACITY:
      g_objs[loc]->opacity = (float)value;
      break;
    default:
      //INVALID_ENUM error
      break;
  }
}

สังเกตว่าฟังก์ชันนี้ตั้งค่าสิ่งที่เกิดขึ้นเป็นlocค่าที่ถูกผูกไว้ในปัจจุบันอย่างไร

glTexParameterสำหรับวัตถุพื้นผิวรัฐเนื้อหลักเปลี่ยนฟังก์ชั่น ฟังก์ชันอื่น ๆ เท่านั้นที่เปลี่ยนสถานะพื้นผิวคือglTexImageฟังก์ชันและรูปแบบต่างๆ ( glCompressedTexImage, glCopyTexImageล่าสุดglTexStorage) ต่าง ๆSubImageรุ่นที่เปลี่ยนเนื้อหาของเนื้อ แต่พวกเขาไม่ได้ในทางเทคนิคเปลี่ยนของรัฐ Imageฟังก์ชั่นการจัดเก็บข้อมูลการจัดสรรพื้นผิวและกำหนดรูปแบบพื้นผิวของ; SubImageฟังก์ชั่นเพียงคัดลอกพิกเซลรอบ ๆ นั่นไม่ถือว่าเป็นสถานะของพื้นผิว

อนุญาตให้ฉันทำซ้ำ: นี่เป็นฟังก์ชันเดียวที่แก้ไขสถานะพื้นผิว glTexEnvปรับเปลี่ยนสถานะสภาพแวดล้อม มันไม่ส่งผลกระทบต่อสิ่งที่เก็บไว้ในวัตถุพื้นผิว

พื้นผิวที่ใช้งานอยู่

สถานการณ์ของพื้นผิวมีความซับซ้อนมากขึ้นอีกครั้งด้วยเหตุผลทางมรดกที่ดีที่สุดที่ยังไม่เปิดเผย นี่คือที่glActiveTextureมา

สำหรับพื้นผิวที่มีไม่ได้เป็นเพียงเป้าหมาย ( GL_TEXTURE_1D, GL_TEXTURE_CUBE_MAPฯลฯ ) นอกจากนี้ยังมีเนื้อหน่วย ในตัวอย่าง C / C ++ ของเราสิ่งที่เรามีคือ:

Object *g_objs[MAX_OBJECTS][MAX_LOCATIONS] = {NULL};
int g_currObject = 0;

void BindObject(int loc, Object *obj)
{
  g_objs[g_currObject][loc] = obj;
}

void ActiveObject(int currObject)
{
  g_currObject = currObject;
}

สังเกตว่าตอนนี้เราไม่เพียง แต่มีรายการ 2 มิติObjectเท่านั้น แต่เรายังมีแนวคิดของวัตถุปัจจุบัน เรามีฟังก์ชั่นในการตั้งค่าวัตถุปัจจุบันเรามีแนวคิดเกี่ยวกับจำนวนสูงสุดของวัตถุปัจจุบันและฟังก์ชันการจัดการวัตถุทั้งหมดของเราจะได้รับการปรับให้เลือกจากวัตถุปัจจุบัน

เมื่อคุณเปลี่ยนวัตถุที่ใช้งานอยู่คุณจะเปลี่ยนชุดเป้าหมายทั้งหมด ดังนั้นคุณสามารถผูกสิ่งที่เข้ากับวัตถุปัจจุบัน 0 เปลี่ยนเป็นวัตถุปัจจุบัน 4 และจะแก้ไขวัตถุที่แตกต่างกันโดยสิ้นเชิง

การเปรียบเทียบกับวัตถุพื้นผิวนี้สมบูรณ์แบบ ... เกือบ

ดูglActiveTextureไม่ใช้จำนวนเต็ม จะใช้เวลาการแจงนับ ซึ่งในทางทฤษฎีหมายความว่ามันสามารถใช้อะไรจากการGL_TEXTURE0 GL_TEXTURE31แต่มีสิ่งหนึ่งที่คุณต้องเข้าใจ:

นี่คือความผิด!

ช่วงที่เกิดขึ้นจริงที่สามารถใช้เวลาอยู่ภายใต้glActiveTexture GL_MAX_COMBINED_TEXTURE_IMAGE_UNITSนั่นคือจำนวนสูงสุดของมัลติเท็กซ์เจอร์พร้อมกันที่การใช้งานอนุญาต สิ่งเหล่านี้แบ่งออกเป็นกลุ่มที่แตกต่างกันสำหรับขั้นตอนการสร้างเงา ตัวอย่างเช่นบนฮาร์ดแวร์คลาส GL 3.x คุณจะได้รับพื้นผิวจุดสุดยอด 16 พื้นผิวส่วนเงา 16 ส่วนและพื้นผิวรูปทรงเรขาคณิต 16 แบบ ดังนั้นGL_MAX_COMBINED_TEXTURE_IMAGE_UNITSจะเป็น 48

แต่ไม่มีผู้แจงนับ 48 คน ซึ่งเป็นเหตุผลที่glActiveTextureไม่ใช้ตัวแจงนับ ที่ถูกต้องวิธีการเรียกร้องglActiveTextureดังต่อไปนี้:

glActiveTexture(GL_TEXTURE0 + i);

ซึ่งiเป็นตัวเลขระหว่าง 0 GL_MAX_COMBINED_TEXTURE_IMAGE_UNITSและ

การแสดงผล

แล้วทั้งหมดนี้เกี่ยวข้องกับการเรนเดอร์อย่างไร?

เมื่อใช้เฉดสีคุณตั้งค่าเครื่องแบบแซมเปิลของคุณเป็นหน่วยภาพพื้นผิว (หน่วยภาพglUniform1i(samplerLoc, i)อยู่ที่ไหนi) glActiveTextureที่แสดงถึงหมายเลขที่คุณใช้กับ ตัวอย่างจะเลือกเป้าหมายตามประเภทตัวอย่าง ดังนั้นsampler2DจะเลือกจากGL_TEXTURE_2Dเป้าหมาย นี่เป็นสาเหตุหนึ่งที่ทำให้แซมเปิลมีประเภทต่างๆ

ตอนนี้ฟังดูน่าสงสัยเช่นคุณสามารถมี GLSL samplers สองตัวโดยประเภทต่างๆที่ใช้หน่วยภาพพื้นผิวเดียวกัน แต่คุณทำไม่ได้ OpenGL ห้ามสิ่งนี้และจะทำให้คุณมีข้อผิดพลาดเมื่อคุณพยายามแสดงผล


12
ว้าว! อีกคำตอบที่ยอดเยี่ยม - ขอบคุณ Nicol! ผมชอบเกี่ยวกับวรรคเนื้อ 2D ที่มักจะเป็นเนื้อ 2D ตอนนี้ฉันกำลังสร้างกระดาษห่อหุ้มสิ่งเหล่านี้และฉันไม่แน่ใจว่าควรปล่อยให้มันเปลี่ยนแปลงไปหรือไม่ และส่วนที่เกี่ยวกับGL_TEXTURE0 + i- ฉันหมายถึงการตรวจสอบค่า enum เพื่อดูว่าถูกต้องหรือไม่ และย่อหน้าสุดท้าย - ไม่รู้ว่าถูกกฎหมายหรือไม่ ยอดเยี่ยม! ฉันบุ๊กมาร์กคำตอบทั้งหมดของคุณเพื่อให้สามารถอ้างอิงได้อีกครั้ง
mpen

6
@Nicol Bolas: นี่เป็นคำอธิบายที่ดีจริงๆ คุณควรคัดลอกบางส่วนไปยังบทพื้นผิวในหนังสือ opengl ออนไลน์ของคุณ ฉันคิดว่าเรื่องนี้ชัดเจนกว่ามากและจะชมเชยบทนี้ด้วย
WesDec

3
@Nicol Bolas ฉันเพิ่งเริ่มเรียนรู้ OpenGL และคำตอบนี้ช่วยฉันได้มาก ขอบคุณ!
อินไลน์

2
สวัสดีนิโคเพียงต้องการชี้ให้เห็นการพิมพ์ผิดเล็กน้อยของคุณ: GL_DRAW_FRAMEBUFFER ไม่ใช่ GL_WRITE_FRAMEBUFFER
Defd

3
@Nicol: ว้าวคำจำกัดความที่ดีที่สุดที่ฉันเคยมีมาก่อนตอนนี้มาจากบทเรียนการสังเคราะห์แสงของคุณตอนนี้คุณทำได้ดีกว่าแหล่งข้อมูลที่ยอดเยี่ยม Thankyou
Baggers

21

จะลองดู! ทั้งหมดนี้ไม่ได้ซับซ้อนแค่คำถามเกี่ยวกับเงื่อนไขหวังว่าฉันจะทำให้ตัวเองกระจ่าง


คุณสามารถสร้างTexture Objects ได้มากเท่าที่มีหน่วยความจำในระบบของคุณ ออบเจ็กต์เหล่านี้เก็บข้อมูลจริง (เท็กซ์) ของพื้นผิวของคุณพร้อมกับพารามิเตอร์ที่จัดหาโดยglTexParameter (ดูคำถามที่พบบ่อย )

เมื่อถูกสร้างขึ้นคุณจะต้องกำหนดหนึ่งเนื้อเป้าหมายไปยังวัตถุเนื้อหนึ่งซึ่งหมายถึงชนิดของพื้นผิว ( GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE, ... )

ทั้งสองรายการวัตถุพื้นผิวและเป้าหมายพื้นผิวแสดงถึงข้อมูลพื้นผิว เราจะกลับมาหาพวกเขาในภายหลัง

หน่วยพื้นผิว

ตอนนี้ OpenGL มีอาร์เรย์ของหน่วยพื้นผิวที่สามารถใช้พร้อมกันในขณะวาด ขนาดของอาร์เรย์ขึ้นอยู่กับระบบ OpenGL ของคุณมี 8

คุณสามารถผูกวัตถุพื้นผิวกับหน่วยพื้นผิวเพื่อใช้พื้นผิวที่กำหนดขณะวาดได้

ในโลกที่เรียบง่ายและง่ายดายในการวาดด้วยพื้นผิวที่กำหนดคุณต้องผูกวัตถุพื้นผิวเข้ากับหน่วยพื้นผิวและคุณจะทำ (รหัสเทียม):

glTextureUnit[0] = textureObject

เนื่องจาก GL เป็นเครื่องจักรของรัฐ แต่อนิจจาไม่ทำงานในลักษณะนี้ สมมติว่าเราtextureObjectมีข้อมูลสำหรับGL_TEXTURE_2Dพื้นผิวเป้าหมายเราจะแสดงการมอบหมายก่อนหน้านี้เป็น:

glActiveTexture(GL_TEXTURE0);                   // select slot 0 of the texture units array
glBindTexture(GL_TEXTURE_2D, textureObject);    // do the binding

โปรดทราบว่าGL_TEXTURE_2Dขึ้นอยู่กับประเภทของพื้นผิวที่คุณต้องการผูก

วัตถุพื้นผิว

ในรหัสหลอกในการตั้งค่าข้อมูลพื้นผิวหรือพารามิเตอร์พื้นผิวคุณต้องทำเช่น:

setTexData(textureObject, ...)
setTexParameter(textureObject, TEXTURE_MIN_FILTER, LINEAR)

OpenGL ไม่สามารถจัดการกับวัตถุพื้นผิวได้โดยตรงในการอัปเดต / ตั้งค่าเนื้อหาหรือเปลี่ยนพารามิเตอร์คุณต้องผูกไว้กับหน่วยพื้นผิวที่ใช้งานอยู่ก่อน (แล้วแต่ว่าจะเป็นแบบใด) รหัสเทียบเท่าจะกลายเป็น:

glBindTexture(GL_TEXTURE_2D, textureObject)       // this 'installs' textureObject in texture unit
glTexImage2D(GL_TEXTURE_2D, ...)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)

เฉดสี

เฉดสีสามารถเข้าถึงหน่วยพื้นผิวทั้งหมดพวกเขาไม่สนใจพื้นผิวที่ใช้งานอยู่

เครื่องแบบแซมเพลอร์คือintค่าที่แสดงดัชนีของหน่วยพื้นผิวที่จะใช้สำหรับตัวอย่าง ( ไม่ใช่วัตถุพื้นผิวที่จะใช้)

ดังนั้นคุณต้องผูกวัตถุพื้นผิวของคุณกับหน่วยที่คุณต้องการใช้

ประเภทของตัวอย่างจะจับคู่กับเป้าหมายพื้นผิวที่ใช้ในหน่วยพื้นผิว: Sampler2DสำหรับGL_TEXTURE_2Dและอื่น ๆ ...


สิ่งหนึ่งที่ฉันไม่เข้าใจ สมมติว่าฉันมีพื้นผิวบางส่วนและถูกใช้ในเฉดสีจำนวนมากในหน่วยพื้นผิวที่แตกต่างกัน สมมติว่าฉันต้องการเปลี่ยนการกรองพื้นผิวในเวลาทำงาน ฉันควรใช้หน่วยพื้นผิวใด ฉันสามารถเปลี่ยนสถานะพื้นผิวในหน่วย 0 แล้วใช้พื้นผิวนั้นกับหน่วยอื่นได้หรือไม่
majakthecoder

@majakthecoder ในคำตอบของฉันฉันถือว่าการกรองเป็นคุณสมบัติของวัตถุพื้นผิวซึ่งหมายความว่าคุณไม่สามารถเปลี่ยนเฉพาะในหน่วยพื้นผิวได้ ขึ้นอยู่กับรสชาติของ OpenGL ที่คุณกำหนดเป้าหมายคุณอาจสามารถสุ่มตัวอย่างวัตถุเพื่อแก้ปัญหานี้ได้ ( opengl.org/wiki/Sampler_Object ) มิฉะนั้นคุณอาจต้องทำซ้ำวัตถุพื้นผิวเพื่อให้มีการกรองหลายรายการพร้อมกัน
rotoglup

12

ลองนึกภาพ GPU เหมือนโรงงานแปรรูปสีบางแห่ง

มีรถถังจำนวนหนึ่งซึ่งส่งสีย้อมไปยังเครื่องพ่นสี ในเครื่องพ่นสีจะใช้สีย้อมกับวัตถุ รถถังเหล่านั้นเป็นหน่วยพื้นผิว

ถังเหล่านี้สามารถติดตั้งสีย้อมชนิดต่างๆได้ สีย้อมแต่ละชนิดต้องใช้ตัวทำละลายชนิดอื่น "การทำละลาย" คือเป้าหมายเนื้อ เพื่อความสะดวกในแต่ละถังจะเชื่อมต่อกับแหล่งจ่ายตัวทำละลายบางชนิดและสามารถใช้ตัวทำละลายได้ครั้งละหนึ่งชนิดเท่านั้นในแต่ละถัง ดังนั้นจึงมีวาล์ว / สวิทช์TEXTURE_CUBE_MAP, TEXTURE_3D, ,TEXTURE_2D TEXTURE_1Dคุณสามารถเติมสีย้อมทุกประเภทลงในถังได้ในเวลาเดียวกัน แต่เนื่องจากตัวทำละลายเพียงชนิดเดียวเข้าไปจึงจะ "เจือจาง" เฉพาะชนิดของสีย้อมที่ตรงกัน ดังนั้นคุณสามารถผูกพื้นผิวแต่ละชนิดได้ แต่การผูกด้วยตัวทำละลายที่ "สำคัญที่สุด" จะเข้าไปในถังและผสมกับสีย้อมที่เป็นของมัน

แล้วก็มีสีย้อมเองซึ่งมาจากโกดังและเติมลงในถังโดยการ "มัด" นั่นคือพื้นผิวของคุณ


2
การเปรียบเทียบแบบแปลก ๆ ... ฉันไม่แน่ใจว่ามันจะเคลียร์อะไรได้จริงๆ โดยเฉพาะอย่างยิ่งส่วนที่เกี่ยวกับ "การเจือจาง" และ "ตัวทำละลายที่สำคัญที่สุด" คุณกำลังบอกว่าถ้าฉันผูกทั้งพื้นผิว 2 มิติและพื้นผิว 3 มิติฉันสามารถใช้เพียงหนึ่งในนั้นหรืออะไร? สิ่งใดที่ถือว่าสำคัญที่สุด?
mpen

2
@ มาร์ค: ฉันพยายามพูดในแง่ของจิตรกรที่ทำงานกับสีย้อมตามตัวอักษร (พูดว่าใช้น้ำมันและน้ำ) อย่างไรก็ตามใช่หากคุณเชื่อมโยงและเปิดใช้งานพื้นผิวหลายเป้าหมายจะมีลำดับความสำคัญ: CUBE_MAP> 3D> TEXTURE_ARRAY> 2D> 1D
datenwolf

1
เรียบร้อย! ฉันไม่ทราบเกี่ยวกับลำดับความสำคัญ ทำให้รู้สึกมากขึ้นตอนนี้ฉันรู้ว่าสามารถใช้เป้าหมายพื้นผิวได้เพียงหนึ่งชิ้นต่อหนึ่งหน่วยพื้นผิว
mpen

1
@ legends2k: ตอนนี้เริ่มน่าสนใจแล้ว เรากำลังพูดถึงแกนหลักหรือโปรไฟล์ความเข้ากันได้ เราคิดว่าคนขับรถในอุดมคติหรือรถบักกี้ ตามทฤษฎีแล้วประเภทของเครื่องแบบจะเลือกเป้าหมายของหน่วยพื้นผิวที่จะเลือก ในทางปฏิบัติสิ่งนี้เกิดขึ้นในโปรไฟล์หลัก ในโปรไฟล์ความเข้ากันได้คาดว่าไดรเวอร์บั๊กกี้บางตัวจะแสดงพื้นผิวเริ่มต้นสีขาวทั้งหมดให้คุณหากเป้าหมายก่อนหน้าของหน่วยพื้นผิวไม่ตรงกับประเภทของตัวอย่าง
datenwolf

1
@ legends2k: ลองคิดดูว่าจะเกิดอะไรขึ้นถ้ามีพื้นผิว 2D และ 3D ที่เชื่อมโยงกับหน่วยเดียวกันและคุณมีเครื่องแบบ 2D และ 3D ซึ่งคุณเชื่อมโยงกับหน่วยเดียวกัน? คุณสามารถเรียกใช้ข้อบกพร่องของไดรเวอร์แปลก ๆ ได้ทุกชนิด ในการฝึกคิดในรูปแบบลำดับความสำคัญของฟังก์ชันคงที่แบบเก่าจะช่วยให้จิตใจของคุณมีสติและโปรแกรมของคุณทำงานได้ดีเพราะนั่นเป็นวิธีที่คนขับส่วนใหญ่จะประพฤติตัวในลักษณะที่คาดเดาได้
datenwolf

2

หากใน shader ของคุณคุณต้องค้นหาจาก 2 พื้นผิว:

uniform sampler2D tex1;  
uniform sampler2D tex2;  

จำเป็นต้องระบุแหล่งที่มาของ tex1 และ tex2 ดังนี้:

tex1 = gl.createTexture();  
gl.activeTexture(gl.TEXTURE3);  
gl.bindTexture(gl.TEXTURE_2D, tex1); 
gl.texParameteri(gl.TEXTURE_2D, ...);  
....


tex2 = gl.createTexture();  
gl.activeTexture(gl.TEXTURE7);  
gl.bindTexture(gl.TEXTURE_2D, tex2); 
gl.texParameteri(gl.TEXTURE_2D, ...);  
....  
var tex1Loc  = gl.getUniformLocation(your_shader,"tex1");  
var tex2Loc  = gl.getUniformLocation(your_shader,"tex2");

ในลูปการแสดงผล:

gl.uniform1i(tex1Loc, 3);  
gl.uniform1i(tex2Loc, 7);  
// but you can dynamically change these values

ด้วย gl_bindtexture ไม่สามารถทำสิ่งนั้นได้ ในทางกลับกันการใช้การโยงในลูปของการแสดงผลที่เป็นไปได้คือกรณีที่คุณป้อนพื้นผิวด้วยเนื้อหาในสตรีม (วิดีโอเว็บแคม):

gl.bindTexture(gl.TEXTURE_2D, tex1);  
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video);  
// in the render loop
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.