Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411423 Posts in 69363 Topics- by 58416 Members - Latest Member: JamesAGreen

April 19, 2024, 04:18:54 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)The grumpy old programmer room
Pages: 1 ... 283 284 [285] 286 287 ... 295
Print
Author Topic: The grumpy old programmer room  (Read 738220 times)
ThemsAllTook
Administrator
Level 10
******



View Profile WWW
« Reply #5680 on: January 25, 2019, 05:42:09 PM »

I did that exact task recently (word wrapping and CPU-side clipping), and found it quite enjoyable and not too hard. The actual word wrapping algorithm shouldn't need to intermingle with rendering code; it just needs to be able to measure the width of a string. Clipping can happen separately. My implementation allocates a buffer of wrap points, which can subsequently be used to split up the text for render calls, or height measurement, or getting a character index for a screen position.

If you're curious, my code is available here: http://ludobloom.com/svn/StemLibProjects/glbitmapfont/trunk/source/glbitmapfont/TextFlow.c
updateWrapInfo() is where the core of the word wrap algorithm lives. Hopefully it's friendly enough to read, in case you want to use it as a sanity check against whatever you end up implementing.
Logged

qMopey
Level 6
*


View Profile WWW
« Reply #5681 on: January 25, 2019, 09:35:37 PM »

Thanks! That was a nice reference. I thought it was quite interesting how your solution seems to cache wrap points.

I went for as little code as possible, and computed all wrap points and whatnot on-the-fly. I'm thinking if someone really wanted to cache out the word-wrapped and clipped string, they can cache the vertex buffer and call that good enough. But your solution can definitely be more efficient.

Seems to be all working now! Smiley


Here's the commit: https://github.com/RandyGaul/cute_headers/commit/30720c2ebf8ff7271aa8dbfb0b64a062472c85b0

Pretty happy with the code. My goal was to not add much code, and keep it really straightforward with minimal edge-cases. I'm especially happy with clipping, which is done as if calculating the intersection point of a one-dimensional plane, like so:

Code:
static inline float s_dist_to_plane(float v, float d)
{
    return v - d;
}

static inline float s_intersect(float a, float b, float u0, float u1, float plane_d)
{
    float da = s_dist_to_plane(a, plane_d);
    float db = s_dist_to_plane(b, plane_d);
    return u0 + (u1 - u0) * (da / (da - db));
}

a and b are input points, u0 and u1 are associated u or v coordinates for a and b respectively. plane_d is distance of the plane to the origin.

In 3D, to calculate the intersection point of a plane, it would look like:

da = distance(a, plane)
db = distance(b, plane)
intersect_point = a + (b - a) * (da / (da - db))

Where the distance function looks like:

Code:
float distance(v3 v, plane p)
{
    return dot(v, plane.point) - plane.distance;
}

In one axis-aligned dimension the dot product is just a number multiplied by 1.0, so it can be removed, leaving just the subtraction of the point with the plane's distance from the origin.

I actually have done this kind of one-dimensional AABB clipping in an open-source physics engine before, here at this code. I find it good to think of plane equations, even in a single dimension.
« Last Edit: January 25, 2019, 09:52:59 PM by qMopey » Logged
Ordnas
Level 10
*****



View Profile WWW
« Reply #5682 on: January 27, 2019, 02:58:56 AM »

Very cool qMopey!  Grin Just to nitpicking a bit, what about passing params by reference? (in the case of the v3 and plane classe in the distance function above, just to avoid to call again the constructor).

Also what you think about the function s_intersect to take as a params a struct instead of 5 params? Just to avoid to add 5 params in a row every time (even if I am just seeing right now that it is used in the function cute_font_fill_vertex_buffer, and create every time a struct in every branch of inside_clip_x_axis can be tricky).
Logged

Games:

qMopey
Level 6
*


View Profile WWW
« Reply #5683 on: January 27, 2019, 12:49:26 PM »

Thanks Ordnas!

5 Things. 1) The compiler will in-line and completely compile the functions away. 2) Most of the time math primitives will already be loaded into a register, and will be “passed by register”. This is getting very common since in 64bit builds wide registers and SIMD are used by default. 3) Passing by pointers or references causes a lot of pointer aliasing and inadvertent cache misses (these are both performance problems). 4) Less typing. 5) Older compiler versions used to have a lot of trouble optimizing SIMD code if math types were not passed by value. So this is a habit I have learned.

So in reality those structures will not be copied around extra times, and the same goes for the extra parameters.

Personally I consider passing by value the “default”, and only upgrade to a pointer if the structure is more than a tiny math primitive. Also I don’t use references because I think they make code harder to read.
« Last Edit: January 27, 2019, 12:57:07 PM by qMopey » Logged
Raptor85
Level 5
*****



View Profile WWW
« Reply #5684 on: January 27, 2019, 05:37:25 PM »

So, I think this qualifies me as grumpy and old.

I finished writing a few test vulkan applications, Don't get me wrong, vulkan is FANTASTIC, but man is it a lot of work to do the simple things, it does make more complicated things a lot easier though.  I'm so burnt out on command queues and the like though...seems like with every modern API you need like 1000 lines of glue code just to get a graphics context, and drawing a box on the screen need multiple shaders, vertex buffers, etc...After working with vulkan for a bit I started to REALLY miss the older style drawing api's, so....

I just spent the last few weeks writing helper libs, a custom cross-platform window management lib (Right now supports XCB/Xlib/Wayland/Win32, OSX support planned), a framebuffer library with custom software raster functions and raw "backbuffer" access, a file management lib to properly load resources and save config to the proper places per platform specs, even a working raw input lib with it that does direct device polling instead of using the OS's event system. (Right now linux only, havn't figured out how to do it in windows yet)

Still need to make a sound library, but kinda tossing around the idea of making a software raytracer just for shits-n-giggles as well

TLDR: Got frustrated with how complicated vulkan and other modern libs were so wrote an entire cross platform windowing/framebuffer/raster/input system that lets me write programs with simplier, older style fixed function/direct rendering calls.
Logged

-Fuzzy Spider
qMopey
Level 6
*


View Profile WWW
« Reply #5685 on: January 27, 2019, 05:55:18 PM »

I’m never going to use newer graphics APIs. They are over engineered, and don’t personally provide me with any benefits. I will pay someone else to port my own graphics API if the necessity arises. I won’t waste my life on that stuff. You are brave for diving into that tangled mess!

/rant
« Last Edit: January 27, 2019, 06:01:08 PM by qMopey » Logged
Raptor85
Level 5
*****



View Profile WWW
« Reply #5686 on: January 27, 2019, 06:44:15 PM »

I’m never going to use newer graphics APIs. They are over engineered, and don’t personally provide me with any benefits. I will pay someone else to port my own graphics API if the necessity arises. I won’t waste my life on that stuff. You are brave for diving into that tangled mess!

/rant
I mean, if you intend to do something complicated in 3d Vulkan really does make things a LOT simpler, it's literally direct access to the hardware as it works, so if you're doing all sorts of advanced rendering features, high quality art needing a lot of instancing to reduce draw calls, etc, vulkan makes a lot of sense.  Both vulkan and modern opengl both have the same annoying quality though that when you want to do something SIMPLE (like...drawing a rectangle) you still have to do all the setup, querying devices, creating buffers, etc...     I normally turn to SDL/SDL2 for less advanced things but there's some things I've always kinda hated about SDL, for one I never use 90% of the lib but still need to pull in a ton of dependencies for it, aside from creating a window and getting a GL context I've just never had much use for the rest of it's functionality.  All my helper libs are being written with the old unix philosophy of "do one thing and do it well", so they're all completely independent of each other, and I'm designing them to by default cover the "common" use cases without extra work. For instance, unless you explicitly tell it otherwise the window will start up in "borderless fullscreen" mode at the desktop's current resolution of whatever you have set as your default monitor, and obeys all normal keyboard commands (alt+enter toggles "fullscreen", ctrl+g toggles mouse grab, alt+f4 aborts), as well as handling common window events (resizing, etc) as I was tired of writing handlers for all that crap in every single program I wrote...sometimes I just want a damned window.

Code:
#include "sgtwin/include/Window.h"

int main()
{
    sgt::Window* window = sgt::Window::Create("test",false, sgt::MONITOR_DEFAULT);
    if(window == nullptr)
        return -1;

    while(window->ProcessEvents())
    {
    }

    delete(window);
    return 0;
}

Also <rant>
The documentation on every single windowing system besides xlib is complete ass, half the functions are either undocumented or have changed since they were last documented, Bonus when there's conflicting versions of the documentation with completely different descriptions of how functions work and no version numbers attached to them.</rant>
Logged

-Fuzzy Spider
Crimsontide
Level 5
*****


View Profile
« Reply #5687 on: January 27, 2019, 10:04:04 PM »

Yeah I understand the Vulkan rant.  I love it, 90% of it makes perfect sense and runs beautifully.  But that last 10%...

Hard stuff becomes so simple, but simple stuff becomes so hard.  And its not even stuff they couldn't fix, that last 10% could be cleaned up, but there seems to be this idea that 'Vulkan is supposed to be hard' in all the forums, so any suggestions are just blown off as 'you're not smart enough'.  I think that bothers me the most about it, the Reddit, Khronos, and Github forums are just useless.  Instead of keeping things nice and clean, its just more features and extensions packed on, they're determined to make this OpenGL all over again.
Logged
qMopey
Level 6
*


View Profile WWW
« Reply #5688 on: January 27, 2019, 10:25:51 PM »

Thing is for my own game I'm just doing 2D image rendering, and write really basic shaders whenever a sort of special effect is needed. For example, last one I wrote was a sprite outline shader. It can stroke the border of any sprite with a one-pixel border, and optionally strokes around corners as well.

For a lot of people just drawing images is good enough.

Plus people don't really buy the game with the best graphics. League of Legends is a prime example. So is Undertale. To me I feel like all newer graphics APIs are just big wastes of my time, coming from the perspective of making money on a 2D game. Even to the point of not upgrading beyond DirectX 9. Thing with d3d9 is it will run on Windows XP, and many people in Russia/China still run on XP. Even a good chunk of people in Korea still run XP. The old APIs aren't broken, and all the newer graphics APIs feels like "forced progress".

And then there's the topic of 3D graphics engines in big companies. I've worked on a variety of large AAA engines and my personal experience is every single one of them is that the graphics areas of the engine are the absolute most over-engineered. Loading animations from a file, for example, is not a very complicated process. And yet all the big tech completely obfuscates the process of loading 3D animation data behind a multi-layered abstraction wall for no *real* reason. Seems like the whole graphics community in general likes to over-engineer their creations because they enjoy technology more than they enjoy actually making a product, or something useful.
« Last Edit: January 27, 2019, 10:35:20 PM by qMopey » Logged
Crimsontide
Level 5
*****


View Profile
« Reply #5689 on: January 28, 2019, 01:11:37 PM »

Quote
And then there's the topic of 3D graphics engines in big companies. I've worked on a variety of large AAA engines and my personal experience is every single one of them is that the graphics areas of the engine are the absolute most over-engineered. Loading animations from a file, for example, is not a very complicated process. And yet all the big tech completely obfuscates the process of loading 3D animation data behind a multi-layered abstraction wall for no *real* reason. Seems like the whole graphics community in general likes to over-engineer their creations because they enjoy technology more than they enjoy actually making a product, or something useful.

This I completely agree with.  I've had a few arguments with 'professional' game devs on GameDev.net over stupidly simple stuff, and man do they get ugly.  Its why I stopped visiting there.  I remember one issue where there was an argument over the correct way to pass flags to a function (C++).  I suggested an enumeration with a few overloaded bit operators.  Simple, safe, as fast as possible.  You'd think I'd suggested sacrificing a goat or something, they went bonkers.  Enums are not meant for that, its non-standard, no one does it, blah blah blah...  Despite showing where in the spec it stated it was safe, systematically correcting all the incorrect accusations, even linking to qutoes from Bjarne himself over enum used for flags and where he used them; they still refused to even admit that it was a viable option...

Yeah... I feel ya.  There's too many smart idiots in programming.  Its why I love Tigsource.  We can disagree, do things completely differently, and no one loses their mind.  Some people on here love C and hate C++ as being too complex, others the opposite.  We can disagree, and still be civil.

That said, I find Vulkan (for the most part) to be very simple at its core.  Once you get your device up and running (and that is probably the most complex part of the system, I kid you not) I found it to be, for the most part, pretty straight forward.  I like manually managing pipelines and command buffers (no guessing, just do this and its done).  Semaphores, fences, make a lot of sense, and while they are explained very poorly in the spec, work stupidly easy.  Memory management is actually quite empowering.  But you really need framework to handle the little things.  At its core, its one of the best APIs I've ever seen.  Its clear that since the core was written that others have messed up what was otherwise a clean and elegant API, I'm hoping it doesn't deviate too far...
Logged
ProgramGamer
Administrator
Level 10
******


aka Mireille


View Profile
« Reply #5690 on: January 28, 2019, 02:07:49 PM »

Meanwhile I plan on using OpenGL ES 1.2 for compatibility with the 3DS...

Also, I want to know what kind of whack C++ programmer refuses to use enums for flags.
Logged

qMopey
Level 6
*


View Profile WWW
« Reply #5691 on: January 28, 2019, 02:22:59 PM »

Lots of people in the professional game industry absolutely love to create abstractions for things like bitmasks. Another super common one is arrays. I’ve had code revieews flat out denied because I used an array represented as a pointer and integer pair, instead of a std::vector. My reasoning was to reduce header dependencies, and avoid pulling in unnecessary templates, all to help compile time (our #1 customer complaint was our compiling times, and loading times). There are lots of people who flat out refuse to use pointers, and anything “bare” is considered “hacks”. Basically it’s all anti-C style at many places. It’s a cult of style.
Logged
Ordnas
Level 10
*****



View Profile WWW
« Reply #5692 on: January 29, 2019, 01:38:13 AM »

I think this trend is the preferred one because it is the safest one if you need to work with a team of a lot of people. Things break in a daily basis, even for the stupidest things, and offloading some things from the developer (like memory deallocation and structures implementations to say a few) can avoids to waste time on tracking nasty bugs. Even if you lose performance in doing that. Of course, from a very skilled perspective is something annoying, but from an industry perspective embracing the widest range possible of developers, from junior to senior, creates more productivity.
Logged

Games:

qMopey
Level 6
*


View Profile WWW
« Reply #5693 on: January 29, 2019, 03:24:47 AM »

I think you’re right about their intentions Ordnas. But, it doesn’t work. That strategy does not scale, and everyone starts getting their productivity locked. Microsoft, in my opinion, has a way better strategy: make many weaker developers use C#. This is their “safer” C++, except it actually works better because the design of the language, from the ground up, is fairly clear and coherent.

Personally I think the best strategy is to stick with only the best of engineers and keep the team very small. If the project “needs more manpower”, then I personally think this is a sign of incompetent management who are simply bad at efficient resource allocation. The big machine of “safe” C++ locks developer productivity within a small range, and completely squashes out the ability for competent employees to meet their potential. At some employers I am thousands of times more productive than myself at other employers simply because I don’t have to abide by a methodology and have freedom to solve whatever technical problem gets in my way in an efficient manner.

My take is that over-engineering and “safe C++” go hand-in-hand, and are simply manifestations of people-problems on the realm of technology. People-problems, born of incompetence, start oozing into the code and are expressed there as a poor attempt to recast a non-technical socio-hierarchical problem as a technologically solvable problem. Which is inane.
« Last Edit: January 29, 2019, 03:43:07 AM by qMopey » Logged
qMopey
Level 6
*


View Profile WWW
« Reply #5694 on: January 29, 2019, 03:36:34 AM »

I have an example. The one I always see is “I want to make a version of X that other developers can use to do Y. My version will be better, because it will be a generic solution capable of very powerfully and flexibly solving all use-cases.”

To me this kind of thinking is a people problem manifested as a technological problem. The people problem is: no sense of direction, no focused goal, and no discipline. If I translate the original mandate into plain speak, it would really say: “I want to waste time creating a useless technology that doesn’t solve any specifics problem, and I want to have fun doing it. At the end of the day, whoever uses my technology will have to solve the real problem, and I would have successfully avoided any real work, and instead will focus on my masturbatory and pointless product.” Unfortunately software can not be written without specific problem context, and it can’t be written efficiently with very many people actively participating.

And then incompetent management will greenlight projects like these that last for anywhere from 2-10 years, wasting many millions of dollars. When things go awry and deadlines can not be meet, teams ask for “more manpower”. And the whole flaming ship eventually burns itself into the sea.

People problems are *not* tech problems, and can *not* be solved by tech. “Safe C++” is, to me at least, and sign of massive people problems in the leadership which have oozed into code where they will never be solved.
Logged
Raptor85
Level 5
*****



View Profile WWW
« Reply #5695 on: January 29, 2019, 04:34:28 AM »

I mean, it's really what you get when the colleges teach nothing but Java for years and suddenly all these new people get dumped into the industry working in languages like C++ and immediately apply java best practices to it.  It's why you see such rampant misuse of inheritance and unnecessary overuse of STL/Boost.  Now that's not saying STL and Boost are useless, far from so.  When dealing with large quantities of strings, associative lists,  etc in non-realtime situations often std::vector and std::map ARE the right thing to use.  When you start seeing things like catchall exception handlers and GC'd memory management in performance critical code sections though...well, there's a reason so many games run like absolute ass on modern hardware while not looking much better than a PS2 game, and often having fewer gameplay features... which is impressive when you consider that all the harder to process calculations get executed directly on the video hardware now.  The amount of processing power in a modern computer is INCREDIBLE, but the bloat has grown so exponential in the past 15 years most software BARELY accomplishes more than was possible on a P3.  Network code in particular is SO much worse than it was, indies in particular are terrible about basically not giving a flying fuck about minimizing bandwidth use, packet size, replaying states on lost connections, etc...which is why so many games lag MORE on a 40Mbit connection with 28ms ping than shit used to on 56k w/ 150ms ping.  Not really helped by the fact that a lot of modern games execute AUTHORITATIVE code on all clients and sync everything with the server, so there's a lot of duplicated data being sent across, which is also why cheating is so ridiculously easy and so many ridiculous things can be hacked in on so many of these games.  Then to "fix" the cheating instead of properly designing the game, bandage solutions like EasyAC and BattleEye get pushed on top causing even MORE lag and burning up more resources.

Other industries aren't any better either, it's REALLY fun when you get tasked to add new features to some web service and whoever wrote it used whatever the current flavor of the month framework is, bonus if it's VB based and starts with "on error resume next" or C# with the main loop wrapped in while(true) and a try/catch with a blank catch (essentially just suppressing all error messages and restarting on any error), which is WAY more commonly used than people would like to believe.  Instead of learning to do things properly the "standard" these days seems to be just suppress all error messages, leak memory like crazy, and hope the GC does a good enough job keeping the computer from exploding.
Logged

-Fuzzy Spider
Ordnas
Level 10
*****



View Profile WWW
« Reply #5696 on: February 02, 2019, 01:03:59 AM »

I like this idea about abstractions as a way to absolve the lack of programmer knowledge of the machine and consequently a lack of skills, but what are the alternatives? C# is a good choice, but if engines and tools (check Unreal) are using C++, then you should expect technical artists and designers using C++ as it would be a scripting language in extreme cases (I noticed in my career C++ used as it was Java or even worse as it was Python).
 
« Last Edit: February 02, 2019, 01:15:18 AM by Ordnas » Logged

Games:

InfiniteStateMachine
Level 10
*****



View Profile
« Reply #5697 on: February 02, 2019, 07:03:42 AM »

My reasoning was to reduce header dependencies, and avoid pulling in unnecessary templates, all to help compile time (our #1 customer complaint was our compiling times, and loading times).

Thank you. People tend to forget about compile time and bad build times are brutal.
Logged

Daid
Level 3
***



View Profile
« Reply #5698 on: February 02, 2019, 12:16:33 PM »

Also, I want to know what kind of whack C++ programmer refuses to use enums for flags.
Unless you need some kind of ABI stability, bitfields in structs are in certain cases a much better solution:
https://en.cppreference.com/w/cpp/language/bit_field
Logged

Software engineer by trade. Game development by hobby.
The Tribute Of Legends Devlog Co-op zelda.
EmptyEpsilon Free Co-op multiplayer spaceship simulator
ProgramGamer
Administrator
Level 10
******


aka Mireille


View Profile
« Reply #5699 on: February 02, 2019, 12:19:59 PM »

Huh, I'd never heard of bitfields before. Thanks for the link!
Logged

Pages: 1 ... 283 284 [285] 286 287 ... 295
Print
Jump to:  

Theme orange-lt created by panic