Page 2 of 2

Re: background in 3D

Posted: Sun Feb 19, 2023 11:16 pm
by RNavega
Here's a test with G3D using draw command ordering.
If you load the default demo ("main.lua" file as it comes with G3D), you can add this love.load function to get a bigger font:

Code: Select all

function love:load()
    love.graphics.setFont(love.graphics.newFont(26))
end
And then replace the entire love.draw function with this:

Code: Select all

function love.draw()
    -- 3D.
    love.graphics.setDepthMode('lequal', true)  
    background:draw()
    
    -- Drawing 2D content after 3D.
    -- First disable depth testing AND depth writes, draw what you want.
    love.graphics.setDepthMode()
    love.graphics.setColor(0.7, 0.5, 0.8)
    love.graphics.print('Behind the Earth', 430, 250)
    
    -- Drawing 3D content after 2D.
    -- Turn back on the depth testing AND depth writing.
    love.graphics.setDepthMode('lequal', true)
    love.graphics.setColor(1.0, 1.0, 1.0)
    earth:draw()

    -- 2D.
    love.graphics.setDepthMode()
    love.graphics.setColor(0.6, 1.0, 0.6)
    love.graphics.print('Behind the Moon', 240, 210)

    -- 3D.
    love.graphics.setDepthMode('lequal', true)
    love.graphics.setColor(1.0, 1.0, 1.0)
    moon:draw()

    -- 2D.
    love.graphics.setDepthMode()
    love.graphics.setColor(1.0, 1.0, 1.0)
    love.graphics.print('In front of all', 270, 280) 
end
It produces this (those occluded texts are "Behind the Moon" and "Behind the Earth"):
g3d_2D_3D_layering.jpg
g3d_2D_3D_layering.jpg (31.43 KiB) Viewed 1239 times
PS the default depth testing mode for Löve is GL_ALWAYS as seen here:
https://github.com/love2d/love/blob/c82 ... ics.h#L955
Then when you require G3D, it changes that to GL_LEQUAL as seen here:
https://github.com/groverburger/g3d/blo ... it.lua#L59

PS2 while you can access raw OpenGL function calls, like glClear, glDepthMask etc. like this...

Code: Select all

local ffi = require('ffi')
local SDL = ffi.load('SDL2')

-- References:
-- https://github.com/nanoant/glua/blob/master/gl/gl3.lua
-- https://github.com/luapower/opengl/blob/master/gl11.lua
ffi.cdef [[
typedef unsigned int GLbitfield;
typedef float GLfloat;

typedef void (*glClearColor_ptr)(GLfloat red,
                                 GLfloat green,
                                 GLfloat blue,
                                 GLfloat alpha);
typedef void (*glClear_ptr)(GLbitfield mask);

void* SDL_GL_GetProcAddress(const char *proc);
]]
local GL_DEPTH_BUFFER_BIT   = 0x00000100
local GL_STENCIL_BUFFER_BIT = 0x00000400
local GL_COLOR_BUFFER_BIT   = 0x00004000

local glClearColor = ffi.cast('glClearColor_ptr', SDL.SDL_GL_GetProcAddress('glClearColor'))
local glClear = ffi.cast('glClear_ptr', SDL.SDL_GL_GetProcAddress('glClear'))

glClearColor(1.0, 0.0, 0.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT)
...they can't be used properly, because Löve queues its drawing commands instead of executing them immediately (I think it's an optimization to reduce state changes). If you call a raw GL function inside love.draw, it will be executed immediately and not be in the order that you expect in relation to the Löve drawing commands.