Làm cách nào để sửa đổi kết cấu trong SDL với truy cập pixel trực tiếp?


8

Tôi đang cố gắng sử dụng SDL_LockTexture và SDL_UnlockTexture để chỉnh sửa trực tiếp các pixel trong một kết cấu. Tôi đang sử dụng SDL 2.0. Đặt giá trị pixel bằng mã sau đây sẽ không sửa đổi kết cấu:

void *pixels;
int pitch;

SDL_LockTexture(mytexture, NULL, &pixels, &pitch);

// Set pixel 100,100 to blue
((uint32_t *)pixels)[100 * 100] = 255;

SDL_UnlockTexture(mytexture);

Giá trị trả về của SDL_LockTexture (...);?
Jon

Câu trả lời:


2

Tô màu kết cấu SDL có thể là một chút khó khăn. Các mã sau đây nên phác thảo các điểm chính của tô màu một kết cấu. Điều quan trọng là tìm nạp tất cả dữ liệu cần thiết từ SDL trước khi bắt đầu thay đổi kết cấu.

Uint32* pixels = nullptr;
int pitch = 0;
int format;

// Get the size of the texture.
int w, h;
SDL_QueryTexture(texture, &format, nullptr, &w, &h);

// Now let's make our "pixels" pointer point to the texture data.
if (SDL_LockTexture(texture, nullptr, (void**)&pixels, &pitch))
{
    // If the locking fails, you might want to handle it somehow. SDL_GetError(); or something here.
}

SDL_PixelFormat pixelFormat;
pixelFormat.format = format;
// Now you want to format the color to a correct format that SDL can use.
// Basically we convert our RGB color to a hex-like BGR color.
Uint32 color = SDL_MapRGB(&pixelFormat, R, G, B);

// Before setting the color, we need to know where we have to place it.
Uint32 pixelPosition = y * (pitch / sizeof(unsigned int)) + x;

// Now we can set the pixel(s) we want.
pixels[pixelPosition] = color;

// Also don't forget to unlock your texture once you're done.
SDL_UnlockTexture(texture);

Bây giờ, bạn cũng nên lưu ý rằng sửa đổi kết cấu trong mã là tương đối đắt tiền. Ngoài ra, mã này không được rõ ràng lắm, vì việc chỉnh sửa các mảng con trỏ int C ++ và dịch màu sang các định dạng khác nhau có thể gây ra vấn đề, vì những gì diễn ra ở nơi có thể không rõ ràng khi cần. Tuy nhiên, chỉ làm điều này khi thực sự cần thiết không nên gây ra quá nhiều vấn đề.

Bạn cũng có thể muốn xem xét sử dụng SDL_SetRenderTargetvà sửa đổi kết cấu bằng cách hiển thị nó. Tuy nhiên, đối với một số tác vụ, hiển thị nguyên thủy cho kết cấu có thể không phải là một tùy chọn và đó là trường hợp khi sửa đổi các pixel như thế này có thể trở nên tiện dụng.


1
1. Cách tiếp cận hoàn toàn sai, không chạm vào pixel trên Hoạ tiết, đó là những gì Bề mặt dành cho. - 2. Sử dụng SDL_MapRGB để tính toán màu sắc, sẽ không an toàn khi giả sử mọi thứ là RGBA 32 bit - 3. Sử dụng surface->BytesPerPixel, không an toàn khi giả sử ... vv
MickLH

Vượt qua các bề mặt và giữ những thứ đó trong bộ nhớ không đáng để IMHO nỗ lực, sửa đổi kết cấu bề mặt andor là điều nên được thực hiện hiếm khi, vì vậy việc chuyển pixel cho GPU không phải là một công cụ giải quyết ở đây. Tuy nhiên, đây SDL_MapRGBlà một điểm hợp lệ.
Tyyppi_77

-1

không chính xác - bạn cần các chi tiết định dạng "bề mặt" từ kết cấu - trước khi người ta có thể sử dụng MapRGB một cách mù quáng.

Để lấy dữ liệu - bạn truy vấn Texture- như đã nêu ở trên.

MapRGB hy vọng định dạng bề mặt-> (trong trường hợp của tôi là ^ .format) sẽ được trao cho nó. kiểm tra (cú pháp SDL trong các tệp tiêu đề)

Kết xuất với kết cấu là cách SDL2 hiệu quả hơn. bạn thường kết xuất hàng loạt - không cập nhật các pixel đơn lẻ- (ít nhất là cho đến khi làm mới màn hình tiếp theo). Rất nhiều người QUÁ kết xuất và nhận ra nó. Không trình bày cho đến khi màn hình (màn hình) sẵn sàng cho nó - làm như vậy gây ra "nhấp nháy". Cá nhân, Id đợi cho đến khi mọi thứ được kết xuất để kết thúc .... sau đó chuẩn bị các ops tiếp theo.

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.