ฉันจะโหลดพื้นผิวด้วย SFML สำหรับ OpenGL ได้อย่างไร


9

ฉันกำลังมองหาที่NeHe ของพื้นผิวการทำแผนที่การกวดวิชา มันดูซับซ้อนเกินไปสำหรับการโหลดพื้นผิว

มีวิธีการโหลดพื้นผิวใน SFML แล้วใช้มันใน Open GL หรือไม่ ฉันใช้ SFML สำหรับหน้าต่างของฉัน

คำตอบ:


16

ยินดีต้อนรับสู่ OpenGL ที่สิ่งรวดเร็วมาฟรีและสิ่งที่ง่ายทำยาก

หากคุณคิดว่าตัวอย่างนั้นยาวและซับซ้อน "เพียงแค่โหลดพื้นผิว" คุณก็ยังไม่เห็นอะไรเลย รอจนกว่าคุณจะต้องโหลดพื้นผิว DDS, ประมวลผลพื้นผิว HDR, สนับสนุน cubemaps, เรนเดอร์ไปสู่พื้นผิว, เป็นต้น

การโหลดพื้นผิวใน OpenGL ประกอบด้วยสององค์ประกอบ:

  • รับข้อมูลจากรูปแบบภาพของคุณ คุณสามารถโหลดพื้นผิวจากไฟล์หรือสร้างขั้นตอน มันไม่สำคัญตราบใดที่คุณมีข้อมูลสีจำนวนมาก

  • ใส่ข้อมูลลงใน videocard ข้อมูลจำเป็นต้องเปลี่ยนจาก RAM ระบบไปเป็น RAM วิดีโอ

ส่วนแรกควรเป็นเรื่องง่ายเพราะ SFML มาพร้อมกับตัวโหลดอิมเมจมาตรฐาน

sf::Image img_data;
if (!img_data.LoadFromFile("images/avatar.png"))
{
    LOG_ERROR("Could not load '%s'.", "images/avatar.png");
    return false;
}

ต่อไปเราจะต้องสร้างวัตถุพื้นผิว OpenGL

GLuint texture_handle;
glGenTextures(1, &texture_handle);

มีตัวเลือกมากมายสำหรับผูกพื้นผิว มีสามประเภทหลัก: 1D, 2D และ 3D และคุณได้รับการสนับสนุน cubemaps (+ X, -X, + Y, -Y, + Z, -Z) อย่างไรก็ตามใน 99% ของกรณีคุณจะต้องการพื้นผิวแบบ 2D

glBindTexture(GL_TEXTURE_2D, texture_handle);

ตอนนี้เราไปถึงส่วนที่น่าสนใจ มาอัปโหลดข้อมูลของเราไปยังการ์ดวิดีโอ

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_RGBA,
    img_data.GetWidth(), img_data.GetHeight(),
    0,
    GL_RGBA, GL_UNSIGNED_BYTE, img_data.GetPixelsPtr()
);

สุดท้ายเราสามารถตั้งค่าพารามิเตอร์พื้นผิวได้จำนวนหนึ่ง คำถามคำตอบเหล่านี้เช่น: ถ้าเราใช้การประสานพื้นผิวที่อยู่นอกช่วง (0.0, 1.0) เราห่อหุ้ม ( GL_REPEAT) หรือไม่ทำอะไรเลย ( GL_CLAMP)? พวกเขายังสามารถใช้อธิบายวิดีโอที่เราต้องการใช้การแก้ไขเชิงเส้นบนพื้นผิวของเรา

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

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


mmm ฉันพยายามทำเช่นนั้นและสิ่งที่ฉันได้รับคือลูกบาศก์สีขาว: pastebin.com/nVQFAMRJ
Darestium

ลองใส่glEnable(GL_TEXTURE2D);ฟังก์ชั่น init
knight666

เยี่ยมมากเลย! ขอบคุณ! BTW ฟังก์ชั่นนั้นทำอะไร? เปิดใช้งานการกำหนดพื้นผิวหรือไม่
Darestium

ใช่มันเปิดวัตถุพื้นผิว 2D เพื่อให้สามารถรับข้อมูลพื้นผิวได้ คุณต้องเปิดใช้งานเพียงครั้งเดียวเมื่อเริ่มต้น แต่มักจะลืมเมื่อคัดลอกรหัสไปยังโครงการใหม่ รวมตัวเองด้วย ;)
knight666

คำอธิบายที่ดีมาก คุณสามารถเขียนบทเรียน!
danijar

2

SFML 2.0+ ทำให้การโหลดพื้นผิวง่ายยิ่งขึ้น

sf::Texture texLid;
std::string image2="images/top.jpg";
if (!texLid.loadFromFile(image2))
{
    std::cout << "Could not load" << image2;
    char c;
    std::cin>>c;
    return false;
}


glEnable(GL_TEXTURE_2D);//tell OpenGL to use textures when drawing

sf::Texture::bind(&texLid);//select this texture for OpenGL rendering
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.