Skip to content

Commit 10a5a53

Browse files
author
Roberto De Ioris
committed
added render_target_get_data_to_buffer()
1 parent 4228109 commit 10a5a53

File tree

3 files changed

+99
-30
lines changed

3 files changed

+99
-30
lines changed

Source/UnrealEnginePython/Private/UEPyModule.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,7 @@ static PyMethodDef ue_PyUObject_methods[] = {
837837
{ "texture_get_width", (PyCFunction)py_ue_texture_get_width, METH_VARARGS, "" },
838838
{ "texture_get_height", (PyCFunction)py_ue_texture_get_height, METH_VARARGS, "" },
839839
{ "render_target_get_data", (PyCFunction)py_ue_render_target_get_data, METH_VARARGS, "" },
840+
{ "render_target_get_data_to_buffer", (PyCFunction)py_ue_render_target_get_data_to_buffer, METH_VARARGS, "" },
840841
{ "texture_update_resource", (PyCFunction)py_ue_texture_update_resource, METH_VARARGS, "" },
841842

842843
#if WITH_EDITOR

Source/UnrealEnginePython/Private/UObject/UEPyTexture.cpp

Lines changed: 97 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
#include "Runtime/Engine/Public/ImageUtils.h"
44
#include "Runtime/Engine/Classes/Engine/Texture.h"
55

6-
PyObject *py_ue_texture_update_resource(ue_PyUObject *self, PyObject * args) {
6+
PyObject *py_ue_texture_update_resource(ue_PyUObject *self, PyObject * args)
7+
{
78

89
ue_py_check(self);
910

@@ -15,7 +16,8 @@ PyObject *py_ue_texture_update_resource(ue_PyUObject *self, PyObject * args) {
1516
Py_RETURN_NONE;
1617
}
1718

18-
PyObject *py_ue_texture_get_width(ue_PyUObject *self, PyObject * args) {
19+
PyObject *py_ue_texture_get_width(ue_PyUObject *self, PyObject * args)
20+
{
1921

2022
ue_py_check(self);
2123

@@ -26,7 +28,8 @@ PyObject *py_ue_texture_get_width(ue_PyUObject *self, PyObject * args) {
2628
return PyLong_FromLong(texture->GetSizeX());
2729
}
2830

29-
PyObject *py_ue_texture_get_height(ue_PyUObject *self, PyObject * args) {
31+
PyObject *py_ue_texture_get_height(ue_PyUObject *self, PyObject * args)
32+
{
3033

3134
ue_py_check(self);
3235

@@ -37,13 +40,15 @@ PyObject *py_ue_texture_get_height(ue_PyUObject *self, PyObject * args) {
3740
return PyLong_FromLong(texture->GetSizeY());
3841
}
3942

40-
PyObject *py_ue_texture_get_data(ue_PyUObject *self, PyObject * args) {
43+
PyObject *py_ue_texture_get_data(ue_PyUObject *self, PyObject * args)
44+
{
4145

4246
ue_py_check(self);
4347

4448
int mipmap = 0;
4549

46-
if (!PyArg_ParseTuple(args, "|i:texture_get_data", &mipmap)) {
50+
if (!PyArg_ParseTuple(args, "|i:texture_get_data", &mipmap))
51+
{
4752
return NULL;
4853
}
4954

@@ -61,13 +66,15 @@ PyObject *py_ue_texture_get_data(ue_PyUObject *self, PyObject * args) {
6166
}
6267

6368
#if WITH_EDITOR
64-
PyObject *py_ue_texture_get_source_data(ue_PyUObject *self, PyObject * args) {
69+
PyObject *py_ue_texture_get_source_data(ue_PyUObject *self, PyObject * args)
70+
{
6571

6672
ue_py_check(self);
6773

6874
int mipmap = 0;
6975

70-
if (!PyArg_ParseTuple(args, "|i:texture_get_data", &mipmap)) {
76+
if (!PyArg_ParseTuple(args, "|i:texture_get_data", &mipmap))
77+
{
7178
return NULL;
7279
}
7380

@@ -87,13 +94,15 @@ PyObject *py_ue_texture_get_source_data(ue_PyUObject *self, PyObject * args) {
8794
}
8895
#endif
8996

90-
PyObject *py_ue_render_target_get_data(ue_PyUObject *self, PyObject * args) {
97+
PyObject *py_ue_render_target_get_data(ue_PyUObject *self, PyObject * args)
98+
{
9199

92100
ue_py_check(self);
93101

94102
int mipmap = 0;
95103

96-
if (!PyArg_ParseTuple(args, "|i:render_target_get_data", &mipmap)) {
104+
if (!PyArg_ParseTuple(args, "|i:render_target_get_data", &mipmap))
105+
{
97106
return NULL;
98107
}
99108

@@ -102,26 +111,68 @@ PyObject *py_ue_render_target_get_data(ue_PyUObject *self, PyObject * args) {
102111
return PyErr_Format(PyExc_Exception, "object is not a TextureRenderTarget");
103112

104113
FTextureRenderTarget2DResource *resource = (FTextureRenderTarget2DResource *)tex->Resource;
105-
if (!resource) {
114+
if (!resource)
115+
{
106116
return PyErr_Format(PyExc_Exception, "cannot get render target resource");
107117
}
108118

109119
TArray<FColor> pixels;
110-
if (!resource->ReadPixels(pixels)) {
120+
if (!resource->ReadPixels(pixels))
121+
{
111122
return PyErr_Format(PyExc_Exception, "unable to read pixels");
112123
}
113124

114125
return PyByteArray_FromStringAndSize((const char *)pixels.GetData(), (Py_ssize_t)(tex->GetSurfaceWidth() * 4 * tex->GetSurfaceHeight()));
115126
}
116127

117-
PyObject *py_ue_texture_set_data(ue_PyUObject *self, PyObject * args) {
128+
PyObject *py_ue_render_target_get_data_to_buffer(ue_PyUObject *self, PyObject * args)
129+
{
130+
131+
ue_py_check(self);
132+
Py_buffer py_buf;
133+
int mipmap = 0;
134+
135+
if (!PyArg_ParseTuple(args, "z*|i:render_target_get_data_to_buffer", &py_buf, &mipmap))
136+
{
137+
return NULL;
138+
}
139+
140+
UTextureRenderTarget2D *tex = ue_py_check_type<UTextureRenderTarget2D>(self);
141+
if (!tex)
142+
return PyErr_Format(PyExc_Exception, "object is not a TextureRenderTarget");
143+
144+
FTextureRenderTarget2DResource *resource = (FTextureRenderTarget2DResource *)tex->Resource;
145+
if (!resource)
146+
{
147+
return PyErr_Format(PyExc_Exception, "cannot get render target resource");
148+
}
149+
150+
Py_ssize_t data_len = (Py_ssize_t)(tex->GetSurfaceWidth() * 4 * tex->GetSurfaceHeight());
151+
if (py_buf.len < data_len)
152+
{
153+
return PyErr_Format(PyExc_Exception, "buffer is not big enough");
154+
}
155+
156+
TArray<FColor> pixels;
157+
if (!resource->ReadPixels(pixels))
158+
{
159+
return PyErr_Format(PyExc_Exception, "unable to read pixels");
160+
}
161+
162+
FMemory::Memcpy(py_buf.buf, pixels.GetData(), data_len);
163+
Py_RETURN_NONE;
164+
}
165+
166+
PyObject *py_ue_texture_set_data(ue_PyUObject *self, PyObject * args)
167+
{
118168

119169
ue_py_check(self);
120170

121171
Py_buffer py_buf;
122172
int mipmap = 0;
123173

124-
if (!PyArg_ParseTuple(args, "z*|i:texture_set_data", &py_buf, &mipmap)) {
174+
if (!PyArg_ParseTuple(args, "z*|i:texture_set_data", &py_buf, &mipmap))
175+
{
125176
return NULL;
126177
}
127178

@@ -140,7 +191,8 @@ PyObject *py_ue_texture_set_data(ue_PyUObject *self, PyObject * args) {
140191
int32 len = tex->PlatformData->Mips[mipmap].BulkData.GetBulkDataSize();
141192
int32 wanted_len = py_buf.len;
142193
// avoid making mess
143-
if (wanted_len > len) {
194+
if (wanted_len > len)
195+
{
144196
UE_LOG(LogPython, Warning, TEXT("truncating buffer to %d bytes"), len);
145197
wanted_len = len;
146198
}
@@ -158,22 +210,26 @@ PyObject *py_ue_texture_set_data(ue_PyUObject *self, PyObject * args) {
158210
return Py_None;
159211
}
160212

161-
PyObject *py_unreal_engine_compress_image_array(PyObject * self, PyObject * args) {
213+
PyObject *py_unreal_engine_compress_image_array(PyObject * self, PyObject * args)
214+
{
162215
int width;
163216
int height;
164217
Py_buffer py_buf;
165-
if (!PyArg_ParseTuple(args, "iiz*:compress_image_array", &width, &height, &py_buf)) {
218+
if (!PyArg_ParseTuple(args, "iiz*:compress_image_array", &width, &height, &py_buf))
219+
{
166220
return NULL;
167221
}
168222

169-
if (py_buf.buf == nullptr || py_buf.len <= 0) {
223+
if (py_buf.buf == nullptr || py_buf.len <= 0)
224+
{
170225
PyBuffer_Release(&py_buf);
171226
return PyErr_Format(PyExc_Exception, "invalid image data");
172227
}
173228

174229
TArray<FColor> colors;
175230
uint8 *buf = (uint8 *)py_buf.buf;
176-
for (int32 i = 0; i < py_buf.len; i += 4) {
231+
for (int32 i = 0; i < py_buf.len; i += 4)
232+
{
177233
colors.Add(FColor(buf[i], buf[1 + 1], buf[i + 2], buf[i + 3]));
178234
}
179235

@@ -184,11 +240,13 @@ PyObject *py_unreal_engine_compress_image_array(PyObject * self, PyObject * args
184240
return PyBytes_FromStringAndSize((char *)output.GetData(), output.Num());
185241
}
186242

187-
PyObject *py_unreal_engine_create_checkerboard_texture(PyObject * self, PyObject * args) {
243+
PyObject *py_unreal_engine_create_checkerboard_texture(PyObject * self, PyObject * args)
244+
{
188245
PyObject *py_color_one;
189246
PyObject *py_color_two;
190247
int checker_size;
191-
if (!PyArg_ParseTuple(args, "OOi:create_checkboard_texture", &py_color_one, &py_color_two, &checker_size)) {
248+
if (!PyArg_ParseTuple(args, "OOi:create_checkboard_texture", &py_color_one, &py_color_two, &checker_size))
249+
{
192250
return NULL;
193251
}
194252

@@ -209,11 +267,13 @@ PyObject *py_unreal_engine_create_checkerboard_texture(PyObject * self, PyObject
209267
return (PyObject *)ret;
210268
}
211269

212-
PyObject *py_unreal_engine_create_transient_texture(PyObject * self, PyObject * args) {
270+
PyObject *py_unreal_engine_create_transient_texture(PyObject * self, PyObject * args)
271+
{
213272
int width;
214273
int height;
215274
int format = PF_B8G8R8A8;
216-
if (!PyArg_ParseTuple(args, "ii|i:create_transient_texture", &width, &height, &format)) {
275+
if (!PyArg_ParseTuple(args, "ii|i:create_transient_texture", &width, &height, &format))
276+
{
217277
return NULL;
218278
}
219279

@@ -231,12 +291,14 @@ PyObject *py_unreal_engine_create_transient_texture(PyObject * self, PyObject *
231291
return (PyObject *)ret;
232292
}
233293

234-
PyObject *py_unreal_engine_create_transient_texture_render_target2d(PyObject * self, PyObject * args) {
294+
PyObject *py_unreal_engine_create_transient_texture_render_target2d(PyObject * self, PyObject * args)
295+
{
235296
int width;
236297
int height;
237298
int format = PF_B8G8R8A8;
238299
PyObject *py_linear = nullptr;
239-
if (!PyArg_ParseTuple(args, "ii|iO:create_transient_texture_render_target2d", &width, &height, &format, &py_linear)) {
300+
if (!PyArg_ParseTuple(args, "ii|iO:create_transient_texture_render_target2d", &width, &height, &format, &py_linear))
301+
{
240302
return NULL;
241303
}
242304

@@ -254,24 +316,29 @@ PyObject *py_unreal_engine_create_transient_texture_render_target2d(PyObject * s
254316
}
255317

256318
#if WITH_EDITOR
257-
PyObject *py_unreal_engine_create_texture(PyObject * self, PyObject * args) {
319+
PyObject *py_unreal_engine_create_texture(PyObject * self, PyObject * args)
320+
{
258321
PyObject *py_package;
259322
char *name;
260323
int width;
261324
int height;
262325
Py_buffer py_buf;
263326

264-
if (!PyArg_ParseTuple(args, "Osiiz*:create_texture", &py_package, &name, &width, &height, &py_buf)) {
327+
if (!PyArg_ParseTuple(args, "Osiiz*:create_texture", &py_package, &name, &width, &height, &py_buf))
328+
{
265329
return nullptr;
266330
}
267331

268332
UPackage *u_package = nullptr;
269-
if (py_package == Py_None) {
333+
if (py_package == Py_None)
334+
{
270335
u_package = GetTransientPackage();
271336
}
272-
else {
337+
else
338+
{
273339
u_package = ue_py_check_type<UPackage>(py_package);
274-
if (!u_package) {
340+
if (!u_package)
341+
{
275342
return PyErr_Format(PyExc_Exception, "argument is not a UPackage");
276343
}
277344
}
@@ -286,7 +353,7 @@ PyObject *py_unreal_engine_create_texture(PyObject * self, PyObject * args) {
286353
wanted_len = py_buf.len;
287354

288355
FMemory::Memcpy(colors.GetData(), py_buf.buf, wanted_len);
289-
356+
290357
UTexture2D *texture = FImageUtils::CreateTexture2D(width, height, colors, u_package, UTF8_TO_TCHAR(name), RF_Public | RF_Standalone, params);
291358
if (!texture)
292359
return PyErr_Format(PyExc_Exception, "unable to create texture");

Source/UnrealEnginePython/Private/UObject/UEPyTexture.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
PyObject *py_ue_texture_get_data(ue_PyUObject *, PyObject *);
88
PyObject *py_ue_render_target_get_data(ue_PyUObject *, PyObject *);
9+
PyObject *py_ue_render_target_get_data_to_buffer(ue_PyUObject *, PyObject *);
910

1011
PyObject *py_ue_texture_set_data(ue_PyUObject *, PyObject *);
1112
PyObject *py_ue_texture_get_width(ue_PyUObject *, PyObject *);

0 commit comments

Comments
 (0)