Sử dụng XNA ContentPipeline để xuất tệp trong máy không có XNA GS đầy đủ


9

Trò chơi của tôi sử dụng Content Pipeline để tải spriteSheet khi chạy. Nghệ sĩ của trò chơi gửi cho tôi bản thảo đã được sửa đổi và tôi thực hiện một bản dựng trong máy của mình và gửi cho anh ta một dự án cập nhật. Vì vậy, tôi đang tìm cách tạo các tệp xnb trong máy của anh ấy (đây là đầu ra của đường ống nội dung) mà anh ấy không phải cài đặt studio XNA Game đầy đủ.

1) Tôi không muốn nghệ sĩ của mình cài đặt VS + Xna (Tôi biết có phiên bản VS miễn phí nhưng điều này sẽ không mở rộng khi chúng tôi thêm nhiều người vào nhóm). 2) Tôi không quan tâm đến việc chạy trình soạn thảo / công cụ này trong Xbox để giải pháp duy nhất cho Windows hoạt động. 3) Tôi biết các tùy chọn MSBuild nhưng chúng yêu cầu XNA đầy đủ

Tôi đã nghiên cứu blog của Shawn và tìm thấy tùy chọn sử dụng Msbuild Sample hoặc một tùy chọn mới trong XNA 4.0 có vẻ đầy hứa hẹn ở đây nhưng có vẻ như nó có cùng một hạn chế: Cần cài đặt XNA GS đầy đủ vì ContentPipeline không phải là một phần của XNA.

Vì vậy, có ai tìm thấy một cách giải quyết cho điều này?

Câu trả lời:


11

Có vẻ như câu trả lời đúng cho vấn đề này là bỏ qua ContentPipeline và sử dụng Texture2D.FromStream để tải kết cấu khi chạy. Phương pháp này hoạt động tốt trong PC và mặc dù sẽ có một hiệu suất nhỏ nhưng đây là điều tôi có thể tối ưu hóa một khi tôi đến gần ngày phát hành. Hiện tại, có khả năng tự động sửa đổi nội dung cho cả trình chỉnh sửa và trò chơi là chính xác những gì tôi cần. Khi nội dung bị đóng băng, tôi có thể tối ưu hóa điều này bằng cách quay lại ContentPipeline.

Vì bạn đã chọn tuyến đường này, tôi phải cảnh báo bạn rằng nó thực sự không đơn giản như chỉ sử dụng Texture2D.FromStreamvì hai lý do:

Vấn đề # 1 - Thiếu hỗ trợ alpha được nhân lên trước

XNA4 hiện xử lý họa tiết với màu sắc ở định dạng alpha được xử lý trước theo mặc định. Khi bạn tải một kết cấu thông qua đường ống nội dung, quá trình xử lý đó được thực hiện cho bạn một cách tự động. Thật không may Texture2D.FromStream, không làm điều tương tự, vì vậy bất kỳ kết cấu nào yêu cầu một mức độ minh bạch nào đó sẽ được tải và hiển thị không chính xác. Dưới đây là một ảnh chụp màn hình để minh họa vấn đề:

nhập mô tả hình ảnh ở đây

Vì vậy, để có được kết quả chính xác, bạn cần phải tự xử lý. Phương pháp tôi sẽ trình bày sử dụng GPU để xử lý nên khá nhanh. Nó được dựa trên bài viết tuyệt vời này . Tất nhiên bạn cũng có thể hướng dẫn SpriteBatchkết xuất ở chế độ NonPremultiplyAlpha cũ nhưng tôi không thực sự khuyên bạn nên làm điều đó.

Vấn đề # 2 - Các định dạng không được hỗ trợ

Các đường ống nội dung hỗ trợ nhiều định dạng hơn Texture2D.FromStream. Đặc biệt, Texture2D.FromStreamchỉ hỗ trợ png, jpg và gif. Mặt khác, đường ống nội dung hỗ trợ bmp, dds, dib, hdr, jpg, pfm, png, ppm và tga. Nếu bạn cố tải một định dạng được sử dụng thông qua Texture2D.FromStreambạn sẽ nhận được một InvalidOperationExceptionít thông tin bổ sung.

Tôi thực sự cần hỗ trợ bmp trên công cụ của mình vì vậy trong trường hợp cụ thể đó, tôi đã tìm thấy một cách giải quyết có vẻ hoạt động tốt. Tôi không biết về bất kỳ định dạng nào khác. Điều hấp dẫn với phương pháp của tôi là bạn cần thêm một tham chiếu đến System.Drawingtổ hợp vào dự án của mình, vì nó sử dụng GDI Image.FromStreamhỗ trợ nhiều định dạng hơn Texture2D.FromStream.

Nếu bạn không quan tâm đến việc hỗ trợ bmp, bạn có thể dễ dàng bỏ phần giải pháp đó của tôi và chỉ cần thực hiện xử lý alpha được nhân lên trước.

Giải pháp - Phiên bản đơn giản (chậm hơn)

Trước hết, đây là giải pháp đơn giản nhất nếu bạn không quan tâm đến việc hỗ trợ bmps. Trong ví dụ này, giai đoạn xử lý được thực hiện hoàn toàn trên CPU. Nó chậm hơn một chút so với giải pháp thay thế mà tôi sẽ trình bày bên dưới (tôi đã làm chuẩn cả hai giải pháp) nhưng dễ hiểu hơn:

public static Texture2D FromStream(GraphicsDevice graphicsDevice, Stream stream)
{
    Texture2D texture = Texture2D.FromStream(graphicsDevice, stream);
    Color[] data = new Color[texture.Width * texture.Height];
    texture.GetData(data);
    for (int i = 0; i != data.Length; ++i)
        data[i] = Color.FromNonPremultiplied(data[i].ToVector4());
    texture.SetData(data);
    return texture;
}

Nếu bạn quan tâm đến bmps thì việc bạn cần làm là tải hình ảnh bằng GDI trước rồi sau đó chuyển đổi thành PNG trước khi chuyển nó sang Texture2D.FromStream. Đây là mã thực hiện điều đó:

// Load image using GDI because Texture2D.FromStream doesn't support BMP
using (Image image = Image.FromStream(stream))
{
    // Now create a MemoryStream which will be passed to Texture2D after converting to PNG internally
    using (MemoryStream ms = new MemoryStream())
    {
        image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        ms.Seek(0, SeekOrigin.Begin);
        texture = Texture2D.FromStream(_graphicsDevice, ms);
    }
}

Giải pháp - Phiên bản phức tạp (Nhanh hơn)

Cuối cùng, cách tiếp cận tôi sử dụng cho các dự án của mình là sử dụng GPU để xử lý thay thế. Trong phương pháp này, bạn cần tạo mục tiêu kết xuất, thiết lập một số trạng thái pha trộn chính xác và vẽ hình ảnh hai lần bằng SpriteBatch. Cuối cùng, tôi đi qua toàn bộ RenderTarget2D và sao chép nội dung vào một đối tượng Texture2D riêng vì RenderTarget2D rất dễ bay hơi và sẽ không tồn tại những thứ như thay đổi kích thước backbuffer để sao chép an toàn hơn.

Điều buồn cười là ngay cả với tất cả những điều này, trong các thử nghiệm của tôi, phương pháp này đã thực hiện nhanh hơn khoảng 3 lần so với phương pháp CPU. Vì vậy, nó chắc chắn nhanh hơn so với việc đi qua từng pixel và tự tính toán màu sắc. Mã này hơi dài nên tôi đã đặt nó vào một pastebin:

http://pastie.org/3651642

Chỉ cần thêm lớp đó vào dự án của bạn và sử dụng nó đơn giản như:

TextureLoader textureLoader = new TextureLoader(GraphicsDevice);
Texture2D texture = textureLoader.FromFile("Content/texture.png");

Lưu ý: Bạn chỉ cần tạo một TextureLoaderphiên bản cho toàn bộ trò chơi. Ngoài ra, tôi đang sử dụng bản sửa lỗi BMP nhưng bạn có thể gỡ bỏ nếu bạn không cần và đạt được hiệu suất cao hoặc chỉ để lại needsBmptham số là sai.


wow, điều này thật tuyệt! Nó sẽ giúp tôi rất nhiều :) Cảm ơn David rất nhiều, tôi đánh giá cao nó.
krolth

+1 Trên thực tế, tôi đã sử dụng FromStreamvới một luồng bộ nhớ chứa bitmap 32 bit (được lưu vào png), giống như ví dụ khác của bạn, nhưng phương pháp này không tạo ra kết cấu được xử lý trước. Rõ ràng là tiền bối mỗi màu đã làm điều đó, cảm ơn.
Groo

3

Tôi nghĩ rằng hầu hết các đội sẽ cam kết thay đổi xnb (tốt, tất cả các thay đổi thực sự, xnb gộpud) cho máy chủ svn của họ (có thể được thiết lập miễn phí) và cho phép những người khác (nghệ sĩ, v.v.) cập nhật các bản sao làm việc của riêng họ.

Trên thực tế, đó sẽ là một cơ chế tốt để nghệ sĩ phiên bản kiểm soát nghệ thuật gốc (pre-xnb). Anh ấy sẽ cam kết thay đổi điều đó, bạn sẽ cập nhật bản sao làm việc của bạn, xây dựng nó (biến nó thành xnb trong quy trình), cam kết thay đổi của bạn, anh ấy cập nhật bản sao công việc của anh ấy và mọi người đều có thay đổi. (Bạn có tác phẩm nghệ thuật thô mới nhất, anh ấy có xnb (s).

Cái cân này cũng rất tốt.


Vì vậy, bạn đang nói rằng bạn không nghĩ rằng nó có thể được thực hiện? Đề xuất của bạn là thêm kiểm soát phiên bản vào XNB và các họa tiết, chúng tôi đã thực hiện điều đó. Nhưng tôi không thích nó vì tôi trở thành nút cổ chai cho họ. Tôi đã viết một công cụ cho họ để chỉnh sửa hình động và họ có thể thử chúng trong trò chơi. Nhưng nếu họ thực hiện thay đổi cho spritesheet, họ cần đợi cho đến khi tôi xây dựng nó trước khi họ có thể nhìn thấy nó. Như bạn có thể tưởng tượng nếu họ phạm sai lầm, họ cần phải làm lại.
krolth

@krolth Có phải là một thỏa thuận lớn khi các nghệ sĩ của bạn có được VS Express và XNA như một phần trong việc khiến họ thiết lập để làm việc trong một dự án? Tôi nghĩ rằng tại thời điểm này, sự đánh đổi của việc phải viết ra một hướng dẫn và giúp mọi người vượt qua nó sẽ vượt xa năng suất mà bạn đang mất bây giờ vì các nghệ sĩ không thể nhìn thấy công việc của họ. Để hợp lý hóa quy trình, cung cấp cho họ tệp .BAT để họ có thể nhấp đúp vào để biên dịch lại mọi thứ mà không cần phải mở IDE. Và nếu họ chỉ chạy OS X, tốt, thật khó khăn. Chào mừng bạn đến với trò chơi dev. Họ có thể cam kết các sprite của họ và chờ đợi các XNB đã cam kết tiếp theo.
michael.bartnett

nó không phải là một vấn đề lớn, chỉ là một nỗi đau. Nhưng tôi đoán nó sẽ phải làm. Cảm ơn mọi người vì câu trả lời / bình luận của bạn!
krolth

1

Tôi tiếp tục điều tra và sẽ đăng bài này vì lợi ích của một người có cùng câu hỏi.

Có vẻ như câu trả lời đúng cho vấn đề này là bỏ qua ContentPipeline và sử dụng Texture2D.FromStream để tải kết cấu khi chạy. Phương pháp này hoạt động tốt trong một máy tính và thậm chí mặc dù sẽ có một buổi biểu diễn nhỏ đánh này là một cái gì đó mà tôi có thể tối ưu hóa một lần tôi gần gũi hơn với ngày phát hành.

Hiện tại, có khả năng tự động sửa đổi nội dung cho cả trình chỉnh sửa và trò chơi là chính xác những gì tôi cần. Khi nội dung bị đóng băng, tôi có thể tối ưu hóa điều này bằng cách quay lại ContentPipeline.


Bạn đã kiểm tra điều này một cách chính xác? Từ kinh nghiệm của tôi Texture2D.FromStreamtự nó là không đủ. Lý do cho điều đó là vì phiên bản 4 XNA hoạt động với kết cấu alpha đã được xử lý trước và trong khi đường ống nội dung tự động xử lý việc xử lý này cho bạn, Texture2D.FromStreamthì bạn có thể sẽ gặp vấn đề khi vẽ các họa tiết có độ trong suốt. Tôi có thể đăng một giải pháp làm việc nếu bạn muốn mặc dù.
David Gouveia

Ngoài ra, Texture2D.FromStreamkhông hỗ trợ tải .BMPtệp trong khi đường ống nội dung. Đây là thứ có thể sẽ khiến bạn thất vọng nếu bạn sử dụng bất kỳ .BMPtài sản nào trước đó và sau đó chuyển sang Texture2D.FromStream. Tôi cũng có một cách giải quyết cho giới hạn đó. Tôi sẽ tiếp tục và đăng nó.
David Gouveia

0

Kiểm tra dự án này ra .

Nó sẽ cho phép nghệ sĩ của bạn tạo XNB từ bất kỳ thứ gì mà đường ống nội dung XNA mặc định hỗ trợ. Khung XNA có thể phân phối lại vẫn cần thiết mặc dù nghệ sĩ của bạn không cần Visual Studio.


Cảm ơn con trỏ. Nhìn vào mã có vẻ như là một sửa đổi cho mẫu Microsoft mà tôi đã tham chiếu. Nó phụ thuộc vào việc cài đặt XNA Game Studio đầy đủ (xem ContentBuilder.cs). Tại sao bạn nghĩ rằng nó không?
krolth

Tôi không nghĩ rằng nó không. Nếu bạn muốn sử dụng đường ống nội dung thì bạn phải có studio trò chơi đầy đủ. Tuy nhiên, dự án không ngăn các nghệ sĩ của bạn phải sử dụng Visual Studio. Chỉ có các lựa chọn thay thế khác để viết lại đường ống nội dung.
ClassicThunder
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.