Làm cách nào để tải họa tiết bằng SFML cho OpenGL?


Câu trả lời:


16

Chào mừng bạn đến với OpenGL, nơi những điều nhanh chóng đến miễn phí và những điều dễ dàng được thực hiện khó khăn.

Nếu bạn nghĩ rằng mẫu đó dài và phức tạp, "chỉ để tải một kết cấu", thì bạn chưa thấy gì. Đợi cho đến khi bạn phải tải họa tiết DDS, xử lý họa tiết HDR, hỗ trợ hình khối, kết xuất thành họa tiết, v.v.

Tải một kết cấu trong OpenGL bao gồm hai thành phần:

  • Lấy dữ liệu từ định dạng hình ảnh của bạn. Bạn có thể tải một kết cấu từ một tập tin hoặc tạo nó theo thủ tục. Không thành vấn đề, miễn là bạn kết thúc với một loạt thông tin màu sắc đẹp.

  • Đưa dữ liệu lên băng video. Dữ liệu cần phải đi từ RAM hệ thống sang RAM video.

Phần đầu tiên phải dễ dàng, vì SFML đi kèm với trình tải hình ảnh tiêu chuẩn.

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

Tiếp theo, chúng ta sẽ phải tạo một đối tượng kết cấu OpenGL.

GLuint texture_handle;
glGenTextures(1, &texture_handle);

Có một số lựa chọn để ràng buộc một kết cấu. Có ba loại chính: 1D, 2D và 3D và bạn có hỗ trợ cho hình khối (+ X, -X, + Y, -Y, + Z, -Z). Tuy nhiên, trong 99% trường hợp, bạn sẽ muốn có kết cấu 2D.

glBindTexture(GL_TEXTURE_2D, texture_handle);

Bây giờ chúng ta đến phần thú vị. Hãy tải dữ liệu của chúng tôi lên thẻ video.

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

Cuối cùng, chúng ta có thể thiết lập một số tham số kết cấu. Những câu trả lời này như: nếu chúng ta sử dụng tọa độ kết cấu nằm ngoài phạm vi (0,0, 1,0) thì sao? Chúng ta có quấn quanh ( GL_REPEAT) hay chúng ta không làm gì ( GL_CLAMP)? Chúng cũng có thể được sử dụng để giải thích cho videocard rằng chúng tôi muốn sử dụng phép nội suy tuyến tính trên kết cấu của chúng tôi.

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);

Và bây giờ bạn sẽ có thể liên kết kết cấu của bạn bằng cách sử dụng glBindTexturevà sử dụng nó để vẽ các mắt lưới kết cấu.


mmm, tôi đã thử làm như vậy và tất cả những gì tôi nhận được là một khối lập phương màu trắng: pastebin.com/nVQFAMRJ
Darestium

Hãy thử đưa glEnable(GL_TEXTURE2D);vào hàm init.
hiệp sĩ666

Tuyệt vời, hoạt động! Cảm ơn! BTW, chức năng đó làm gì? Cho phép kết cấu?
Darestium

Vâng, nó bật đối tượng kết cấu 2D, vì vậy nó có thể nhận dữ liệu kết cấu. Bạn chỉ phải kích hoạt nó một lần khi khởi tạo, nhưng nó thường bị lãng quên khi sao chép mã vào một dự án mới. Bao gồm cả bản thân mình. ;)
hiệp sĩ666

Giải thích rất hay. Bạn có thể viết hướng dẫn!
danijar

2

SFML 2.0+ giúp tải kết cấu dễ dàng hơn nữa;

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.