Hello everyone,
I started from this example https://github.com/abadonna/defold-skyquad to display a skybox.
Now, I would like to change it at runtime. I have my 6 square textures for each side of my cube. I know how to load them individually but I don’t know how to transform them into a cubemap texture. It remains a rather particular format. Should I send an array of 6 images using a buffer? In which order?
Finally, do you think it’s possible actually to dynamically change or create a “cubemap” texture at runtime?
Thanks for your help.
First you need a cubemap resource, which you can create either via the editor or using resource.create_texture (API reference (resource)) in runtime. Then you upload all of the sides of your cubemap to the texture resource via the resource.set_texture function (API reference (resource)). If you create the texture via runtime, you need to assign this to your components via go.set. I think I have some examples how to upload cubemap data, let me see if I can find any.
Here is a small code snippet on how to create a buffer with cubemap data and upload it to a texture resource that already exists.
-- this is a script property, but you can reference
-- a resource from the project by the path to the built resource
-- something like "/main/my-cubemap.texturec"
go.property("cubemap", resource.texture())
local function test_cubemap(self)
self.x = 16
self.y = 16
self.height = 128 - self.x * 2
self.width = 128 - self.y * 2
self.buffer = buffer.create(self.width * self.height * 6, { {name=hash("rgb"), type=buffer.VALUE_TYPE_UINT8, count=3} } )
self.stream = buffer.get_stream(self.buffer, hash("rgb"))
local psize = self.height * self.width * 3
for z=1,6 do
for y=1,self.height do
for x=1,self.width do
local index = (y-1) * self.width * 3 + (x-1) * 3 + 1
index = index + psize * (z-1)
self.stream[index + 0] = 0xff
self.stream[index + 1] = 0x00
self.stream[index + 2] = 0x00
end
end
end
local header = {
width = self.width,
height = self.height,
type = resource.TEXTURE_TYPE_CUBE_MAP,
format = resource.TEXTURE_FORMAT_RGB,
x = self.x,
y = self.y,
mipmap = 1,
}
resource.set_texture(self.cubemap, header, self.buffer)
end
Let us know about the results! This is interesting use of some newest Defold features
Ok, now I have a little problem:
When I run this minimal code
local cubemap_header = {
width = 1024,
height = 1024,
type = resource.TEXTURE_TYPE_CUBE_MAP,
format = resource.TEXTURE_FORMAT_RGB,
max_mipmaps = 0,
}
local cubemap_texture = resource.create_texture("/mycubemap.texturec", cubemap_header)
local cubemap_buffer = buffer.create(1024 * 1024 * 6, { {name=hash("rgb"), type=buffer.VALUE_TYPE_UINT8, count=3} } )
resource.set_texture(cubemap_texture, cubemap_header, cubemap_buffer)
go.set("/sky#model", "texture0", cubemap_texture)
I get this crashdump:
ERROR:CRASH: CALL STACK:
# 0 pc 0x2af824 dmengine _ZN7dmCrashL7HandlerEiP9__siginfoPv+36
# 1 pc 0x2e2dfd libxpc.dylib _sigtramp+29
# 2 pc 0x20d440acc libxslt.1.dylib _Z15glgConvertTo_32I23GLGConverter_BGR8_ARGB8L9GLGMemory0EEvPK15GLGOperationRecPK15GLDPixelModeRec+599
# 3 pc 0x20d4342c6 libxslt.1.dylib glgProcessPixelsWithProcessor+3639
# 4 pc 0xe0be82b dmengine _ZN13GLDTextureRec18uploadTextureLevelEjjjjjjjjjjjjjP12GLDBufferRecPhiiiU13block_pointerFPU30objcproto19MTLCommandBufferSPI11objc_objectvEU13block_pointerFvS4_jEU13block_pointerFvU13block_pointerFvvEESC_PK15GLDPixelModeRecbb+2
# 5 pc 0xe0f7490 dmengine gldModifyTexSubImage+1896
# 6 pc 0x20d653dce libxslt.1.dylib glTexImage2D_Exec+1926
# 7 pc 0x20d631190 libxslt.1.dylib glTexImage2D+55
# 8 pc 0xc9784 dmengine _ZN10dmGraphicsL16OpenGLSetTextureEPNS_7TextureERKNS_13TextureParamsE+3284
# 9 pc 0xcae55 dmengine _ZN10dmGraphicsL23OpenGLDoSetTextureAsyncEPv+213
#10 pc 0xcb206 dmengine _ZN10dmGraphicsL11AsyncThreadEPv+182
#11 pc 0x25b8e5 dmengine _ZN8dmThreadL16ThreadStartProxyEPv+37
#12 pc 0x2cd4e1 libxpc.dylib _pthread_start+125
Am I missing something do you think?
A few comments:
-
If I comment out this line, there is no longer a crash:
resource.set_texture(cubemap_texture, cubemap_header, cubemap_buffer)
-
This snippet code is reduced to its strictest simplification in order to rule out any side effects. So I removed the part that initialized the buffer with a test color first before thinking about using a C function that copies the buffer from a loaded texture to the cubemap buffer (taking care of the 6 faces of the cubemap)
Can you try with a rgba format and 4 components in the buffer?
yeahhhh, you’re right !
if I replace this line:
local cubemap_buffer = buffer.create(1024 * 1024 * 6, { {name=hash("rgb"), type=buffer.VALUE_TYPE_UINT8, count=3} } )
by this one:
local cubemap_buffer = buffer.create(1024 * 1024 * 6, { {name=hash("rgba"), type=buffer.VALUE_TYPE_UINT8, count=4} } )
I no longer have a crash. So, I will be able to work on my C function to quickly copy the buffer of the loaded face to the buffer of the cubemap…
Stay tuned !
Great! Though I don’t know why RGB wouldn’t work… I’m guessing it’s a driver issue
To summarize at this point, my minimal and working code is finally:
local cubemap_header = {
width = 1024,
height = 1024,
type = resource.TEXTURE_TYPE_CUBE_MAP,
format = resource.TEXTURE_FORMAT_RGBA, -- notice the mention '###_RGBA'
max_mipmaps = 1,
}
local cubemap_texture = resource.create_texture("/mycubemap.texturec", cubemap_header)
local cubemap_buffer = buffer.create(1024 * 1024 * 6, { {name=hash("rgba"), type=buffer.VALUE_TYPE_UINT8, count=4} } ) -- notice the mentions 'rgba' and '4'
resource.set_texture(cubemap_texture, cubemap_header, cubemap_buffer)
go.set("/sky#model", "texture0", cubemap_texture)
Yeah, I was going to say: “What about max mipmaps”?
At least 1 mipmap is required, otherwise it’s just a header. In the initial example a mipmap count of 0 was used, and could potentially cause issues.
We guard for that in the engine, since that value is optional, so I don’t think it’s that. If I understand the callstack, the error seems to come from an expansion in the driver from RGB → RGBA in the _Z15glgConvertTo_32I23GLGConverter_BGR8_ARGB8L9GLGMemory0EEvPK15GLGOperationRecPK15GLDPixelModeRec
(whatever that means, can’t find any info about that function yet)
Hello! I have some success in Lua game logic scripting.
But I absolutly don’t understand texturing and GLSL.
I need something minimal: simple skybox without any additional features.
Is it possible to add these built-ins in nearest update:
“cubemap.fp”, “cubemap.vp” and “cubemap.material” (like as “model.fp”, “model.vp”, “model.material” in “builtins” folder)?
I don’t need to make any complex sky feature, only ordinary sky.
The code from the first link works in the editor, but cannot be compiled.
/user/sky/test/quad.vp
_generated_317d177a.vpc:\Users\asser\AppData\Local\Temp_generated_317d177a.vpc13795762937234452548.glsl
ERROR: C:\Users\asser\AppData\Local\Temp_generated_317d177a.vpc13795762937234452548.glsl:11: ‘highp’ : overloaded functions must have the same parameter precision qualifiers for argument 1
ERROR: C:\Users\asser\AppData\Local\Temp_generated_317d177a.vpc13795762937234452548.glsl:12: ‘’ : missing #endif
ERROR: C:\Users\asser\AppData\Local\Temp_generated_317d177a.vpc13795762937234452548.glsl:12: ‘’ : compilation terminated
ERROR: 3 compilation errors. No code generated.
ERROR: Linking vertex stage: Missing entry point: Each stage requires one entry point
SPIR-V is not generated for failed compile or link