


function CheckOpenGLErrCode(s)
  local gl_err_code = gh_renderer.get_opengl_error()
  local  gl_err_code_str = gh_renderer.opengl_error_code_to_str(gl_err_code)
  print("******** CheckOpenGLErrCode() - " .. s .. " - code: " .. gl_err_code .. " - " .. gl_err_code_str)
end



--CheckOpenGLErrCode("01")



local demo_dir = gh_utils.get_demo_dir()
local lib_dir = gh_utils.get_lib_dir() 		
dofile(lib_dir .. "lua/gx_cam_lib_v1.lua")
dofile(lib_dir .. "lua/imgui.lua")    
dofile(lib_dir .. "lua/gxl.lua")  

dofile(lib_dir .. "lua/libfont/libfont2.lua")   
--dofile(lib_dir .. "lua/shaderlib.lua")    



winW, winH = gh_window.getsize(0)







camera_ortho = gxl.create_camera_2d(winW, winH, 1.0, 10.0)
-- camera_ortho = gh_camera.create_ortho(-winW/2, winW/2, -winH/2, winH/2, 1.0, 10.0)
-- gh_camera.set_viewport(camera_ortho, 0, 0, winW, winH)
-- gh_camera.set_position(camera_ortho, 0, 0, 4)





font_coolvetica_24 = libfont2_new_font(demo_dir .. "fonts/coolvetica rg.ttf", 24, 512)
font_coolvetica_50 = libfont2_new_font(demo_dir .. "fonts/coolvetica rg.ttf", 50, 1024)
font_hack_reg_20 = libfont2_new_font(demo_dir .. "fonts/Hack-Regular.ttf", 20, 1024)





local PF_U8_RGB = 1
local PF_U8_RGBA = 3
local PF_F32_RGBA = 6
local pixel_format = PF_U8_RGBA
local gen_mipmaps = 0
local compressed_texture = ""

local filename = demo_dir .. "images/geexlab.png"
tex_geexlab = gh_texture.create_from_file_v6(filename, pixel_format, gen_mipmaps, compressed_texture)




texture_prog = gh_node.getid("texture_prog")
gh_gpu_program.uniform4f(texture_prog, "color", 1, 1, 1, 1)
gh_gpu_program.uniform2f(texture_prog, "uv_tiling", 1, 1)
gh_gpu_program.uniform1i(texture_prog, "tex0", 0)




local iw = 602 * 0.5
local ih = 120 * 0.5
quad = gh_mesh.create_quad(iw, ih)






vertex_color_prog = gh_node.getid("vertex_color_prog")
gh_gpu_program.uniform4f(vertex_color_prog, "color", 1, 1, 1, 1)






quad_band_width = 12

quad2 = gh_mesh.create_quad(winW, quad_band_width)
gh_mesh.set_vertex_color(quad2, 0, 0.5, 0.2, 0.0, 1) --bottom-left
gh_mesh.set_vertex_color(quad2, 1, 0.5, 0.2, 0.0, 1) -- top-left
gh_mesh.set_vertex_color(quad2, 2, 0.5, 0.2, 0.0, 1) --top-right
gh_mesh.set_vertex_color(quad2, 3, 0.5, 0.2, 0.0, 1) --bottom-right

quad3 = gh_mesh.create_quad(quad_band_width, winH)
gh_mesh.set_vertex_color(quad3, 0, 0.5, 0.2, 0.0, 1) --bottom-left
gh_mesh.set_vertex_color(quad3, 1, 0.5, 0.2, 0.0, 1) -- top-left
gh_mesh.set_vertex_color(quad3, 2, 0.5, 0.2, 0.0, 1) --top-right
gh_mesh.set_vertex_color(quad3, 3, 0.5, 0.2, 0.0, 1) --bottom-right




quad4_h = 30
quad4 = gh_mesh.create_quad(10, quad4_h)






color_prog = gh_node.getid("color_prog")
gh_gpu_program.uniform4f(color_prog, "color", 1, 1, 1, 1)









fx1_prog = gh_node.getid("fx1_prog")

fxquad = gh_mesh.create_quad(winW, winH)
gh_mesh.set_vertex_color(fxquad, 0, 0.2, 0.2, 0.25, 1) --bottom-left
gh_mesh.set_vertex_color(fxquad, 1, 0.10, 0.10, 0.10, 1) -- top-left
gh_mesh.set_vertex_color(fxquad, 2, 0.250, 0.60, 0.70, 1) --top-right
gh_mesh.set_vertex_color(fxquad, 3, 0.250, 0.60, 0.70, 1) --bottom-right





--bgcolor = {r=0.107, g=0.117, b=0.130, a=1}
bgcolor = {r=0.0, g=0.0, b=0.0, a=1}




vsync = 0
gh_renderer.vsync(vsync)

gh_renderer.set_scissor_state(0)
gh_renderer.set_depth_test_state(1)


last_time = gh_utils.get_elapsed_time()

gl_renderer = gh_renderer.get_renderer_model()
gl_version = gh_renderer.get_api_version()


fps_time = 0
fps = 0
frames = 0



app_version = {major=0, minor=0, patch=0, build=0}
app_version.major, app_version.minor, app_version.patch, app_version.build = gh_utils.get_app_version()
geexlab_version = string.format("%d.%d.%d.%d", app_version.major, app_version.minor, app_version.patch, app_version.build)
geexlab_build_date = gh_utils.get_app_build_date()


geexlab_new_version = ""
geexlab_download_url = ""
geexlab_new_version_available = gh_app.get_data_int("geexlab_new_version_available");
if (geexlab_new_version_available == 1) then
  geexlab_new_version = gh_app.get_data_str128("geexlab_new_version_str");
  geexlab_download_url = gh_app.get_data_str128("geexlab_download_url");
end




lua_version = {0, 0, 0}
lua_version[1], lua_version[2], lua_version[3] = gh_utils.get_lua_version()
lua_version_str = string.format("%d.%d.%d", lua_version[1], lua_version[2], lua_version[3])
















---[[
-- Dear ImGui init ------------------
--  

--imgui_init("dark")
imgui_init_v2("") -- no .ini file.

imgui_version = gh_imgui.get_version()

font_RobotoRegular_16 = gh_imgui.add_font_from_file(demo_dir .. "fonts/Roboto-Regular.ttf", 16)
font_BebasNeue_Regular_26 = gh_imgui.add_font_from_file(demo_dir .. "fonts/BebasNeue-Regular.ttf", 26)
font_Hack_Regular_14 = gh_imgui.add_font_from_file(demo_dir .. "fonts/Hack-Regular.ttf", 14)

gh_imgui.rebuild_all_fonts()
--]]














---[[
-- Windows information ------------------
--  
windows_info = {
  ReleaseId = 0,
  ProductName = "",
  CurrentBuildNumber = 0
}

function ReadWindowsInfo()
  local ret = 0
  local str = ""

  ret, str = gh_utils.win_registry_read_value_string("HKEY_LOCAL_MACHINE", "Software\\Microsoft\\Windows NT\\CurrentVersion", "ReleaseId")
  if (ret == 1) then 
    windows_info.ReleaseId = tonumber(str)
  end

  ret, windows_info.ProductName = gh_utils.win_registry_read_value_string("HKEY_LOCAL_MACHINE", "Software\\Microsoft\\Windows NT\\CurrentVersion", "ProductName")

  ret, str = gh_utils.win_registry_read_value_string("HKEY_LOCAL_MACHINE", "Software\\Microsoft\\Windows NT\\CurrentVersion", "CurrentBuildNumber")
  if (ret == 1) then 
    windows_info.CurrentBuildNumber = tonumber(str) 
  end
end  


software_platform = ""

if (gh_utils.get_platform() == 1) then -- Windows
  ReadWindowsInfo()
  software_platform = string.format("%s ver.%d (build %d)", windows_info.ProductName, windows_info.ReleaseId, windows_info.CurrentBuildNumber)

else
  local f = io.popen('uname -snrm', 'r')
  software_platform = f:read('*l')
  f:close()

end
--]]













---[[
-- OpenGL information ----------------------------
--

gl = {
  renderer = "",
  vendor = "",
  version = "",
  is_nvidia_gpu = 0,
  is_amd_gpu = 0,
  can_read_vram_info = false,
  max_texture_size=0,
  num_glext = 0,
  extensions = {},
  num_extensions = 0,
}


function gl_read_gpu_memory_load()
  local gpu_mem_usage = 0

  if (gl.is_nvidia_gpu == 1) then
    gpu_mem_usage = gh_renderer.get_gpu_memory_usage_kb_nv() / 1024
  end

  if (gl.is_amd_gpu == 1) then
    gpu_mem_usage = gh_renderer.get_gpu_memory_usage_kb_amd() / 1024
  end

  return gpu_mem_usage
end  


function gl_read_gpu_memory_size()
 
  local gpu_mem_total = 0

  if (gl.is_nvidia_gpu == 1) then
    gpu_mem_total = gh_renderer.get_gpu_memory_total_available_kb_nv() / 1024
  end

  if (gl.is_amd_gpu == 1) then
    gpu_mem_total = gh_renderer.get_gpu_memory_total_available_kb_amd() / 1024
  end

  return gpu_mem_total
end




function gl_init()

  gl.renderer = gh_renderer.get_renderer_model()
  gl.vendor = gh_renderer.get_renderer_vendor()
  gl.version = gh_renderer.get_api_version()


  local glvendor = string.lower(gl.vendor)
  local glrenderer = string.lower(gl.renderer)

  local pstart, pend = string.find(glvendor, "nvidia")
  if (pstart ~= nil) then
    gl.is_nvidia_gpu = 1
  end   
  
  if (gl.is_nvidia_gpu == 0) then
    pstart, pend = string.find(glrenderer, "geforce")
    if (pstart ~= nil) then
      gl.is_nvidia_gpu = 1
    end    
  end
  
  if (gl.is_nvidia_gpu == 0) then
    pstart, pend = string.find(glrenderer, "quadro")
    if (pstart ~= nil) then
      gl.is_nvidia_gpu = 1
    end    
  end


  if (gl.is_nvidia_gpu == 0) then

    pstart, pend = string.find(glvendor, "amd")
    if (pstart ~= nil) then
      gl.is_amd_gpu = 1
    end    

    if (gl.is_amd_gpu == 0) then
      pstart, pend = string.find(glvendor, "ati")
      if (pstart ~= nil) then
        gl.is_amd_gpu = 1
      end    
    end
    
    if (gl.is_amd_gpu == 0) then
      pstart, pend = string.find(glrenderer, "radeon")
      if (pstart ~= nil) then
        gl.is_amd_gpu = 1
      end    
    end
  end

	
	
	
	local gl_gpu_memory_size = gl_read_gpu_memory_size()
	
	if (gl_gpu_memory_size > 0) then
    gl.can_read_vram_info = true
  end



  gl.num_extensions = gh_renderer.get_num_opengl_extensions()
  for i=1, gl.num_extensions do
    local ename = gh_renderer.get_opengl_extension(i-1)
    gl.extensions[i] = ename
  end

end	

gl_init()
--]]

















---[[
-- Vulkan API information ------------------------
--
vk_gpus = {}
num_vk_gpus = 0
vk_info_initialized = false

function CreateVkGPU()
  local vk_gpu = {
    name="", 
    vendor_id=0, 
    device_id=0, 
    api_ver_major=0, 
    api_ver_minor=0, 
    api_ver_patch=0,
    show_extensions_window = 0,
    num_extensions = 0,
    extensions = {}
  }
  return vk_gpu
end  



function InitVkInfo()
  if (vk_info_initialized) then
    return
  end
  vk_info_initialized = true
  --if (gh_utils.is_sbc() == 0) then
    num_vk_gpus = gh_renderer.vk_get_num_gpus()
    for i=0, num_vk_gpus-1 do
      local vkgpu = CreateVkGPU()
      vkgpu.name = gh_renderer.vk_gpu_get_name(i)
      vkgpu.vendor_id, vkgpu.device_id = gh_renderer.vk_gpu_get_device_id(i)
      vkgpu.api_ver_major, vkgpu.api_ver_minor, vkgpu.api_ver_patch = gh_renderer.vk_gpu_get_api_version(i)

      vkgpu.num_extensions = gh_renderer.vk_gpu_get_num_extensions(i)
      for j=0, vkgpu.num_extensions-1 do
        local ename = gh_renderer.vk_gpu_get_extension_name(i, j)
        vkgpu.extensions[j+1] = ename
      end

      vk_gpus[i+1] = vkgpu
    end
  --end
end

InitVkInfo()
--]]






--[[
Hummm... the call to bind_render_window() deserves an explanation.

Without this call, the demo crashes if there are two NVIDIA graphics cards in the system. 
On my dev station, I have a GeForce RTX 2070 + GeForce GT 1030 + driver R561.09. If I remove the GT 1030,
the demo works fine. With both cards, the demo crashes. This is an OpenGL demo that in middle
of the init script, initializes Vulkan and reads Vulkan information (InitVkInfo). 
Any OpenGL call after InitVkInfo() leads to a crash (OpenGL function pointers seemed correct but crashed when we called them).
After few hours of debugging, I had the feeling that the crash happened as if the OpenGL context was lost or not
properly restored after Vulkan calls. That's why I tested with bind_render_window()
and... YES, that fixed the crash! bind_render_window() is a wrapper around wglMakeCurrent.

But it's not a victory. Because the crash is still there in 32-bit. With bind_render_window() the crash
disappears in 64-bit but not in 32-bit. 

Another detail: this demo runs the rendering in a separate thread. If the rendering is done in the same thread than 
the main application, there is no crash (in 64-bit, the app crashes in 32-bit)... To test it with GeeXLab 64-bit, 
you can add separate_render_thread="1" or separate_render_thread="0" in the window XML node in main.xml.

The other thing is that with 2 graphics cards, the NVIDIA Vulkan driver duplicates all Vulkan physical devices. Instead of detecting
two physical devices, the NV VK driver returns:
GPU 0: NVIDIA GeForce RTX 2070
GPU 1: NVIDIA GeForce RTX 2070
GPU 2: NVIDIA GeForce GT 1030
GPU 3: NVIDIA GeForce GT 1030

There is probably a bug in the NV VK driver. I tried to uninstall it (used DDU for that), reinstalled it, but no change,
any Vulkan utility (GPU Shark 2, GPU Caps Viewer, Vulkan Capability Viewer, vkinfo) still displayed 4 devices...

Modern graphics programming is blood, sweat and pain!
--]]
local make_current = 1
gh_renderer.bind_render_window(make_current)










alpha = 0.0




show_gl_extensions_window = 0
show_vk_extensions_window = 0

show_gl_vk_info = 0
show_links_window = 0
show_info_versions_window = 0

show_mouse_fx = 0




-- Color of the logo depending on the GPU maker.
--
logo_color = {0.2, 0.8, 1.0, 1.0}


---[[
glvendor = string.lower(gl.vendor)

--glvendor = "nvidia"
--glvendor = "amd"
--glvendor = "intel"
--glvendor = "noname"


if string.find(glvendor, "nvidia") then
  logo_color = {118/255, 185/255, 0.0, 1.0}

elseif string.find(glvendor, "amd") then
  logo_color = {216/255, 30/255, 51/255, 1.0}
elseif string.find(glvendor, "ati") then
  logo_color = {216/255, 30/255, 51/255, 1.0}

elseif string.find(glvendor, "intel") then
  logo_color = {51/255, 106/255, 195/255, 1.0}

else
  logo_color = {1.0, 1.0, 1.0, 1.0}

end
--]]

--print("******** DEMO init.lua OK")
