make gg work on Windows; prebuild glad and cJSON; new ft module
parent
06e7354d18
commit
f834644db4
|
@ -40,6 +40,7 @@ fn new_cgen(out_name_c string) *CGen {
|
||||||
gen := &CGen {
|
gen := &CGen {
|
||||||
out_path: path
|
out_path: path
|
||||||
out: out
|
out: out
|
||||||
|
lines: _make(0, 1000, sizeof(string))
|
||||||
}
|
}
|
||||||
return gen
|
return gen
|
||||||
}
|
}
|
||||||
|
@ -220,3 +221,24 @@ fn (g mut CGen) add_to_main(s string) {
|
||||||
g.fn_main = g.fn_main + s
|
g.fn_main = g.fn_main + s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn build_thirdparty_obj_file(flag string) {
|
||||||
|
obj_path := flag.all_after(' ')
|
||||||
|
if os.file_exists(obj_path) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
println('$obj_path not found, building it...')
|
||||||
|
parent := obj_path.all_before_last('/').trim_space()
|
||||||
|
files := os.ls(parent)
|
||||||
|
//files := os.ls(parent).filter(_.ends_with('.c')) TODO
|
||||||
|
mut cfiles := ''
|
||||||
|
for file in files {
|
||||||
|
if file.ends_with('.c') {
|
||||||
|
cfiles += parent + '/' + file + ' '
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cc := if os.user_os() == 'windows' { 'gcc' } else { 'cc' } // TODO clang support on Windows
|
||||||
|
res := os.exec('$cc -c -o $obj_path $cfiles')
|
||||||
|
println(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -244,11 +244,9 @@ fn (p mut Parser) fn_decl() {
|
||||||
typ = p.get_type()
|
typ = p.get_type()
|
||||||
}
|
}
|
||||||
// Translated C code can have empty functions (just definitions)
|
// Translated C code can have empty functions (just definitions)
|
||||||
is_fn_header := !is_c && !is_sig && (p.pref.translated || p.pref.is_test) &&
|
is_fn_header := !is_c && !is_sig && (p.pref.translated || p.pref.is_test) && p.tok != .lcbr
|
||||||
(p.tok != .lcbr)// || (p.tok == .name && p.peek() != .lcbr))
|
|
||||||
if is_fn_header {
|
if is_fn_header {
|
||||||
f.is_decl = true
|
f.is_decl = true
|
||||||
// println('.key_goT fn header $f.name')
|
|
||||||
}
|
}
|
||||||
// { required only in normal function declarations
|
// { required only in normal function declarations
|
||||||
if !is_c && !is_sig && !is_fn_header {
|
if !is_c && !is_sig && !is_fn_header {
|
||||||
|
|
|
@ -247,7 +247,7 @@ void init_consts();')
|
||||||
// Embed cjson either in embedvlib or in json.o
|
// Embed cjson either in embedvlib or in json.o
|
||||||
if imports_json && v.pref.build_mode == .embed_vlib ||
|
if imports_json && v.pref.build_mode == .embed_vlib ||
|
||||||
(v.pref.build_mode == .build && v.out_name.contains('json.o')) {
|
(v.pref.build_mode == .build && v.out_name.contains('json.o')) {
|
||||||
cgen.genln('#include "cJSON.c" ')
|
//cgen.genln('#include "cJSON.c" ')
|
||||||
}
|
}
|
||||||
// We need the cjson header for all the json decoding user will do in default mode
|
// We need the cjson header for all the json decoding user will do in default mode
|
||||||
if v.pref.build_mode == .default_mode {
|
if v.pref.build_mode == .default_mode {
|
||||||
|
@ -522,7 +522,7 @@ fn (v mut V) cc() {
|
||||||
}
|
}
|
||||||
linux_host := os.user_os() == 'linux'
|
linux_host := os.user_os() == 'linux'
|
||||||
v.log('cc() isprod=$v.pref.is_prod outname=$v.out_name')
|
v.log('cc() isprod=$v.pref.is_prod outname=$v.out_name')
|
||||||
mut a := ['-w', '-march=native']// arguments for the C compiler
|
mut a := ['-w'] // arguments for the C compiler
|
||||||
flags := v.table.flags.join(' ')
|
flags := v.table.flags.join(' ')
|
||||||
//mut shared := ''
|
//mut shared := ''
|
||||||
if v.pref.is_so {
|
if v.pref.is_so {
|
||||||
|
|
|
@ -356,7 +356,7 @@ fn (p mut Parser) const_decl() {
|
||||||
// cur_line has const's value right now. if it's just a number, then optimize generation:
|
// cur_line has const's value right now. if it's just a number, then optimize generation:
|
||||||
// output a #define so that we don't pollute the binary with unnecessary global vars
|
// output a #define so that we don't pollute the binary with unnecessary global vars
|
||||||
if is_compile_time_const(p.cgen.cur_line) {
|
if is_compile_time_const(p.cgen.cur_line) {
|
||||||
p.cgen.consts << '#define $name $p.cgen.cur_line'
|
p.cgen.consts << '#define $name $p.cgen.cur_line'
|
||||||
p.cgen.cur_line = ''
|
p.cgen.cur_line = ''
|
||||||
p.fgenln('')
|
p.fgenln('')
|
||||||
continue
|
continue
|
||||||
|
@ -464,7 +464,7 @@ fn (p mut Parser) struct_decl() {
|
||||||
if !is_c {
|
if !is_c {
|
||||||
kind := if is_union{'union'} else { 'struct'}
|
kind := if is_union{'union'} else { 'struct'}
|
||||||
p.gen_typedef('typedef $kind $name $name;')
|
p.gen_typedef('typedef $kind $name $name;')
|
||||||
p.gen_type('$kind /*kind*/ $name {')
|
p.gen_type('$kind $name {')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// V used to have 'type Foo struct', many Go users might use this syntax
|
// V used to have 'type Foo struct', many Go users might use this syntax
|
||||||
|
@ -591,7 +591,7 @@ fn (p mut Parser) enum_decl(_enum_name string) {
|
||||||
}
|
}
|
||||||
// Skip empty enums
|
// Skip empty enums
|
||||||
if enum_name != 'int' {
|
if enum_name != 'int' {
|
||||||
p.cgen.typedefs << 'typedef int $enum_name ;\n'
|
p.cgen.typedefs << 'typedef int $enum_name;'
|
||||||
}
|
}
|
||||||
p.check(.lcbr)
|
p.check(.lcbr)
|
||||||
mut val := 0
|
mut val := 0
|
||||||
|
@ -602,7 +602,7 @@ fn (p mut Parser) enum_decl(_enum_name string) {
|
||||||
name := '${p.mod}__${enum_name}_$field'
|
name := '${p.mod}__${enum_name}_$field'
|
||||||
p.fgenln('')
|
p.fgenln('')
|
||||||
if p.run == .main {
|
if p.run == .main {
|
||||||
p.cgen.consts << '#define $name $val \n'
|
p.cgen.consts << '#define $name $val'
|
||||||
}
|
}
|
||||||
if p.tok == .comma {
|
if p.tok == .comma {
|
||||||
p.next()
|
p.next()
|
||||||
|
@ -2046,7 +2046,8 @@ fn (p mut Parser) factor() string {
|
||||||
p.next()
|
p.next()
|
||||||
return 'T'
|
return 'T'
|
||||||
case Token.lpar:
|
case Token.lpar:
|
||||||
p.gen('(/*lpar*/')
|
//p.gen('(/*lpar*/')
|
||||||
|
p.gen('(')
|
||||||
p.check(.lpar)
|
p.check(.lpar)
|
||||||
typ = p.bool_expression()
|
typ = p.bool_expression()
|
||||||
// Hack. If this `)` referes to a ptr cast `(*int__)__`, it was already checked
|
// Hack. If this `)` referes to a ptr cast `(*int__)__`, it was already checked
|
||||||
|
@ -2686,13 +2687,17 @@ fn (p mut Parser) chash() {
|
||||||
pos := flag.index(' ')
|
pos := flag.index(' ')
|
||||||
flag = flag.right(pos)
|
flag = flag.right(pos)
|
||||||
}
|
}
|
||||||
|
has_vroot := flag.contains('@VROOT')
|
||||||
flag = flag.trim_space().replace('@VROOT', p.vroot)
|
flag = flag.trim_space().replace('@VROOT', p.vroot)
|
||||||
if p.table.flags.contains(flag) {
|
if p.table.flags.contains(flag) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.log('adding flag "$flag"')
|
p.log('adding flag "$flag"')
|
||||||
p.table.flags << flag// .all_after(' '))
|
// `@VROOT/thirdparty/glad/glad.o`, make sure it exists, otherwise build it
|
||||||
// }
|
if has_vroot && flag.contains('.o') {
|
||||||
|
build_thirdparty_obj_file(flag)
|
||||||
|
}
|
||||||
|
p.table.flags << flag
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if hash.starts_with('include') {
|
if hash.starts_with('include') {
|
||||||
|
@ -2745,7 +2750,6 @@ fn (p mut Parser) if_st(is_expr bool) string {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p.genln(') {')
|
p.genln(') {')
|
||||||
p.genln('/*if*/')
|
|
||||||
}
|
}
|
||||||
p.fgen(' ')
|
p.fgen(' ')
|
||||||
p.check(.lcbr)
|
p.check(.lcbr)
|
||||||
|
@ -2775,7 +2779,6 @@ fn (p mut Parser) if_st(is_expr bool) string {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p.genln(' else { ')
|
p.genln(' else { ')
|
||||||
p.genln('/*else if*/')
|
|
||||||
}
|
}
|
||||||
p.check(.lcbr)
|
p.check(.lcbr)
|
||||||
// statements() returns the type of the last statement
|
// statements() returns the type of the last statement
|
||||||
|
@ -2957,6 +2960,7 @@ fn (p mut Parser) for_st() {
|
||||||
}
|
}
|
||||||
p.fspace()
|
p.fspace()
|
||||||
p.check(.lcbr)
|
p.check(.lcbr)
|
||||||
|
p.genln('')
|
||||||
p.statements()
|
p.statements()
|
||||||
p.cur_fn.close_scope()
|
p.cur_fn.close_scope()
|
||||||
p.for_expr_cnt--
|
p.for_expr_cnt--
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "glad.h"
|
||||||
//#include <glad/glad.h>
|
//#include <glad/glad.h>
|
||||||
|
|
||||||
static void* get_proc(const char *namez);
|
static void* get_proc(const char *namez);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,525 @@
|
||||||
|
/*************************************************************************
|
||||||
|
* GLFW 3.3 - www.glfw.org
|
||||||
|
* A library for OpenGL, window and input
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
* Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would
|
||||||
|
* be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
* be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _glfw3_native_h_
|
||||||
|
#define _glfw3_native_h_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Doxygen documentation
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
/*! @file glfw3native.h
|
||||||
|
* @brief The header of the native access functions.
|
||||||
|
*
|
||||||
|
* This is the header file of the native access functions. See @ref native for
|
||||||
|
* more information.
|
||||||
|
*/
|
||||||
|
/*! @defgroup native Native access
|
||||||
|
* @brief Functions related to accessing native handles.
|
||||||
|
*
|
||||||
|
* **By using the native access functions you assert that you know what you're
|
||||||
|
* doing and how to fix problems caused by using them. If you don't, you
|
||||||
|
* shouldn't be using them.**
|
||||||
|
*
|
||||||
|
* Before the inclusion of @ref glfw3native.h, you may define zero or more
|
||||||
|
* window system API macro and zero or more context creation API macros.
|
||||||
|
*
|
||||||
|
* The chosen backends must match those the library was compiled for. Failure
|
||||||
|
* to do this will cause a link-time error.
|
||||||
|
*
|
||||||
|
* The available window API macros are:
|
||||||
|
* * `GLFW_EXPOSE_NATIVE_WIN32`
|
||||||
|
* * `GLFW_EXPOSE_NATIVE_COCOA`
|
||||||
|
* * `GLFW_EXPOSE_NATIVE_X11`
|
||||||
|
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
|
||||||
|
*
|
||||||
|
* The available context API macros are:
|
||||||
|
* * `GLFW_EXPOSE_NATIVE_WGL`
|
||||||
|
* * `GLFW_EXPOSE_NATIVE_NSGL`
|
||||||
|
* * `GLFW_EXPOSE_NATIVE_GLX`
|
||||||
|
* * `GLFW_EXPOSE_NATIVE_EGL`
|
||||||
|
* * `GLFW_EXPOSE_NATIVE_OSMESA`
|
||||||
|
*
|
||||||
|
* These macros select which of the native access functions that are declared
|
||||||
|
* and which platform-specific headers to include. It is then up your (by
|
||||||
|
* definition platform-specific) code to handle which of these should be
|
||||||
|
* defined.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* System headers and types
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||||
|
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
||||||
|
// example to allow applications to correctly declare a GL_ARB_debug_output
|
||||||
|
// callback) but windows.h assumes no one will define APIENTRY before it does
|
||||||
|
#if defined(GLFW_APIENTRY_DEFINED)
|
||||||
|
#undef APIENTRY
|
||||||
|
#undef GLFW_APIENTRY_DEFINED
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||||
|
#if defined(__OBJC__)
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#else
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
typedef void* id;
|
||||||
|
#endif
|
||||||
|
#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/extensions/Xrandr.h>
|
||||||
|
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||||
|
#include <wayland-client.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||||
|
/* WGL is declared by windows.h */
|
||||||
|
#endif
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||||
|
/* NSGL is declared by Cocoa.h */
|
||||||
|
#endif
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||||
|
#include <GL/glx.h>
|
||||||
|
#endif
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
#endif
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||||
|
#include <GL/osmesa.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Functions
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
|
||||||
|
/*! @brief Returns the adapter device name of the specified monitor.
|
||||||
|
*
|
||||||
|
* @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
|
||||||
|
* of the specified monitor, or `NULL` if an [error](@ref error_handling)
|
||||||
|
* occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.1.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
/*! @brief Returns the display device name of the specified monitor.
|
||||||
|
*
|
||||||
|
* @return The UTF-8 encoded display device name (for example
|
||||||
|
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.1.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
/*! @brief Returns the `HWND` of the specified window.
|
||||||
|
*
|
||||||
|
* @return The `HWND` of the specified window, or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.0.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||||
|
/*! @brief Returns the `HGLRC` of the specified window.
|
||||||
|
*
|
||||||
|
* @return The `HGLRC` of the specified window, or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.0.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
|
||||||
|
/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
|
||||||
|
*
|
||||||
|
* @return The `CGDirectDisplayID` of the specified monitor, or
|
||||||
|
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.1.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
/*! @brief Returns the `NSWindow` of the specified window.
|
||||||
|
*
|
||||||
|
* @return The `NSWindow` of the specified window, or `nil` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.0.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||||
|
/*! @brief Returns the `NSOpenGLContext` of the specified window.
|
||||||
|
*
|
||||||
|
* @return The `NSOpenGLContext` of the specified window, or `nil` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.0.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_X11)
|
||||||
|
/*! @brief Returns the `Display` used by GLFW.
|
||||||
|
*
|
||||||
|
* @return The `Display` used by GLFW, or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.0.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI Display* glfwGetX11Display(void);
|
||||||
|
|
||||||
|
/*! @brief Returns the `RRCrtc` of the specified monitor.
|
||||||
|
*
|
||||||
|
* @return The `RRCrtc` of the specified monitor, or `None` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.1.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
/*! @brief Returns the `RROutput` of the specified monitor.
|
||||||
|
*
|
||||||
|
* @return The `RROutput` of the specified monitor, or `None` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.1.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
/*! @brief Returns the `Window` of the specified window.
|
||||||
|
*
|
||||||
|
* @return The `Window` of the specified window, or `None` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.0.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
|
||||||
|
|
||||||
|
/*! @brief Sets the current primary selection to the specified string.
|
||||||
|
*
|
||||||
|
* @param[in] string A UTF-8 encoded string.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
|
* GLFW_PLATFORM_ERROR.
|
||||||
|
*
|
||||||
|
* @pointer_lifetime The specified string is copied before this function
|
||||||
|
* returns.
|
||||||
|
*
|
||||||
|
* @thread_safety This function must only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref clipboard
|
||||||
|
* @sa glfwGetX11SelectionString
|
||||||
|
* @sa glfwSetClipboardString
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI void glfwSetX11SelectionString(const char* string);
|
||||||
|
|
||||||
|
/*! @brief Returns the contents of the current primary selection as a string.
|
||||||
|
*
|
||||||
|
* If the selection is empty or if its contents cannot be converted, `NULL`
|
||||||
|
* is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated.
|
||||||
|
*
|
||||||
|
* @return The contents of the selection as a UTF-8 encoded string, or `NULL`
|
||||||
|
* if an [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
|
* GLFW_PLATFORM_ERROR.
|
||||||
|
*
|
||||||
|
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
|
||||||
|
* should not free it yourself. It is valid until the next call to @ref
|
||||||
|
* glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the
|
||||||
|
* library is terminated.
|
||||||
|
*
|
||||||
|
* @thread_safety This function must only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref clipboard
|
||||||
|
* @sa glfwSetX11SelectionString
|
||||||
|
* @sa glfwGetClipboardString
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI const char* glfwGetX11SelectionString(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||||
|
/*! @brief Returns the `GLXContext` of the specified window.
|
||||||
|
*
|
||||||
|
* @return The `GLXContext` of the specified window, or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.0.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
|
||||||
|
|
||||||
|
/*! @brief Returns the `GLXWindow` of the specified window.
|
||||||
|
*
|
||||||
|
* @return The `GLXWindow` of the specified window, or `None` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.2.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||||
|
/*! @brief Returns the `struct wl_display*` used by GLFW.
|
||||||
|
*
|
||||||
|
* @return The `struct wl_display*` used by GLFW, or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.2.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
|
||||||
|
|
||||||
|
/*! @brief Returns the `struct wl_output*` of the specified monitor.
|
||||||
|
*
|
||||||
|
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.2.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
/*! @brief Returns the main `struct wl_surface*` of the specified window.
|
||||||
|
*
|
||||||
|
* @return The main `struct wl_surface*` of the specified window, or `NULL` if
|
||||||
|
* an [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.2.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||||
|
/*! @brief Returns the `EGLDisplay` used by GLFW.
|
||||||
|
*
|
||||||
|
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.0.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
|
||||||
|
|
||||||
|
/*! @brief Returns the `EGLContext` of the specified window.
|
||||||
|
*
|
||||||
|
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.0.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
|
||||||
|
|
||||||
|
/*! @brief Returns the `EGLSurface` of the specified window.
|
||||||
|
*
|
||||||
|
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.0.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||||
|
/*! @brief Retrieves the color buffer associated with the specified window.
|
||||||
|
*
|
||||||
|
* @param[in] window The window whose color buffer to retrieve.
|
||||||
|
* @param[out] width Where to store the width of the color buffer, or `NULL`.
|
||||||
|
* @param[out] height Where to store the height of the color buffer, or `NULL`.
|
||||||
|
* @param[out] format Where to store the OSMesa pixel format of the color
|
||||||
|
* buffer, or `NULL`.
|
||||||
|
* @param[out] buffer Where to store the address of the color buffer, or
|
||||||
|
* `NULL`.
|
||||||
|
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer);
|
||||||
|
|
||||||
|
/*! @brief Retrieves the depth buffer associated with the specified window.
|
||||||
|
*
|
||||||
|
* @param[in] window The window whose depth buffer to retrieve.
|
||||||
|
* @param[out] width Where to store the width of the depth buffer, or `NULL`.
|
||||||
|
* @param[out] height Where to store the height of the depth buffer, or `NULL`.
|
||||||
|
* @param[out] bytesPerValue Where to store the number of bytes per depth
|
||||||
|
* buffer element, or `NULL`.
|
||||||
|
* @param[out] buffer Where to store the address of the depth buffer, or
|
||||||
|
* `NULL`.
|
||||||
|
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer);
|
||||||
|
|
||||||
|
/*! @brief Returns the `OSMesaContext` of the specified window.
|
||||||
|
*
|
||||||
|
* @return The `OSMesaContext` of the specified window, or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _glfw3_native_h_ */
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,358 @@
|
||||||
|
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
||||||
|
// Use of this source code is governed by an MIT license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
module ft
|
||||||
|
|
||||||
|
import stbi
|
||||||
|
import glm
|
||||||
|
import gl
|
||||||
|
|
||||||
|
#flag -I @VROOT/thirdparty/freetype
|
||||||
|
|
||||||
|
#flag @VROOT/thirdparty/freetype/libfreetype.a
|
||||||
|
#flag darwin -lpng -lbz2 -lz
|
||||||
|
|
||||||
|
|
||||||
|
#flag linux -I/usr/include/freetype2
|
||||||
|
#flag linux -I.
|
||||||
|
|
||||||
|
|
||||||
|
#include "ft2build.h"
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
|
struct GG {
|
||||||
|
shader gl.Shader
|
||||||
|
// use_ortho bool
|
||||||
|
width int
|
||||||
|
height int
|
||||||
|
VAO u32
|
||||||
|
rect_vao u32
|
||||||
|
rect_vbo u32
|
||||||
|
line_vao u32
|
||||||
|
line_vbo u32
|
||||||
|
VBO u32
|
||||||
|
chars []gg.Character
|
||||||
|
utf_runes []string
|
||||||
|
utf_chars []gg.Character
|
||||||
|
text_ctx *GG
|
||||||
|
face Face
|
||||||
|
scale int // retina = 2 , normal = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Character {
|
||||||
|
texture_id u32
|
||||||
|
size Vec2
|
||||||
|
bearing Vec2
|
||||||
|
advance u32
|
||||||
|
}
|
||||||
|
|
||||||
|
// jfn ft_load_char(face FT_Face, code FT_ULong) Character {
|
||||||
|
// fn ft_load_char(_face voidptr, _code voidptr) Character {
|
||||||
|
fn ft_load_char(_face Face, code i64) Character {
|
||||||
|
// #FT_Face face = *(FT_Face*)(_face); FT_ULong code = *(FT_ULong*)(code);
|
||||||
|
# FT_Face face = *((FT_Face*)_face.cobj);
|
||||||
|
# if (FT_Load_Char(face, code, FT_LOAD_RENDER))
|
||||||
|
{
|
||||||
|
println('freetype: Failed to load Glyph')
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
// Generate texture
|
||||||
|
# GLuint texture;
|
||||||
|
# glGenTextures(1, &texture);
|
||||||
|
# glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
|
# glTexImage2D(
|
||||||
|
# GL_TEXTURE_2D,
|
||||||
|
# 0,
|
||||||
|
# GL_RED,
|
||||||
|
# face->glyph->bitmap.width,
|
||||||
|
# face->glyph->bitmap.rows,
|
||||||
|
# 0,
|
||||||
|
# GL_RED,
|
||||||
|
# GL_UNSIGNED_BYTE,
|
||||||
|
# face->glyph->bitmap.buffer
|
||||||
|
# );
|
||||||
|
// Set texture options
|
||||||
|
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
// Now store character for later use
|
||||||
|
ch := Character{}
|
||||||
|
# ch.texture_id=texture ;
|
||||||
|
# ch.size = gg__vec2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
|
||||||
|
# ch.bearing = gg__vec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
|
||||||
|
# ch.advance = face->glyph->advance.x;
|
||||||
|
return ch
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_context_text(cfg Cfg, scale int) *GG {
|
||||||
|
// Can only have text in ortho mode
|
||||||
|
if !cfg.use_ortho {
|
||||||
|
return &GG{text_ctx: 0}
|
||||||
|
}
|
||||||
|
mut width := cfg.width * scale
|
||||||
|
mut height := cfg.height * scale
|
||||||
|
font_size := cfg.font_size * scale
|
||||||
|
// exit('fs=$font_size')
|
||||||
|
// if false {
|
||||||
|
// retina
|
||||||
|
// width = width * 2// scale// 2
|
||||||
|
// height = height * 2// scale// 2
|
||||||
|
// font_size *= scale// 2
|
||||||
|
// }
|
||||||
|
/*
|
||||||
|
gl.viewport(0, 0, width, height)
|
||||||
|
*/
|
||||||
|
// gl.enable(GL_CULL_FACE) // TODO NEED CULL?
|
||||||
|
gl.enable(GL_BLEND)
|
||||||
|
return &GG{}
|
||||||
|
// return &GG{}
|
||||||
|
# glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
shader := gl.new_shader('text')
|
||||||
|
shader.use()
|
||||||
|
projection := glm.ortho(0, width, 0, height)// 0 at BOT
|
||||||
|
// projection_new := ortho(0, width, 0, height)// 0 at BOT
|
||||||
|
// projection := gl.ortho(0, width,height,0) // 0 at TOP
|
||||||
|
shader.set_mat4('projection', projection)
|
||||||
|
// FREETYPE
|
||||||
|
# FT_Library ft;
|
||||||
|
// All functions return a value different than 0 whenever an error occurred
|
||||||
|
# if (FT_Init_FreeType(&ft))
|
||||||
|
println('ERROR::FREETYPE: Could not init FreeType Library')
|
||||||
|
// Load font as face
|
||||||
|
// face := FT_Face{}
|
||||||
|
mut font_path := 'RobotoMono-Regular.ttf'
|
||||||
|
if !os.file_exists(font_path) {
|
||||||
|
exePath := os.getexepath()
|
||||||
|
exeDir := os.basedir(exePath)
|
||||||
|
println('Trying to load from $exeDir')
|
||||||
|
font_path = '${exeDir}/RobotoMono-Regular.ttf'
|
||||||
|
}
|
||||||
|
if !os.file_exists(font_path) {
|
||||||
|
println('failed to load RobotoMono-Regular.ttf')
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
# FT_Face face;
|
||||||
|
# if (FT_New_Face(ft, font_path.str, 0, &face))
|
||||||
|
// # if (FT_New_Face(ft, "/Library/Fonts/Courier New.ttf", 0, &face))
|
||||||
|
// # if (FT_New_Face(ft, "/System/Library/Fonts/Apple Color Emoji.ttc", 0, &face))
|
||||||
|
{
|
||||||
|
println('freetyp: Failed to load font')
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
// Set size to load glyphs as
|
||||||
|
# FT_Set_Pixel_Sizes(face, 0, font_size) ;
|
||||||
|
// Disable byte-alignment restriction
|
||||||
|
# glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
// Gen texture
|
||||||
|
// Load first 128 characters of ASCII set
|
||||||
|
mut chars := []gg.Character{}
|
||||||
|
f := Face {
|
||||||
|
cobj: 0
|
||||||
|
}
|
||||||
|
# f.cobj = &face;
|
||||||
|
// # for (GLubyte c = 0; c < 128; c++)
|
||||||
|
for c := 0; c < 128; c++ {
|
||||||
|
// ch := Character{}
|
||||||
|
// ch:=ft_load_char(face, c)
|
||||||
|
// # ch =gg__ft_load_char(&face, &c);
|
||||||
|
// ////////////////////////////////
|
||||||
|
mut ch := ft_load_char(f, i64(c))
|
||||||
|
// s := utf32_to_str(uint(0x043f))
|
||||||
|
// s := 'п'
|
||||||
|
// ch = ft_load_char(f, s.utf32_code())
|
||||||
|
// # ch = gg__ft_load_char(f, 0x043f); // RUS P
|
||||||
|
// # unsigned long c = FT_Get_Char_Index(face, 0x043f );
|
||||||
|
// # printf("!!!!!!!!! %lu\n", c);
|
||||||
|
// # c = FT_Get_Char_Index(face, 0xd0bf );
|
||||||
|
// # printf("!!!!!!!!! %lu\n", c);
|
||||||
|
// # ch = gg__ft_load_char(f, 0xd0bf) ; // UTF 8
|
||||||
|
chars << ch
|
||||||
|
}
|
||||||
|
ch := Character{}
|
||||||
|
// # ch = gg__ft_load_char(f, 0x0000043f);
|
||||||
|
// # ch = gg__ft_load_char(f, 128169);
|
||||||
|
// chars.push(ch)
|
||||||
|
// Configure VAO
|
||||||
|
VAO := gl.gen_vertex_array()
|
||||||
|
println('new gg text context VAO=$VAO')
|
||||||
|
VBO := gl.gen_buffer()
|
||||||
|
gl.bind_vao(VAO)
|
||||||
|
gl.bind_buffer(GL_ARRAY_BUFFER, VBO)
|
||||||
|
// # glBufferData(GL_ARRAY_BUFFER, sizeof(GLf32) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
gl.enable_vertex_attrib_array(0)
|
||||||
|
gl.vertex_attrib_pointer(0, 4, GL_FLOAT, false, 4, 0)
|
||||||
|
// # glVertexAttribPointer(0, 4, GL_FLOAT,false, 4 * sizeof(GLf32), 0);
|
||||||
|
// gl.bind_buffer(GL_ARRAY_BUFFER, uint(0))
|
||||||
|
// # glBindVertexArray(0);
|
||||||
|
mut ctx := &GG {
|
||||||
|
shader: shader,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
scale: scale
|
||||||
|
VAO: VAO,
|
||||||
|
VBO: VBO,
|
||||||
|
chars: chars,
|
||||||
|
face: f
|
||||||
|
text_ctx: 0
|
||||||
|
}
|
||||||
|
ctx.init_utf8_runes()
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
// A dirty hack to implement rendering of cyrillic letters.
|
||||||
|
// All UTF-8 must be supported.
|
||||||
|
fn (ctx mut GG) init_utf8_runes() {
|
||||||
|
s := '≈йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ'
|
||||||
|
println(s)
|
||||||
|
us := s.ustring()
|
||||||
|
for i := 0; i < us.len; i++ {
|
||||||
|
_rune := us.at(i)
|
||||||
|
ch := ft_load_char(ctx.face, _rune.utf32_code())
|
||||||
|
// ctx.utf_rune_map.set(rune, ch)
|
||||||
|
ctx.utf_runes << _rune
|
||||||
|
ctx.utf_chars << ch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn (ctx &GG) render_text(text string, x, y, scale f32, color gx.Color) {
|
||||||
|
pub fn (ctx &GG) draw_text(_x, _y int, text string, cfg gx.TextCfg) {
|
||||||
|
// dont draw non ascii for now
|
||||||
|
/*
|
||||||
|
for i := 0; i < text.len; i++ {
|
||||||
|
c := text[i]
|
||||||
|
if int(c) > 128 {
|
||||||
|
// ctx.text_ctx._draw_text(_x, _y, '[NON ASCII]', cfg)
|
||||||
|
// return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// # glScissor(0,0,300,300);
|
||||||
|
utext := text.ustring_tmp()
|
||||||
|
// utext := text.ustring()
|
||||||
|
ctx.text_ctx._draw_text(_x, _y, utext, cfg)
|
||||||
|
// utext.free()
|
||||||
|
// # glScissor(0,0,ctx->width*2,ctx->height*2);
|
||||||
|
// gl.disable(GL_SCISSOR_TEST)// TODO
|
||||||
|
// #free(text.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (ctx &GG) draw_text_fast(_x, _y int, text ustring, cfg gx.TextCfg) {
|
||||||
|
ctx.text_ctx._draw_text(_x, _y, text, cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO HACK with second text context
|
||||||
|
// fn (ctx &GG) _draw_text(_x, _y int, text string, cfg gx.TextCfg) {
|
||||||
|
fn (ctx &GG) _draw_text(_x, _y int, utext ustring, cfg gx.TextCfg) {
|
||||||
|
/*
|
||||||
|
if utext.s.contains('on_seg') {
|
||||||
|
println('\nat(0)')
|
||||||
|
println(utext.runes)
|
||||||
|
firstc := utext.at(0)
|
||||||
|
println('drawtext "$utext.s" len=$utext.s.len ulen=$utext.len x=$_x firstc=$firstc')
|
||||||
|
if firstc != ' ' {
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// println('scale=$ctx.scale size=$cfg.size')
|
||||||
|
if cfg.align == gx.ALIGN_RIGHT {
|
||||||
|
width := utext.len * 7
|
||||||
|
_x -= width + 10
|
||||||
|
}
|
||||||
|
x := f32(_x) * ctx.scale// f32(2)
|
||||||
|
// println('y=$_y height=$ctx.height')
|
||||||
|
// _y = _y * int(ctx.scale) //+ 26
|
||||||
|
_y = _y * int(ctx.scale) + ((cfg.size * ctx.scale) / 2) + 5 * ctx.scale
|
||||||
|
y := f32(ctx.height - _y)
|
||||||
|
color := cfg.color
|
||||||
|
// Activate corresponding render state
|
||||||
|
ctx.shader.use()
|
||||||
|
ctx.shader.set_color('textColor', color)
|
||||||
|
# glActiveTexture(GL_TEXTURE0);
|
||||||
|
gl.bind_vao(ctx.VAO)
|
||||||
|
// Iterate through all characters
|
||||||
|
// utext := text.ustring()
|
||||||
|
for i := 0; i < utext.len; i++ {
|
||||||
|
_rune := utext.at(i)
|
||||||
|
// println('$i => $_rune')
|
||||||
|
mut ch := Character{}
|
||||||
|
if _rune.len == 1 {
|
||||||
|
idx := _rune[0]
|
||||||
|
if idx < 0 || idx >= ctx.chars.len {
|
||||||
|
println('BADE RUNE $_rune')
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ch = ctx.chars[_rune[0]]
|
||||||
|
}
|
||||||
|
else if _rune.len > 1 {
|
||||||
|
// TODO O(1) use map
|
||||||
|
for j := 0; j < ctx.utf_runes.len; j++ {
|
||||||
|
rune_j := ctx.utf_runes[j]
|
||||||
|
// if string_eq(ctx.utf_runes[j], rune) {
|
||||||
|
if rune_j==_rune {
|
||||||
|
ch = ctx.utf_chars[j]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ch.size.x == 0 {
|
||||||
|
// continue
|
||||||
|
}
|
||||||
|
// mut c := int(text[i])
|
||||||
|
// c = 128
|
||||||
|
// s := 'A'
|
||||||
|
// c := int(s[0])
|
||||||
|
// ch := ctx.chars[c]
|
||||||
|
xpos := x + f32(ch.bearing.x) * 1
|
||||||
|
ypos := y - f32(ch.size.y - ch.bearing.y) * 1
|
||||||
|
w := f32(ch.size.x) * 1
|
||||||
|
h := f32(ch.size.y) * 1
|
||||||
|
// Update VBO for each character
|
||||||
|
# GLfloat vertices[6][4] = {
|
||||||
|
# { xpos, ypos + h, 0.0, 0.0 },
|
||||||
|
# { xpos, ypos, 0.0, 1.0 },
|
||||||
|
# { xpos + w, ypos, 1.0, 1.0 },
|
||||||
|
# { xpos, ypos + h, 0.0, 0.0 },
|
||||||
|
# { xpos + w, ypos, 1.0, 1.0 },
|
||||||
|
# { xpos + w, ypos + h, 1.0, 0.0 }
|
||||||
|
# };
|
||||||
|
// t := glfw.get_time()
|
||||||
|
// Render glyph texture over quad
|
||||||
|
// t1 := glfw.get_time()
|
||||||
|
# glBindTexture(GL_TEXTURE_2D, ch.texture_id);
|
||||||
|
// Update content of VBO memory
|
||||||
|
gl.bind_buffer(GL_ARRAY_BUFFER, ctx.VBO)
|
||||||
|
// t2 := glfw.get_time()
|
||||||
|
// # glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); // Be sure to use glBufferSubData and not glBufferData
|
||||||
|
# glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
|
||||||
|
// t3 := glfw.get_time()
|
||||||
|
// gl.bind_buffer(GL_ARRAY_BUFFER, uint(0))
|
||||||
|
// t4 := glfw.get_time()
|
||||||
|
// Render quad
|
||||||
|
gl.draw_arrays(GL_TRIANGLES, 0, 6)
|
||||||
|
// t5 := glfw.get_time()
|
||||||
|
// # if (glfw__get_time() - t > 0.001)
|
||||||
|
// {
|
||||||
|
// # printf("do_text = %f '%s' \n", glfw__get_time() - t, text.str);
|
||||||
|
// # printf("t1=%f, t2=%f, t3=%f, t4=%f, t5=%f\n\n\n", t1-t, t2-t1, t3-t2, t4-t3, t5-t4);
|
||||||
|
// }
|
||||||
|
// Now advance cursors for next glyph (note that advance is number of 1/64 pixels)
|
||||||
|
// Bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels))
|
||||||
|
# x += (ch.advance >> 6) * 1;
|
||||||
|
}
|
||||||
|
gl.bind_vao(u32(0))
|
||||||
|
# glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
// runes.free()
|
||||||
|
// #free(runes.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (ctx &GG) draw_text_def(x, y int, text string) {
|
||||||
|
cfg := gx.TextCfg {
|
||||||
|
color: gx.Black,
|
||||||
|
size: DEFAULT_FONT_SIZE,
|
||||||
|
align: gx.ALIGN_LEFT,
|
||||||
|
}
|
||||||
|
ctx.draw_text(x, y, text, cfg)
|
||||||
|
}
|
335
vlib/gg/gg.v
335
vlib/gg/gg.v
|
@ -8,13 +8,6 @@ import stbi
|
||||||
import glm
|
import glm
|
||||||
import gl
|
import gl
|
||||||
|
|
||||||
#flag darwin -I/usr/local/Cellar/freetype/2.10.0/include/freetype2
|
|
||||||
#flag -lfreetype
|
|
||||||
#flag linux -I/usr/include/freetype2
|
|
||||||
#flag linux -I.
|
|
||||||
#include "ft2build.h"
|
|
||||||
#include FT_FREETYPE_H
|
|
||||||
#include "glad.h"
|
|
||||||
struct Vec2 {
|
struct Vec2 {
|
||||||
x int
|
x int
|
||||||
y int
|
y int
|
||||||
|
@ -40,13 +33,6 @@ pub fn vec2(x, y int) Vec2 {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Character {
|
|
||||||
texture_id u32
|
|
||||||
size Vec2
|
|
||||||
bearing Vec2
|
|
||||||
advance u32
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
println(gl.TEXT_VERT)
|
println(gl.TEXT_VERT)
|
||||||
gl.init_glad()
|
gl.init_glad()
|
||||||
|
@ -75,11 +61,6 @@ struct GG {
|
||||||
line_vao u32
|
line_vao u32
|
||||||
line_vbo u32
|
line_vbo u32
|
||||||
VBO u32
|
VBO u32
|
||||||
chars []gg.Character
|
|
||||||
utf_runes []string
|
|
||||||
utf_chars []gg.Character
|
|
||||||
text_ctx *GG
|
|
||||||
face Face
|
|
||||||
scale int // retina = 2 , normal = 1
|
scale int // retina = 2 , normal = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,11 +93,11 @@ pub fn new_context(cfg Cfg) *GG {
|
||||||
*/
|
*/
|
||||||
// projection_new := ortho(0, width, height, 0)
|
// projection_new := ortho(0, width, height, 0)
|
||||||
// println('\nORTHO OLD=')
|
// println('\nORTHO OLD=')
|
||||||
# for (int i=0;i<16;i++) printf("%d=%f ",i, projection.data[i]);
|
//# for (int i=0;i<16;i++) printf("%d=%f ",i, projection.data[i]);
|
||||||
// println('\n\n!ORTHO NEW=')
|
// println('\n\n!ORTHO NEW=')
|
||||||
// # for (int i=0;i<16;i++) printf("%d=%f ",i, projection_new[i]);
|
// # for (int i=0;i<16;i++) printf("%d=%f ",i, projection_new[i]);
|
||||||
// println('\n\n')
|
// println('\n\n')
|
||||||
println('setting o')
|
//println('setting o')
|
||||||
shader.set_mat4('projection', projection)
|
shader.set_mat4('projection', projection)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -125,21 +106,29 @@ pub fn new_context(cfg Cfg) *GG {
|
||||||
shader.set_mat4('projection', glm.identity())
|
shader.set_mat4('projection', glm.identity())
|
||||||
}
|
}
|
||||||
VAO := gl.gen_vertex_array()
|
VAO := gl.gen_vertex_array()
|
||||||
println('new gg context VAO=$VAO')
|
//println('new gg context VAO=$VAO')
|
||||||
VBO := gl.gen_buffer()
|
VBO := gl.gen_buffer()
|
||||||
mut scale := 1
|
mut scale := 1
|
||||||
if cfg.retina {
|
if cfg.retina {
|
||||||
scale = 2
|
scale = 2
|
||||||
}
|
}
|
||||||
|
gl.enable(GL_BLEND)
|
||||||
|
# glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
//println('new gg text context VAO=$VAO')
|
||||||
|
gl.bind_vao(VAO)
|
||||||
|
gl.bind_buffer(GL_ARRAY_BUFFER, VBO)
|
||||||
|
gl.enable_vertex_attrib_array(0)
|
||||||
|
gl.vertex_attrib_pointer(0, 4, GL_FLOAT, false, 4, 0)
|
||||||
|
todo_remove_me(cfg, scale)
|
||||||
mut ctx := &GG {
|
mut ctx := &GG {
|
||||||
shader: shader,
|
shader: shader
|
||||||
width: cfg.width,
|
width: cfg.width
|
||||||
height: cfg.height,
|
height: cfg.height
|
||||||
VAO: VAO,
|
VAO: VAO
|
||||||
VBO: VBO,
|
VBO: VBO
|
||||||
// /line_vao: gl.gen_vertex_array()
|
// /line_vao: gl.gen_vertex_array()
|
||||||
// /line_vbo: gl.gen_buffer()
|
// /line_vbo: gl.gen_buffer()
|
||||||
text_ctx: new_context_text(cfg, scale),
|
//text_ctx: new_context_text(cfg, scale),
|
||||||
scale: scale
|
scale: scale
|
||||||
// use_ortho: use_ortho
|
// use_ortho: use_ortho
|
||||||
}
|
}
|
||||||
|
@ -265,66 +254,15 @@ pub fn (ctx &GG) draw_rect2(x, y, w, h f32, c gx.Color) {
|
||||||
C.glDeleteBuffers(1, &ebo)
|
C.glDeleteBuffers(1, &ebo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// jfn ft_load_char(face FT_Face, code FT_ULong) Character {
|
fn todo_remove_me(cfg Cfg, scale int) {
|
||||||
// fn ft_load_char(_face voidptr, _code voidptr) Character {
|
|
||||||
fn ft_load_char(_face Face, code i64) Character {
|
|
||||||
// #FT_Face face = *(FT_Face*)(_face); FT_ULong code = *(FT_ULong*)(code);
|
|
||||||
# FT_Face face = *((FT_Face*)_face.cobj);
|
|
||||||
# if (FT_Load_Char(face, code, FT_LOAD_RENDER))
|
|
||||||
{
|
|
||||||
println('freetype: Failed to load Glyph')
|
|
||||||
exit(1)
|
|
||||||
}
|
|
||||||
// Generate texture
|
|
||||||
# GLuint texture;
|
|
||||||
# glGenTextures(1, &texture);
|
|
||||||
# glBindTexture(GL_TEXTURE_2D, texture);
|
|
||||||
# glTexImage2D(
|
|
||||||
# GL_TEXTURE_2D,
|
|
||||||
# 0,
|
|
||||||
# GL_RED,
|
|
||||||
# face->glyph->bitmap.width,
|
|
||||||
# face->glyph->bitmap.rows,
|
|
||||||
# 0,
|
|
||||||
# GL_RED,
|
|
||||||
# GL_UNSIGNED_BYTE,
|
|
||||||
# face->glyph->bitmap.buffer
|
|
||||||
# );
|
|
||||||
// Set texture options
|
|
||||||
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
// Now store character for later use
|
|
||||||
ch := Character{}
|
|
||||||
# ch.texture_id=texture ;
|
|
||||||
# ch.size = gg__vec2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
|
|
||||||
# ch.bearing = gg__vec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
|
|
||||||
# ch.advance = face->glyph->advance.x;
|
|
||||||
return ch
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_context_text(cfg Cfg, scale int) *GG {
|
|
||||||
// Can only have text in ortho mode
|
// Can only have text in ortho mode
|
||||||
if !cfg.use_ortho {
|
if !cfg.use_ortho {
|
||||||
return &GG{text_ctx: 0}
|
return &GG{}
|
||||||
}
|
}
|
||||||
mut width := cfg.width * scale
|
mut width := cfg.width * scale
|
||||||
mut height := cfg.height * scale
|
mut height := cfg.height * scale
|
||||||
font_size := cfg.font_size * scale
|
font_size := cfg.font_size * scale
|
||||||
// exit('fs=$font_size')
|
|
||||||
// if false {
|
|
||||||
// retina
|
|
||||||
// width = width * 2// scale// 2
|
|
||||||
// height = height * 2// scale// 2
|
|
||||||
// font_size *= scale// 2
|
|
||||||
// }
|
|
||||||
/*
|
|
||||||
gl.viewport(0, 0, width, height)
|
|
||||||
*/
|
|
||||||
// gl.enable(GL_CULL_FACE) // TODO NEED CULL? MEANS SHIT IS BROKEN?
|
|
||||||
gl.enable(GL_BLEND)
|
gl.enable(GL_BLEND)
|
||||||
// return &GG{}
|
|
||||||
# glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
# glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
shader := gl.new_shader('text')
|
shader := gl.new_shader('text')
|
||||||
shader.use()
|
shader.use()
|
||||||
|
@ -332,246 +270,13 @@ pub fn new_context_text(cfg Cfg, scale int) *GG {
|
||||||
// projection_new := ortho(0, width, 0, height)// 0 at BOT
|
// projection_new := ortho(0, width, 0, height)// 0 at BOT
|
||||||
// projection := gl.ortho(0, width,height,0) // 0 at TOP
|
// projection := gl.ortho(0, width,height,0) // 0 at TOP
|
||||||
shader.set_mat4('projection', projection)
|
shader.set_mat4('projection', projection)
|
||||||
// FREETYPE
|
|
||||||
# FT_Library ft;
|
|
||||||
// All functions return a value different than 0 whenever an error occurred
|
|
||||||
# if (FT_Init_FreeType(&ft))
|
|
||||||
println('ERROR::FREETYPE: Could not init FreeType Library')
|
|
||||||
// Load font as face
|
|
||||||
// face := FT_Face{}
|
|
||||||
mut font_path := 'RobotoMono-Regular.ttf'
|
|
||||||
if !os.file_exists(font_path) {
|
|
||||||
exePath := os.getexepath()
|
|
||||||
exeDir := os.basedir(exePath)
|
|
||||||
println('Trying to load from $exeDir')
|
|
||||||
font_path = '${exeDir}/RobotoMono-Regular.ttf'
|
|
||||||
}
|
|
||||||
if !os.file_exists(font_path) {
|
|
||||||
println('failed to load RobotoMono-Regular.ttf')
|
|
||||||
exit(1)
|
|
||||||
}
|
|
||||||
# FT_Face face;
|
|
||||||
# if (FT_New_Face(ft, font_path.str, 0, &face))
|
|
||||||
// # if (FT_New_Face(ft, "/Library/Fonts/Courier New.ttf", 0, &face))
|
|
||||||
// # if (FT_New_Face(ft, "/System/Library/Fonts/Apple Color Emoji.ttc", 0, &face))
|
|
||||||
{
|
|
||||||
println('freetyp: Failed to load font')
|
|
||||||
exit(1)
|
|
||||||
}
|
|
||||||
// Set size to load glyphs as
|
|
||||||
# FT_Set_Pixel_Sizes(face, 0, font_size) ;
|
|
||||||
// Disable byte-alignment restriction
|
|
||||||
# glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
||||||
// Gen texture
|
|
||||||
// Load first 128 characters of ASCII set
|
|
||||||
mut chars := []gg.Character{}
|
|
||||||
f := Face {
|
|
||||||
cobj: 0
|
|
||||||
}
|
|
||||||
# f.cobj = &face;
|
|
||||||
// # for (GLubyte c = 0; c < 128; c++)
|
|
||||||
for c := 0; c < 128; c++ {
|
|
||||||
// ch := Character{}
|
|
||||||
// ch:=ft_load_char(face, c)
|
|
||||||
// # ch =gg__ft_load_char(&face, &c);
|
|
||||||
// ////////////////////////////////
|
|
||||||
mut ch := ft_load_char(f, i64(c))
|
|
||||||
// s := utf32_to_str(uint(0x043f))
|
|
||||||
// s := 'п'
|
|
||||||
// ch = ft_load_char(f, s.utf32_code())
|
|
||||||
// # ch = gg__ft_load_char(f, 0x043f); // RUS P
|
|
||||||
// # unsigned long c = FT_Get_Char_Index(face, 0x043f );
|
|
||||||
// # printf("!!!!!!!!! %lu\n", c);
|
|
||||||
// # c = FT_Get_Char_Index(face, 0xd0bf );
|
|
||||||
// # printf("!!!!!!!!! %lu\n", c);
|
|
||||||
// # ch = gg__ft_load_char(f, 0xd0bf) ; // UTF 8
|
|
||||||
chars << ch
|
|
||||||
}
|
|
||||||
ch := Character{}
|
|
||||||
// # ch = gg__ft_load_char(f, 0x0000043f);
|
|
||||||
// # ch = gg__ft_load_char(f, 128169);
|
|
||||||
// chars.push(ch)
|
|
||||||
// Configure VAO
|
|
||||||
VAO := gl.gen_vertex_array()
|
VAO := gl.gen_vertex_array()
|
||||||
println('new gg text context VAO=$VAO')
|
//println('new gg text context VAO=$VAO')
|
||||||
VBO := gl.gen_buffer()
|
VBO := gl.gen_buffer()
|
||||||
gl.bind_vao(VAO)
|
gl.bind_vao(VAO)
|
||||||
gl.bind_buffer(GL_ARRAY_BUFFER, VBO)
|
gl.bind_buffer(GL_ARRAY_BUFFER, VBO)
|
||||||
// # glBufferData(GL_ARRAY_BUFFER, sizeof(GLf32) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
|
||||||
gl.enable_vertex_attrib_array(0)
|
gl.enable_vertex_attrib_array(0)
|
||||||
gl.vertex_attrib_pointer(0, 4, GL_FLOAT, false, 4, 0)
|
gl.vertex_attrib_pointer(0, 4, GL_FLOAT, false, 4, 0)
|
||||||
// # glVertexAttribPointer(0, 4, GL_FLOAT,false, 4 * sizeof(GLf32), 0);
|
|
||||||
// gl.bind_buffer(GL_ARRAY_BUFFER, uint(0))
|
|
||||||
// # glBindVertexArray(0);
|
|
||||||
mut ctx := &GG {
|
|
||||||
shader: shader,
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
scale: scale
|
|
||||||
VAO: VAO,
|
|
||||||
VBO: VBO,
|
|
||||||
chars: chars,
|
|
||||||
face: f
|
|
||||||
text_ctx: 0
|
|
||||||
}
|
|
||||||
ctx.init_utf8_runes()
|
|
||||||
return ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
// A dirty hack to implement rendering of cyrillic letters.
|
|
||||||
// All UTF-8 must be supported.
|
|
||||||
fn (ctx mut GG) init_utf8_runes() {
|
|
||||||
s := '≈йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ'
|
|
||||||
println(s)
|
|
||||||
us := s.ustring()
|
|
||||||
for i := 0; i < us.len; i++ {
|
|
||||||
_rune := us.at(i)
|
|
||||||
ch := ft_load_char(ctx.face, _rune.utf32_code())
|
|
||||||
// ctx.utf_rune_map.set(rune, ch)
|
|
||||||
ctx.utf_runes << _rune
|
|
||||||
ctx.utf_chars << ch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fn (ctx &GG) render_text(text string, x, y, scale f32, color gx.Color) {
|
|
||||||
pub fn (ctx &GG) draw_text(_x, _y int, text string, cfg gx.TextCfg) {
|
|
||||||
// dont draw non ascii for now
|
|
||||||
/*
|
|
||||||
for i := 0; i < text.len; i++ {
|
|
||||||
c := text[i]
|
|
||||||
if int(c) > 128 {
|
|
||||||
// ctx.text_ctx._draw_text(_x, _y, '[NON ASCII]', cfg)
|
|
||||||
// return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// # glScissor(0,0,300,300);
|
|
||||||
utext := text.ustring_tmp()
|
|
||||||
// utext := text.ustring()
|
|
||||||
ctx.text_ctx._draw_text(_x, _y, utext, cfg)
|
|
||||||
// utext.free()
|
|
||||||
// # glScissor(0,0,ctx->width*2,ctx->height*2);
|
|
||||||
// gl.disable(GL_SCISSOR_TEST)// TODO
|
|
||||||
// #free(text.str);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (ctx &GG) draw_text_fast(_x, _y int, text ustring, cfg gx.TextCfg) {
|
|
||||||
ctx.text_ctx._draw_text(_x, _y, text, cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO HACK with second text context
|
|
||||||
// fn (ctx &GG) _draw_text(_x, _y int, text string, cfg gx.TextCfg) {
|
|
||||||
fn (ctx &GG) _draw_text(_x, _y int, utext ustring, cfg gx.TextCfg) {
|
|
||||||
/*
|
|
||||||
if utext.s.contains('on_seg') {
|
|
||||||
println('\nat(0)')
|
|
||||||
println(utext.runes)
|
|
||||||
firstc := utext.at(0)
|
|
||||||
println('drawtext "$utext.s" len=$utext.s.len ulen=$utext.len x=$_x firstc=$firstc')
|
|
||||||
if firstc != ' ' {
|
|
||||||
exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// println('scale=$ctx.scale size=$cfg.size')
|
|
||||||
if cfg.align == gx.ALIGN_RIGHT {
|
|
||||||
width := utext.len * 7
|
|
||||||
_x -= width + 10
|
|
||||||
}
|
|
||||||
x := f32(_x) * ctx.scale// f32(2)
|
|
||||||
// println('y=$_y height=$ctx.height')
|
|
||||||
// _y = _y * int(ctx.scale) //+ 26
|
|
||||||
_y = _y * int(ctx.scale) + ((cfg.size * ctx.scale) / 2) + 5 * ctx.scale
|
|
||||||
y := f32(ctx.height - _y)
|
|
||||||
color := cfg.color
|
|
||||||
// Activate corresponding render state
|
|
||||||
ctx.shader.use()
|
|
||||||
ctx.shader.set_color('textColor', color)
|
|
||||||
# glActiveTexture(GL_TEXTURE0);
|
|
||||||
gl.bind_vao(ctx.VAO)
|
|
||||||
// Iterate through all characters
|
|
||||||
// utext := text.ustring()
|
|
||||||
for i := 0; i < utext.len; i++ {
|
|
||||||
_rune := utext.at(i)
|
|
||||||
// println('$i => $_rune')
|
|
||||||
mut ch := Character{}
|
|
||||||
if _rune.len == 1 {
|
|
||||||
idx := _rune[0]
|
|
||||||
if idx < 0 || idx >= ctx.chars.len {
|
|
||||||
println('BADE RUNE $_rune')
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ch = ctx.chars[_rune[0]]
|
|
||||||
}
|
|
||||||
else if _rune.len > 1 {
|
|
||||||
// TODO O(1) use map
|
|
||||||
for j := 0; j < ctx.utf_runes.len; j++ {
|
|
||||||
rune_j := ctx.utf_runes[j]
|
|
||||||
// if string_eq(ctx.utf_runes[j], rune) {
|
|
||||||
if rune_j==_rune {
|
|
||||||
ch = ctx.utf_chars[j]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ch.size.x == 0 {
|
|
||||||
// continue
|
|
||||||
}
|
|
||||||
// mut c := int(text[i])
|
|
||||||
// c = 128
|
|
||||||
// s := 'A'
|
|
||||||
// c := int(s[0])
|
|
||||||
// ch := ctx.chars[c]
|
|
||||||
xpos := x + f32(ch.bearing.x) * 1
|
|
||||||
ypos := y - f32(ch.size.y - ch.bearing.y) * 1
|
|
||||||
w := f32(ch.size.x) * 1
|
|
||||||
h := f32(ch.size.y) * 1
|
|
||||||
// Update VBO for each character
|
|
||||||
# GLfloat vertices[6][4] = {
|
|
||||||
# { xpos, ypos + h, 0.0, 0.0 },
|
|
||||||
# { xpos, ypos, 0.0, 1.0 },
|
|
||||||
# { xpos + w, ypos, 1.0, 1.0 },
|
|
||||||
# { xpos, ypos + h, 0.0, 0.0 },
|
|
||||||
# { xpos + w, ypos, 1.0, 1.0 },
|
|
||||||
# { xpos + w, ypos + h, 1.0, 0.0 }
|
|
||||||
# };
|
|
||||||
// t := glfw.get_time()
|
|
||||||
// Render glyph texture over quad
|
|
||||||
// t1 := glfw.get_time()
|
|
||||||
# glBindTexture(GL_TEXTURE_2D, ch.texture_id);
|
|
||||||
// Update content of VBO memory
|
|
||||||
gl.bind_buffer(GL_ARRAY_BUFFER, ctx.VBO)
|
|
||||||
// t2 := glfw.get_time()
|
|
||||||
// # glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); // Be sure to use glBufferSubData and not glBufferData
|
|
||||||
# glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
|
|
||||||
// t3 := glfw.get_time()
|
|
||||||
// gl.bind_buffer(GL_ARRAY_BUFFER, uint(0))
|
|
||||||
// t4 := glfw.get_time()
|
|
||||||
// Render quad
|
|
||||||
gl.draw_arrays(GL_TRIANGLES, 0, 6)
|
|
||||||
// t5 := glfw.get_time()
|
|
||||||
// # if (glfw__get_time() - t > 0.001)
|
|
||||||
// {
|
|
||||||
// # printf("do_text = %f '%s' \n", glfw__get_time() - t, text.str);
|
|
||||||
// # printf("t1=%f, t2=%f, t3=%f, t4=%f, t5=%f\n\n\n", t1-t, t2-t1, t3-t2, t4-t3, t5-t4);
|
|
||||||
// }
|
|
||||||
// Now advance cursors for next glyph (note that advance is number of 1/64 pixels)
|
|
||||||
// Bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels))
|
|
||||||
# x += (ch.advance >> 6) * 1;
|
|
||||||
}
|
|
||||||
gl.bind_vao(u32(0))
|
|
||||||
# glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
// runes.free()
|
|
||||||
// #free(runes.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (ctx &GG) draw_text_def(x, y int, text string) {
|
|
||||||
cfg := gx.TextCfg {
|
|
||||||
color: gx.Black,
|
|
||||||
size: DEFAULT_FONT_SIZE,
|
|
||||||
align: gx.ALIGN_LEFT,
|
|
||||||
}
|
|
||||||
ctx.draw_text(x, y, text, cfg)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update() {
|
fn update() {
|
||||||
|
|
|
@ -103,7 +103,7 @@ pub fn new_shader(name string) Shader {
|
||||||
}
|
}
|
||||||
vertex_path := '${dir}${name}.vert'
|
vertex_path := '${dir}${name}.vert'
|
||||||
fragment_path := '${dir}${name}.frag'
|
fragment_path := '${dir}${name}.frag'
|
||||||
println('shader path=$vertex_path,\n fpath="$fragment_path"')
|
//println('shader path=$vertex_path,\n fpath="$fragment_path"')
|
||||||
// vertex_src := os.read_file(vertex_path.trim_space())
|
// vertex_src := os.read_file(vertex_path.trim_space())
|
||||||
mut vertex_src := ''
|
mut vertex_src := ''
|
||||||
mut fragment_src := ''
|
mut fragment_src := ''
|
||||||
|
|
|
@ -19,12 +19,11 @@ import const (
|
||||||
GL_ARRAY_BUFFER
|
GL_ARRAY_BUFFER
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: windows support
|
#flag -I @VROOT/thirdparty/glad
|
||||||
#flag linux -I @VROOT/thirdparty/glad
|
|
||||||
#flag darwin -I @VROOT/thirdparty/glad
|
|
||||||
|
|
||||||
#include "glad.h"
|
#include "glad.h"
|
||||||
#include "glad.c"
|
#flag @VROOT/thirdparty/glad/glad.o
|
||||||
|
//#include "glad.c"
|
||||||
|
|
||||||
pub fn init_glad() {
|
pub fn init_glad() {
|
||||||
ok := C.gladLoadGL()
|
ok := C.gladLoadGL()
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
|
|
||||||
module glfw
|
module glfw
|
||||||
|
|
||||||
|
#flag -I @VROOT/thirdparty/glfw
|
||||||
|
|
||||||
|
#flag windows @VROOT/thirdparty/glfw/libglfw3.a
|
||||||
|
|
||||||
// Debugging a custom build
|
// Debugging a custom build
|
||||||
#flag darwin -L/var/tmp/glfw/src/
|
#flag darwin -L/var/tmp/glfw/src/
|
||||||
#flag darwin -lglfw
|
#flag darwin -lglfw
|
||||||
|
|
|
@ -117,7 +117,7 @@ fn (a Vec3) print() {
|
||||||
x := a.x
|
x := a.x
|
||||||
y := a.y
|
y := a.y
|
||||||
z := a.z
|
z := a.z
|
||||||
# printf("vec3{%f,%f,%f}\n",x,y,z);
|
C.printf('vec3{%f,%f,%f}\n',x,y,z)
|
||||||
// println('vec3{$x,$y,$z}')
|
// println('vec3{$x,$y,$z}')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ fn normalize(vec Vec3) Vec3 {
|
||||||
*/
|
*/
|
||||||
// https://github.com/g-truc/glm/blob/0ceb2b755fb155d593854aefe3e45d416ce153a4/glm/ext/matrix_clip_space.inl
|
// https://github.com/g-truc/glm/blob/0ceb2b755fb155d593854aefe3e45d416ce153a4/glm/ext/matrix_clip_space.inl
|
||||||
pub fn ortho(left, right, bottom, top f32) Mat4 {
|
pub fn ortho(left, right, bottom, top f32) Mat4 {
|
||||||
println('glm ortho($left, $right, $bottom, $top)')
|
//println('glm ortho($left, $right, $bottom, $top)')
|
||||||
// mat<4, 4, T, defaultp> Result(static_cast<T>(1));
|
// mat<4, 4, T, defaultp> Result(static_cast<T>(1));
|
||||||
n := 16
|
n := 16
|
||||||
mut res := f32_calloc(n)
|
mut res := f32_calloc(n)
|
||||||
|
|
|
@ -9,7 +9,8 @@ module json
|
||||||
#flag linux -I @VROOT/thirdparty/cJSON
|
#flag linux -I @VROOT/thirdparty/cJSON
|
||||||
#flag darwin -I @VROOT/thirdparty/cJSON
|
#flag darwin -I @VROOT/thirdparty/cJSON
|
||||||
|
|
||||||
// #include "cJSON.c"
|
#flag @VROOT/thirdparty/cJSON/cJSON.o
|
||||||
|
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
struct C.cJSON {
|
struct C.cJSON {
|
||||||
valueint int
|
valueint int
|
||||||
|
|
|
@ -615,7 +615,7 @@ pub fn ls(path string) []string {
|
||||||
}
|
}
|
||||||
$else {
|
$else {
|
||||||
mut res := []string
|
mut res := []string
|
||||||
dir := C.opendir(path.str)
|
dir := C.opendir(path.cstr())
|
||||||
if isnil(dir) {
|
if isnil(dir) {
|
||||||
println('ls() couldnt open dir "$path"')
|
println('ls() couldnt open dir "$path"')
|
||||||
print_c_errno()
|
print_c_errno()
|
||||||
|
|
|
@ -6,8 +6,7 @@ module stbi
|
||||||
|
|
||||||
import gl
|
import gl
|
||||||
|
|
||||||
#flag linux -I @VROOT/thirdparty/stb_image
|
#flag -I @VROOT/thirdparty/stb_image
|
||||||
#flag darwin -I @VROOT/thirdparty/stb_image
|
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include "stb_image.h"
|
#include "stb_image.h"
|
||||||
|
|
Loading…
Reference in New Issue