background in 3D [SOLVED]

General discussion about LÖVE, Lua, game development, puns, and unicorns.
RNavega
Party member
Posts: 355
Joined: Sun Aug 16, 2020 1:28 pm

Re: background in 3D

Post 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 1238 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.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest