Skip to content

Instantly share code, notes, and snippets.

// x = vx*t
// y = vy*t - 0.5g*t^2
//
// vx = x/t
// vy = (y+0.5g*t^2)/t
//
// vx*vx + vy*vy = v0*v0
//
// v0*v0 = (x/t)^2 + ((y+0.5g*t^2)/t)^2
// v0*v0*t^2 = x^2 + (y+0.5g*t^2)^2

People who program in C
People who care about the C standard
People who have stakes in C compiler behavior, and sample opinions on UB (reflecting my bias):

// slightly concrete example of how something can change behavior if you switch between by-value and const-ref semantics,
// shown here using a hypothetical dialect of C/C++ with those semantics
// Changing between these two typedefs changes the semantics of the program, introducing a bug
typedef float ProfileTime; // works
//typedef double ProfileTime; // doesn't work
struct ProfileZone
{
#define STB_DEFINE
#include "stb.h"
int get_seconds(char *timestamp)
{
int sec;
struct tm t;
// sscanf was very slow
t.tm_year = atoi(timestamp+ 0);
#define STB_DEFINE
#include "stb.h"
int main(int argc, char **argv)
{
stb_sdict *d;
char *s;
void *a;
int len,i;
char **p = stb_stringfile("c:/x/lenovo_url.txt", &len);
#ifdef _WIN64
typedef unsigned __int64 STBP_UINTPTR;
#else
typedef unsigned int STBP_UINTPTR;
#endif
// WINUSERAPI => __declspec(import)
// WINAPI => __stdcall
// HDC,HGLRC,etc => void *
// LONG_PTR, INTPTR, LRESULT => ptrdiff_t
#ifdef STB_PLATFORM_NO_SIMD
// 97..125us to sum 2 seconds of sound in testbed
static void stbp_audio_add_wrapped_buffer(float *dest, int dest_offset, float *src, int num_aframes)
{
int i;
for (i=0; i < num_aframes; ++i) {
dest[dest_offset+0] += src[i*2+0];
dest[dest_offset+1] += src[i*2+1];
src[i*2+0] = 0; // also zero the source data here, it's faster than a separate memset
src[i*2+1] = 0;
@nothings
nothings / kotaku_hzd.md
Last active September 4, 2024 06:33
Why Frustum Culling Matters, and Why It's Not Important

There is a nice GIF illustrating a technique called "frustum culling" in this Kotaku article: http://kotaku.com/horizon-zero-dawn-uses-all-sorts-of-clever-tricks-to-lo-1794385026

The interwebs being what they are, this has also led to some controversy.

Some people have interpreted the opening sentence "Every time you move the camera in Horizon Zero Dawn, the game is doing all sorts of under-the-hood calculations, loading and unloading chunks of world to ensure that it all runs properly," as being about the GIF; that's not what frustum culling does, but that's probably not what the article's author meant anyway.

#define FOURCC(s) (((uint32)s[0]<<0) | ((uint32)s[1]<<8) | ((uint32)s[2]<<16) | ((uint32)s[3]<<24))
// this is not the public function, see following two functions after this one
static GLuint load_dds_bc_only_raw(GLuint tex, int slice, int total_slices, char *filename)
{
int target = slice < 0 ? GL_TEXTURE_2D : GL_TEXTURE_2D_ARRAY, i, mips;
GLenum fmt_for_bc[8] = { 0, 0x83F0, 0x83F2, 0x83F3, 0x8DBB, 0x8DBD, 0x8E8E, 0x8E8F };
int bytes_per_4x4block[8] = { 0, 8,16,16,8,16,16,16 };
uint32 width,height,flags,size,fourcc,depth,fflags,caps,caps2,dim=0;
int len, bc=0, fmt=1, intfmt;
// What I'm trying to do: store a 1-byte alpha texture:
GLenum swizzle[4] = { GL_ONE, GL_ONE, GL_ONE, GL_RED };
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width,height, 0, GL_RED, GL_UNSIGNED_BYTE, pixels);
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
// above draws (1,1,1,1)
// works as expected: storing to red channel of an RGBA texture and using swizzle into the alpha
GLenum swizzle[4] = { GL_ONE, GL_ONE, GL_ONE, GL_RED };
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width,height, 0, GL_RED, GL_UNSIGNED_BYTE, pixels);
// ^^^^^^^^