├── VisualStudio2012 ├── dx_test │ ├── stdafx.cpp │ ├── stdafx.h │ ├── targetver.h │ ├── dx_test.vcxproj.filters │ ├── dx_test.vcxproj │ └── dx_test.cpp ├── gl_test │ ├── gl_test.vcxproj.filters │ └── gl_test.vcxproj ├── fpf_test │ ├── fpf_test.vcxproj.filters │ └── fpf_test.vcxproj └── fpf_test.sln ├── XCode ├── fpf_test │ ├── en.lproj │ │ └── InfoPlist.strings │ └── fpf_test-Info.plist └── fpf_test.xcodeproj │ ├── project.xcworkspace │ └── contents.xcworkspacedata │ └── project.pbxproj ├── images ├── fpf_texture_atlas_6x_size.png └── fpf_texture_atlas_full_size.png ├── LICENSE ├── test ├── fpf_test.c └── gl_test.c ├── README.md └── five_pixel_font.h /VisualStudio2012/dx_test/stdafx.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | -------------------------------------------------------------------------------- /XCode/fpf_test/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /images/fpf_texture_atlas_6x_size.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChrisG0x20/five-pixel-font/HEAD/images/fpf_texture_atlas_6x_size.png -------------------------------------------------------------------------------- /images/fpf_texture_atlas_full_size.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChrisG0x20/five-pixel-font/HEAD/images/fpf_texture_atlas_full_size.png -------------------------------------------------------------------------------- /XCode/fpf_test.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /VisualStudio2012/dx_test/stdafx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "targetver.h" 4 | 5 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 6 | // Windows Header Files: 7 | #include 8 | #include 9 | 10 | #include 11 | -------------------------------------------------------------------------------- /VisualStudio2012/dx_test/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /XCode/fpf_test/fpf_test-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.fpf.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /VisualStudio2012/gl_test/gl_test.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | 23 | 24 | Source Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /VisualStudio2012/fpf_test/fpf_test.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /VisualStudio2012/dx_test/dx_test.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /VisualStudio2012/fpf_test.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fpf_test", "fpf_test\fpf_test.vcxproj", "{CCE02F26-6635-4DB6-B7C7-924F775D82A2}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gl_test", "gl_test\gl_test.vcxproj", "{DB7D9D87-3CAB-4FDB-8F0C-9B14418B70A5}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dx_test", "dx_test\dx_test.vcxproj", "{BFF89764-370F-4F6C-8956-661FD8088625}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Win32 = Debug|Win32 13 | Release|Win32 = Release|Win32 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {CCE02F26-6635-4DB6-B7C7-924F775D82A2}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {CCE02F26-6635-4DB6-B7C7-924F775D82A2}.Debug|Win32.Build.0 = Debug|Win32 18 | {CCE02F26-6635-4DB6-B7C7-924F775D82A2}.Release|Win32.ActiveCfg = Release|Win32 19 | {CCE02F26-6635-4DB6-B7C7-924F775D82A2}.Release|Win32.Build.0 = Release|Win32 20 | {DB7D9D87-3CAB-4FDB-8F0C-9B14418B70A5}.Debug|Win32.ActiveCfg = Debug|Win32 21 | {DB7D9D87-3CAB-4FDB-8F0C-9B14418B70A5}.Debug|Win32.Build.0 = Debug|Win32 22 | {DB7D9D87-3CAB-4FDB-8F0C-9B14418B70A5}.Release|Win32.ActiveCfg = Release|Win32 23 | {DB7D9D87-3CAB-4FDB-8F0C-9B14418B70A5}.Release|Win32.Build.0 = Release|Win32 24 | {BFF89764-370F-4F6C-8956-661FD8088625}.Debug|Win32.ActiveCfg = Debug|Win32 25 | {BFF89764-370F-4F6C-8956-661FD8088625}.Debug|Win32.Build.0 = Debug|Win32 26 | {BFF89764-370F-4F6C-8956-661FD8088625}.Release|Win32.ActiveCfg = Release|Win32 27 | {BFF89764-370F-4F6C-8956-661FD8088625}.Release|Win32.Build.0 = Release|Win32 28 | EndGlobalSection 29 | GlobalSection(SolutionProperties) = preSolution 30 | HideSolutionNode = FALSE 31 | EndGlobalSection 32 | EndGlobal 33 | -------------------------------------------------------------------------------- /test/fpf_test.c: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // Example program showing use of the five-pixel-font library. 3 | // by Chris Gassib 4 | // ----------------------------------------------------------------------- 5 | // This is free and unencumbered software released into the public domain. 6 | // 7 | // Anyone is free to copy, modify, publish, use, compile, sell, or 8 | // distribute this software, either in source code form or as a compiled 9 | // binary, for any purpose, commercial or non-commercial, and by any 10 | // means. 11 | // 12 | // In jurisdictions that recognize copyright laws, the author or authors 13 | // of this software dedicate any and all copyright interest in the 14 | // software to the public domain. We make this dedication for the benefit 15 | // of the public at large and to the detriment of our heirs and 16 | // successors. We intend this dedication to be an overt act of 17 | // relinquishment in perpetuity of all present and future rights to this 18 | // software under copyright law. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 24 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | // OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | // For more information, please refer to 29 | 30 | #include 31 | #define FPF_IMPLEMENTATION 32 | #include "five_pixel_font.h" 33 | 34 | const size_t line_pitch = 75; 35 | const size_t alpha_texture_size = FPF_TEXTURE_HEIGHT * line_pitch; 36 | unsigned char alpha_texture[alpha_texture_size]; 37 | 38 | int main(int argc, char* argv[]) 39 | { 40 | (void)(argc); 41 | (void)(argv); 42 | 43 | memset(alpha_texture, 0xcc, alpha_texture_size); 44 | 45 | size_t result = fpf_create_alpha_texture( 46 | alpha_texture, 47 | alpha_texture_size, 48 | line_pitch, 49 | FPF_RASTER_Y_AXIS // FPF_VECTOR_Y_AXIS 50 | ); 51 | 52 | #ifdef WIN32 53 | printf("create texture result = %ld\n", result); 54 | #else 55 | printf("create texture result = %zd\n", result); 56 | #endif 57 | 58 | if (0 != result) 59 | { 60 | printf("failed to create texture atlas"); 61 | return 1; 62 | } 63 | 64 | unsigned int x; 65 | unsigned int y; 66 | for (y = 0; y < FPF_TEXTURE_HEIGHT; ++y) 67 | { 68 | putchar('['); 69 | for (x = 0; x < line_pitch; ++x) 70 | { 71 | const unsigned char texel = alpha_texture[y * line_pitch + x]; 72 | if (0xff == texel) 73 | { 74 | putchar('#'); 75 | } 76 | else if (0x00 == texel) 77 | { 78 | putchar(' '); 79 | } 80 | else 81 | { 82 | putchar('~'); 83 | } 84 | } 85 | putchar(']'); 86 | putchar('\n'); 87 | } 88 | 89 | fpf_get_glyph_position('A', &x, &y); 90 | 91 | for (unsigned int k = y; k < y + 6; ++k) 92 | { 93 | for (unsigned int j = x; j < x + 6; ++j) 94 | { 95 | if (alpha_texture[k * line_pitch + j]) 96 | { 97 | putchar('#'); 98 | } 99 | else 100 | { 101 | putchar(' '); 102 | } 103 | } 104 | putchar('\n'); 105 | } 106 | 107 | float left, top, right, bottom; 108 | fpf_get_glyph_gl_texture_coordinates(' ', &left, &top, &right, &bottom); 109 | printf("[%f, %f] [%f, %f]\n", left, top, right, bottom); 110 | 111 | fpf_get_glyph_gl_texture_coordinates('~' + 1, &left, &top, &right, &bottom); 112 | printf("[%f, %f] [%f, %f]\n", left, top, right, bottom); 113 | 114 | return 0; 115 | } 116 | -------------------------------------------------------------------------------- /VisualStudio2012/fpf_test/fpf_test.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {CCE02F26-6635-4DB6-B7C7-924F775D82A2} 15 | Win32Proj 16 | fpf_test 17 | 18 | 19 | 20 | Application 21 | true 22 | v110 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | v110 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | true 45 | 46 | 47 | false 48 | true 49 | 50 | 51 | 52 | 53 | 54 | Level4 55 | Disabled 56 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 57 | true 58 | true 59 | CompileAsCpp 60 | $(SolutionDir)..\; 61 | 62 | 63 | Console 64 | true 65 | 66 | 67 | 68 | 69 | Level4 70 | 71 | 72 | MaxSpeed 73 | true 74 | true 75 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 76 | true 77 | true 78 | CompileAsCpp 79 | $(SolutionDir)..\; 80 | 81 | 82 | Console 83 | true 84 | true 85 | true 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /VisualStudio2012/gl_test/gl_test.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {DB7D9D87-3CAB-4FDB-8F0C-9B14418B70A5} 15 | Win32Proj 16 | gl_test 17 | 18 | 19 | 20 | Application 21 | true 22 | v110 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | v110 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | true 45 | 46 | 47 | false 48 | true 49 | 50 | 51 | 52 | Level4 53 | Disabled 54 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 55 | true 56 | $(SolutionDir)..\;$(SolutionDir)..\..\glfw-3.0.1.bin.WIN32\include\ 57 | true 58 | true 59 | 60 | 61 | Console 62 | true 63 | $(SolutionDir)..\..\glfw-3.0.1.bin.WIN32\lib-msvc110\ 64 | glfw3dll.lib;opengl32.lib;%(AdditionalDependencies) 65 | 66 | 67 | 68 | 69 | Level4 70 | MaxSpeed 71 | true 72 | true 73 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 74 | true 75 | $(SolutionDir)..\;$(SolutionDir)..\..\glfw-3.0.1.bin.WIN32\include\ 76 | true 77 | true 78 | NoListing 79 | 80 | 81 | Console 82 | true 83 | true 84 | true 85 | $(SolutionDir)..\..\glfw-3.0.1.bin.WIN32\lib-msvc110\ 86 | glfw3dll.lib;opengl32.lib;%(AdditionalDependencies) 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /VisualStudio2012/dx_test/dx_test.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {BFF89764-370F-4F6C-8956-661FD8088625} 15 | Win32Proj 16 | dx_test 17 | 18 | 19 | 20 | Application 21 | true 22 | v110 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | v110 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | true 45 | 46 | 47 | false 48 | true 49 | 50 | 51 | 52 | Use 53 | Level4 54 | Disabled 55 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 56 | true 57 | true 58 | true 59 | $(SolutionDir)..\; 60 | 61 | 62 | Windows 63 | true 64 | d3d9.lib;%(AdditionalDependencies) 65 | 66 | 67 | 68 | 69 | Level4 70 | Use 71 | MaxSpeed 72 | true 73 | true 74 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 75 | true 76 | true 77 | true 78 | $(SolutionDir)..\; 79 | 80 | 81 | Windows 82 | true 83 | true 84 | true 85 | d3d9.lib;%(AdditionalDependencies) 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | Create 97 | Create 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /test/gl_test.c: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // five-pixel-font library 3 | // by Chris Gassib 4 | // ----------------------------------------------------------------------- 5 | // This is free and unencumbered software released into the public domain. 6 | // 7 | // Anyone is free to copy, modify, publish, use, compile, sell, or 8 | // distribute this software, either in source code form or as a compiled 9 | // binary, for any purpose, commercial or non-commercial, and by any 10 | // means. 11 | // 12 | // In jurisdictions that recognize copyright laws, the author or authors 13 | // of this software dedicate any and all copyright interest in the 14 | // software to the public domain. We make this dedication for the benefit 15 | // of the public at large and to the detriment of our heirs and 16 | // successors. We intend this dedication to be an overt act of 17 | // relinquishment in perpetuity of all present and future rights to this 18 | // software under copyright law. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 24 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | // OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | // For more information, please refer to 29 | // 30 | 31 | #ifdef WIN32 32 | #define WIN32_LEAN_AND_MEAN 33 | #include 34 | #define MySleep Sleep 35 | #else 36 | #include 37 | #define MySleep(ms) usleep(ms * 1000u) 38 | #endif 39 | 40 | #include 41 | 42 | #define FPF_IMPLEMENTATION 43 | #include "five_pixel_font.h" 44 | 45 | int main(int argc, char* argv[]) 46 | { 47 | GLFWwindow* window; 48 | 49 | GLuint texture_name; 50 | 51 | float left; 52 | float top; 53 | float right; 54 | float bottom; 55 | 56 | char ch = ' '; 57 | 58 | const GLfloat billboard_verts[] = 59 | { 60 | -1.0f, -1.0f, 61 | 1.0f, -1.0f, 62 | -1.0f, 1.0f, 63 | 1.0f, 1.0f 64 | }; 65 | 66 | GLfloat texture_coords[] = 67 | { 68 | 0.0f, 0.0f, // DEBUG: Useful for seeing the whole texture. 69 | 1.0f, 0.0f, 70 | 0.0f, 1.0f, 71 | 1.0f, 1.0f 72 | }; 73 | 74 | unsigned char alpha_texture[FPF_TEXTURE_WIDTH * FPF_TEXTURE_HEIGHT]; 75 | 76 | (void)(argc); 77 | (void)(argv); 78 | 79 | /* Initialize the library */ 80 | if (!glfwInit()) 81 | return -1; 82 | 83 | /* Create a windowed mode window and its OpenGL context */ 84 | window = glfwCreateWindow(640, 640, "Hello World", NULL, NULL); 85 | if (!window) 86 | { 87 | glfwTerminate(); 88 | return -1; 89 | } 90 | 91 | /* Make the window's context current */ 92 | glfwMakeContextCurrent(window); 93 | 94 | glViewport(0, 0, 640, 640); 95 | glMatrixMode(GL_PROJECTION); 96 | glLoadIdentity(); 97 | //glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 100.0f); 98 | glFrustum(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 100.0f); 99 | glMatrixMode(GL_MODELVIEW); 100 | glLoadIdentity(); 101 | glTranslatef(0.0f, 0.0f, -1.0f); 102 | 103 | fpf_create_alpha_texture( 104 | alpha_texture, 105 | FPF_TEXTURE_WIDTH * FPF_TEXTURE_HEIGHT, 106 | FPF_TEXTURE_WIDTH, 107 | FPF_VECTOR_Y_AXIS 108 | ); 109 | 110 | glGenTextures(1, &texture_name); 111 | glBindTexture(GL_TEXTURE_2D, texture_name); 112 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 113 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 114 | glTexImage2D( 115 | GL_TEXTURE_2D, 116 | 0, 117 | GL_ALPHA, 118 | FPF_TEXTURE_WIDTH, 119 | FPF_TEXTURE_HEIGHT, 120 | 0, 121 | GL_ALPHA, 122 | GL_UNSIGNED_BYTE, 123 | alpha_texture 124 | ); 125 | 126 | glShadeModel(GL_SMOOTH); 127 | 128 | glEnable(GL_BLEND); 129 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 130 | 131 | glEnable(GL_TEXTURE_2D); 132 | //glActiveTexture(GL_TEXTURE0); 133 | 134 | glColor4f(0.0f, 1.0f, 0.0f, 1.0f); 135 | 136 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); 137 | glEnableClientState(GL_VERTEX_ARRAY); 138 | 139 | //fpf_get_cursor_glyph_gl_texture_coordinates(FPF_UNDERLINE_CURSOR, &left, &top, &right, &bottom); 140 | 141 | /* Loop until the user closes the window */ 142 | while (!glfwWindowShouldClose(window)) 143 | { 144 | /* Render here */ 145 | glClearColor(0.2f, 0.2f, 0.2f, 0.0f); 146 | glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 147 | 148 | //fpf_get_glyph_gl_texture_coordinates('~' + 1, &left, &top, &right, &bottom); 149 | fpf_get_glyph_gl_texture_coordinates(ch++, &left, &top, &right, &bottom); 150 | if (ch > '~') 151 | { 152 | ch = ' '; 153 | } 154 | 155 | texture_coords[0] = left; texture_coords[1] = bottom; 156 | texture_coords[2] = right; texture_coords[3] = bottom; 157 | texture_coords[4] = left; texture_coords[5] = top; 158 | texture_coords[6] = right; texture_coords[7] = top; 159 | 160 | glTexCoordPointer(2, GL_FLOAT, 0, texture_coords); 161 | glVertexPointer(2, GL_FLOAT, 0, billboard_verts); 162 | 163 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 164 | 165 | // Relax guy... take it easy. 166 | MySleep(250); 167 | 168 | /* Swap front and back buffers */ 169 | glfwSwapBuffers(window); 170 | 171 | /* Poll for and process events */ 172 | glfwPollEvents(); 173 | } 174 | 175 | glfwTerminate(); 176 | 177 | return 0; 178 | } 179 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Five-Pixel-Font Library 2 | ======================= 3 | 4 | This is a header-only library in pure C. It contains a whole ASCII font inside a single header file. It's handy for debugging since it doesn't require loading any external font resources. Also, it can be used to quickly add text output to a new graphics engine before putting in the effort for TrueType or custom font rendering. Finally, since the font was originally designed for MCGA mode graphics (320x200) it works on very small displays. 5 | 6 | The library creates a texture atlas of font glyphs in a client buffer. The texture atlas is a single channel (8-bit) alpha texture. The client application then uses the library to calculate texture coordinates for individual glyphs while rendering text. 7 | 8 | The library itself contains around 430 bytes of font data. The texture atlas created by the library is a single channel (8-bit) 64x64 texture which works out to use 4KB of video memory. 9 | 10 | Each glyph is 5x5 texels. However, there is a space on the right and bottom of each glyph so that they can be rendered into 6x6 pixel character cells without worrying about kerning. So it works like this: render a character, then advance six pixels and render the next character. 11 | 12 | What the font (and texture atlas) looks like: 13 | 14 | ![The Font's Texture Atlas](images/fpf_texture_atlas_full_size.png) 15 | 16 | And at 6x size: 17 | 18 | ![The Font's Texture Atlas 6x Size](images/fpf_texture_atlas_6x_size.png) 19 | 20 | Portability 21 | ----------- 22 | 23 | There's nothing particularly platform specific about the library. However, the scope of testing has been limited. It's been tested with Microsoft Visual C v11.0 and Clang v3.2 (OS X). By default it includes `` (for `memset()`) and ``. The defaults can be overridden. 24 | 25 | Including the Library 26 | --------------------- 27 | 28 | The header file (`"five_pixel_font.h"`) may be included in multiple source files. However, `FPF_IMPLEMENTATION` should be defined in a single source file before including `"five_pixel_font.h"`. Defining `FPF_IMPLEMENTATION` causes the library code to be expanded in that translation unit. For example: 29 | 30 | ```C 31 | #define FPF_IMPLEMENTATION 32 | #include "five_pixel_font.h" 33 | ``` 34 | 35 | Destructions 36 | ------------ 37 | 38 | Here's a brief example of how the library could be used with OpenGL. Using the library with DirectX or something else is very similar. 39 | 40 | 1. Use **`fpf_create_alpha_texture()`** to fill a block of memory with the font's alpha texture. Example: 41 | ```C 42 | // Allocate a graphics surface or your own buffer to hold the font's texture. 43 | // FPF_TEXTURE_WIDTH and FPF_TEXTURE_HEIGHT are constants defined in the library header. 44 | unsigned char alpha_texture[FPF_TEXTURE_WIDTH * FPF_TEXTURE_HEIGHT]; 45 | 46 | // Draw the font's texture in the buffer. 47 | fpf_create_alpha_texture( 48 | alpha_texture, // pointer to buffer (or graphics surface memory) 49 | FPF_TEXTURE_WIDTH * FPF_TEXTURE_HEIGHT, // size of the buffer in bytes 50 | FPF_TEXTURE_WIDTH, // pitch of the graphics buffer (number of bytes per row) 51 | FPF_VECTOR_Y_AXIS // order to draw the rows (raster or vector order) 52 | ); 53 | ``` 54 | 2. Copy the alpha texture into graphics memory with something like `glTexImage2D()`. Example: 55 | ```C 56 | // Prepare an OpenGL texture resource. 57 | GLuint texture_name; 58 | glGenTextures(1, &texture_name); 59 | glBindTexture(GL_TEXTURE_2D, texture_name); 60 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 61 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 62 | 63 | // Copy the texture into graphics memory. 64 | glTexImage2D( 65 | GL_TEXTURE_2D, 66 | 0, 67 | GL_ALPHA, 68 | FPF_TEXTURE_WIDTH, 69 | FPF_TEXTURE_HEIGHT, 70 | 0, 71 | GL_ALPHA, 72 | GL_UNSIGNED_BYTE, 73 | alpha_texture 74 | ); 75 | ``` 76 | 3. Get the texture coordinates of a character glyph from **`fpf_get_glyph_gl_texture_coordinates()`**. Example: 77 | ```C 78 | // Get texture coordinates for the 'X' glyph. 79 | float left; 80 | float top; 81 | float right; 82 | float bottom; 83 | fpf_get_glyph_gl_texture_coordinates('X', &left, &top, &right, &bottom); 84 | ``` 85 | 4. Render a blended, colored, textured quad to the framebuffer. Example: 86 | ```C 87 | // Fill the whole viewport with the glyph. 88 | const GLfloat billboard_verts[] = 89 | { 90 | -1.0f, -1.0f, 91 | 1.0f, -1.0f, 92 | -1.0f, 1.0f, 93 | 1.0f, 1.0f 94 | }; 95 | 96 | // Prepare the glyph's texture coordinates. 97 | const GLfloat texture_coords[] = 98 | { 99 | left, bottom, 100 | right, bottom, 101 | left, top, 102 | right, top 103 | }; 104 | 105 | // Make sure alpha blending is turned on. 106 | glEnable(GL_BLEND); 107 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 108 | 109 | // Make sure texturing is turned on. 110 | glEnable(GL_TEXTURE_2D); 111 | 112 | // Set the text color. 113 | glColor4f(0.0f, 1.0f, 0.0f, 1.0f); 114 | 115 | // Send the billboard and texture coordinates to OpenGL. 116 | glTexCoordPointer(2, GL_FLOAT, 0, texture_coords); 117 | glVertexPointer(2, GL_FLOAT, 0, billboard_verts); 118 | 119 | // Draw the glyph. 120 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 121 | ``` 122 | 123 | Further Examples 124 | ---------------- 125 | 126 | There's three example/test programs included. 127 | 128 | - **`test/fpf_test.c`** - a command-line program that expands the texture atlas into memory, then writes the whole texture out to the console. 129 | 130 | - **`test/gl_test.c`** - an OpenGL example using the GLFW library for cross-platform windowing. 131 | 132 | - **`VisualStudio2012/dx_test/dx_test.cpp`** - a Direct3D 9 example. 133 | 134 | License 135 | ======= 136 | 137 | ### Public Domain 138 | - For more information, please refer to 139 | -------------------------------------------------------------------------------- /VisualStudio2012/dx_test/dx_test.cpp: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // five-pixel-font library 3 | // by Chris Gassib 4 | // ----------------------------------------------------------------------- 5 | // This is free and unencumbered software released into the public domain. 6 | // 7 | // Anyone is free to copy, modify, publish, use, compile, sell, or 8 | // distribute this software, either in source code form or as a compiled 9 | // binary, for any purpose, commercial or non-commercial, and by any 10 | // means. 11 | // 12 | // In jurisdictions that recognize copyright laws, the author or authors 13 | // of this software dedicate any and all copyright interest in the 14 | // software to the public domain. We make this dedication for the benefit 15 | // of the public at large and to the detriment of our heirs and 16 | // successors. We intend this dedication to be an overt act of 17 | // relinquishment in perpetuity of all present and future rights to this 18 | // software under copyright law. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 24 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | // OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | // For more information, please refer to 29 | // 30 | 31 | #include "stdafx.h" 32 | 33 | #define FPF_IMPLEMENTATION 34 | #include "five_pixel_font.h" 35 | 36 | #define MAX_LOADSTRING 100 37 | #define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_TEX1 ) 38 | 39 | struct CUSTOMVERTEX 40 | { 41 | FLOAT x, y, z; // from the D3DFVF_XYZ flag 42 | FLOAT u, v; // D3DFVF_TEX1 43 | }; 44 | 45 | const int ClientWidth = 640; 46 | const int ClientHeight = 640; 47 | 48 | // Global Variables: 49 | HINSTANCE hInst; // current instance 50 | HWND hWnd; 51 | const TCHAR szTitle[] = _T("Five Pixel Font Test"); // The title bar text 52 | const TCHAR szWindowClass[] = _T("FpfTestWindow"); // the main window class name 53 | 54 | // Forward declarations of functions included in this code module: 55 | ATOM MyRegisterClass(HINSTANCE hInstance); 56 | BOOL InitInstance(HINSTANCE, int); 57 | LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 58 | INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); 59 | 60 | // global declarations 61 | LPDIRECT3D9 d3d; // the pointer to our Direct3D interface 62 | LPDIRECT3DDEVICE9 d3ddev; // the pointer to the device class 63 | LPDIRECT3DTEXTURE9 pTexture; 64 | LPDIRECT3DVERTEXBUFFER9 v_buffer; 65 | 66 | // function prototypes 67 | void initD3D(HWND hWnd); // sets up and initializes Direct3D 68 | void render_frame(void); // renders a single frame 69 | void cleanD3D(void); // closes Direct3D and releases memory 70 | 71 | int APIENTRY _tWinMain( 72 | _In_ HINSTANCE hInstance, 73 | _In_opt_ HINSTANCE hPrevInstance, 74 | _In_ LPTSTR lpCmdLine, 75 | _In_ int nCmdShow 76 | ) 77 | { 78 | UNREFERENCED_PARAMETER(hPrevInstance); 79 | UNREFERENCED_PARAMETER(lpCmdLine); 80 | 81 | // Initialize global strings 82 | MyRegisterClass(hInstance); 83 | 84 | // Perform application initialization: 85 | if (!InitInstance (hInstance, nCmdShow)) 86 | { 87 | return FALSE; 88 | } 89 | 90 | initD3D(hWnd); 91 | 92 | // Main message loop: 93 | MSG msg; 94 | while (GetMessage(&msg, NULL, 0, 0)) 95 | { 96 | TranslateMessage(&msg); 97 | DispatchMessage(&msg); 98 | } 99 | 100 | cleanD3D(); 101 | 102 | return (int) msg.wParam; 103 | } 104 | 105 | // 106 | // FUNCTION: MyRegisterClass() 107 | // 108 | // PURPOSE: Registers the window class. 109 | // 110 | ATOM MyRegisterClass(HINSTANCE hInstance) 111 | { 112 | WNDCLASSEX wcex; 113 | 114 | wcex.cbSize = sizeof(WNDCLASSEX); 115 | 116 | wcex.style = CS_HREDRAW | CS_VREDRAW; 117 | wcex.lpfnWndProc = WndProc; 118 | wcex.cbClsExtra = 0; 119 | wcex.cbWndExtra = 0; 120 | wcex.hInstance = hInstance; 121 | wcex.hIcon = nullptr; 122 | wcex.hCursor = nullptr; 123 | wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 124 | wcex.lpszMenuName = nullptr; 125 | wcex.lpszClassName = szWindowClass; 126 | wcex.hIconSm = nullptr; 127 | 128 | return RegisterClassEx(&wcex); 129 | } 130 | 131 | // 132 | // FUNCTION: InitInstance(HINSTANCE, int) 133 | // 134 | // PURPOSE: Saves instance handle and creates main window 135 | // 136 | // COMMENTS: 137 | // 138 | // In this function, we save the instance handle in a global variable and 139 | // create and display the main program window. 140 | // 141 | BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 142 | { 143 | hInst = hInstance; // Store instance handle in our global variable 144 | 145 | hWnd = CreateWindow( 146 | szWindowClass, 147 | szTitle, 148 | WS_OVERLAPPEDWINDOW, 149 | CW_USEDEFAULT, 150 | CW_USEDEFAULT, 151 | ClientWidth, 152 | ClientHeight, 153 | nullptr, 154 | nullptr, 155 | hInstance, 156 | nullptr 157 | ); 158 | 159 | if (!hWnd) 160 | { 161 | return FALSE; 162 | } 163 | 164 | ShowWindow(hWnd, nCmdShow); 165 | UpdateWindow(hWnd); 166 | 167 | RECT client; 168 | GetClientRect(hWnd, &client); 169 | 170 | if (client.right != ClientWidth || client.bottom != ClientHeight) 171 | { 172 | RECT window; 173 | GetWindowRect(hWnd, &window); 174 | 175 | const auto cx = (window.right - window.left) - (client.right - ClientWidth); 176 | const auto cy = (window.bottom - window.top) - (client.bottom - ClientHeight); 177 | 178 | SetWindowPos(hWnd, nullptr, 0, 0, cx, cy, 0); 179 | } 180 | 181 | return TRUE; 182 | } 183 | 184 | // 185 | // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) 186 | // 187 | // PURPOSE: Processes messages for the main window. 188 | // 189 | // WM_COMMAND - process the application menu 190 | // WM_PAINT - Paint the main window 191 | // WM_DESTROY - post a quit message and return 192 | // 193 | // 194 | LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 195 | { 196 | //PAINTSTRUCT ps; 197 | //HDC hdc; 198 | 199 | switch (message) 200 | { 201 | case WM_PAINT: 202 | //hdc = BeginPaint(hWnd, &ps); 203 | if (nullptr != d3d) 204 | { 205 | render_frame(); 206 | } 207 | //EndPaint(hWnd, &ps); 208 | break; 209 | case WM_KEYDOWN: 210 | if (VK_ESCAPE == wParam) 211 | { 212 | DestroyWindow(hWnd); 213 | } 214 | break; 215 | case WM_DESTROY: 216 | PostQuitMessage(0); 217 | break; 218 | default: 219 | return DefWindowProc(hWnd, message, wParam, lParam); 220 | } 221 | return 0; 222 | } 223 | 224 | void init_graphics(void) 225 | { 226 | float left = 0.0f; 227 | float top = 0.0f; 228 | float right = 1.0f; 229 | float bottom = 1.0f; 230 | //fpf_get_glyph_dx_texture_coordinates('w', &left, &top, &right, &bottom); 231 | //fpf_get_cursor_glyph_dx_texture_coordinates(FPF_VERTICAL_CURSOR, &left, &top, &right, &bottom); 232 | 233 | // create three vertices using the CUSTOMVERTEX struct built earlier 234 | CUSTOMVERTEX vertices[] = 235 | { 236 | { -1.0f, -1.0f, 0.0f, left, bottom, }, 237 | { -1.0f, 1.0f, 0.0f, left, top, }, 238 | { 1.0f, -1.0f, 0.0f, right, bottom, }, 239 | { 1.0f, 1.0f, 0.0f, right, top, }, 240 | }; 241 | 242 | // Compensate for pre-DX10 texture coordinate retardation. 243 | for (auto i = 0; i < (sizeof(vertices) / sizeof(CUSTOMVERTEX)); ++i) 244 | { 245 | vertices[i].x -= (1.0f / float(ClientWidth)) * 0.5f; 246 | vertices[i].y -= (1.0f / float(ClientHeight)) * 0.5f; 247 | } 248 | 249 | // create the vertex and store the pointer into v_buffer, which is created globally 250 | d3ddev->CreateVertexBuffer( 251 | 4 * sizeof(CUSTOMVERTEX), 252 | 0, 253 | CUSTOMFVF, 254 | D3DPOOL_MANAGED, 255 | &v_buffer, 256 | nullptr 257 | ); 258 | 259 | // lock and copy the vertices to the buffer 260 | void* pVoid; 261 | v_buffer->Lock(0, 0, &pVoid, 0); 262 | { 263 | memcpy(pVoid, vertices, sizeof(vertices)); 264 | } 265 | v_buffer->Unlock(); 266 | } 267 | 268 | // this function initializes and prepares Direct3D for use 269 | void initD3D(HWND hWnd) 270 | { 271 | d3d = Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface 272 | 273 | D3DPRESENT_PARAMETERS d3dpp; // create a struct to hold various device information 274 | 275 | ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear out the struct for use 276 | d3dpp.Windowed = TRUE; // program windowed, not fullscreen 277 | d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames 278 | d3dpp.hDeviceWindow = hWnd; // set the window to be used by Direct3D 279 | 280 | // create a device class using this information and information from the d3dpp stuct 281 | d3d->CreateDevice( 282 | D3DADAPTER_DEFAULT, 283 | D3DDEVTYPE_HAL, 284 | hWnd, 285 | D3DCREATE_SOFTWARE_VERTEXPROCESSING, 286 | &d3dpp, 287 | &d3ddev 288 | ); 289 | 290 | // Turn off DX lighting (which is ON by default). 291 | d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE); 292 | 293 | // Turn on alpha blending. 294 | d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); 295 | d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); 296 | d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); 297 | 298 | // Set the magic DX "Texture Factor" color to the desired font color and opacity. 299 | d3ddev->SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_ARGB(255, 0, 255, 0)); 300 | 301 | // Draw with the Texture Factor color. 302 | d3ddev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); 303 | d3ddev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); 304 | 305 | // Modulate the alpha texture with the Texture Factor's alpha component. 306 | d3ddev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); 307 | d3ddev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); 308 | d3ddev->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); 309 | 310 | d3ddev->CreateTexture( 311 | FPF_TEXTURE_WIDTH, 312 | FPF_TEXTURE_HEIGHT, 313 | 1, 314 | 0, 315 | D3DFMT_A8, 316 | D3DPOOL_MANAGED, 317 | &pTexture, 318 | nullptr 319 | ); 320 | 321 | D3DLOCKED_RECT rect; 322 | pTexture->LockRect(0, &rect, nullptr, 0); 323 | { 324 | auto result = fpf_create_alpha_texture( 325 | static_cast(rect.pBits), 326 | FPF_TEXTURE_WIDTH * FPF_TEXTURE_HEIGHT, 327 | rect.Pitch, 328 | FPF_RASTER_Y_AXIS 329 | ); 330 | if (0 != result) 331 | { 332 | DebugBreak(); 333 | } 334 | } 335 | pTexture->UnlockRect(0); 336 | 337 | d3ddev->SetTexture(0, pTexture); 338 | } 339 | 340 | // this is the function used to render a single frame 341 | void render_frame(void) 342 | { 343 | init_graphics(); 344 | 345 | // clear the window to a deep blue 346 | d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0); 347 | 348 | d3ddev->BeginScene(); // begins the 3D scene 349 | { 350 | 351 | // select which vertex format we are using 352 | d3ddev->SetFVF(CUSTOMFVF); 353 | 354 | // select the vertex buffer to display 355 | d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); 356 | 357 | // copy the vertex buffer to the back buffer 358 | d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); 359 | 360 | } 361 | d3ddev->EndScene(); // ends the 3D scene 362 | 363 | d3ddev->Present(NULL, NULL, NULL, NULL); // displays the created frame 364 | } 365 | 366 | // this is the function that cleans up Direct3D and COM 367 | void cleanD3D(void) 368 | { 369 | v_buffer->Release(); // close and release the vertex buffer 370 | pTexture->Release(); 371 | d3ddev->Release(); // close and release the 3D device 372 | d3d->Release(); // close and release Direct3D 373 | } 374 | -------------------------------------------------------------------------------- /XCode/fpf_test.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8F1E27C517CAEC1000CB73F4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F1E27C417CAEC1000CB73F4 /* Cocoa.framework */; }; 11 | 8F1E27CF17CAEC1000CB73F4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8F1E27CD17CAEC1000CB73F4 /* InfoPlist.strings */; }; 12 | 8F2A89C817CB24750024992D /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F2A89C717CB24750024992D /* IOKit.framework */; }; 13 | 8F2A89CA17CB24BA0024992D /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F2A89C917CB24BA0024992D /* OpenGL.framework */; }; 14 | 8F2A89CC17CB28B00024992D /* gl_test.c in Sources */ = {isa = PBXBuildFile; fileRef = 8F2A89CB17CB28B00024992D /* gl_test.c */; }; 15 | 8F2A89DB17CB2A0A0024992D /* fpf_test.c in Sources */ = {isa = PBXBuildFile; fileRef = 8F2A89DA17CB2A0A0024992D /* fpf_test.c */; }; 16 | 8F3DD02817CB19B1004C9436 /* libglfw3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F3DD02717CB19B1004C9436 /* libglfw3.a */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXContainerItemProxy section */ 20 | 8F2A89DC17CB2AB60024992D /* PBXContainerItemProxy */ = { 21 | isa = PBXContainerItemProxy; 22 | containerPortal = 8F1E27B917CAEC1000CB73F4 /* Project object */; 23 | proxyType = 1; 24 | remoteGlobalIDString = 8F2A89D017CB29BB0024992D; 25 | remoteInfo = fpf_test; 26 | }; 27 | /* End PBXContainerItemProxy section */ 28 | 29 | /* Begin PBXCopyFilesBuildPhase section */ 30 | 8F2A89CF17CB29BB0024992D /* CopyFiles */ = { 31 | isa = PBXCopyFilesBuildPhase; 32 | buildActionMask = 2147483647; 33 | dstPath = /usr/share/man/man1/; 34 | dstSubfolderSpec = 0; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 1; 38 | }; 39 | /* End PBXCopyFilesBuildPhase section */ 40 | 41 | /* Begin PBXFileReference section */ 42 | 8F1E27C117CAEC1000CB73F4 /* fpf_test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; name = fpf_test.app; path = gl_test.app; sourceTree = BUILT_PRODUCTS_DIR; }; 43 | 8F1E27C417CAEC1000CB73F4 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 44 | 8F1E27C717CAEC1000CB73F4 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 45 | 8F1E27C817CAEC1000CB73F4 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 46 | 8F1E27C917CAEC1000CB73F4 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 47 | 8F1E27CC17CAEC1000CB73F4 /* fpf_test-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "fpf_test-Info.plist"; sourceTree = ""; }; 48 | 8F1E27CE17CAEC1000CB73F4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 49 | 8F2A89C717CB24750024992D /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; 50 | 8F2A89C917CB24BA0024992D /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; 51 | 8F2A89CB17CB28B00024992D /* gl_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gl_test.c; path = ../../test/gl_test.c; sourceTree = ""; }; 52 | 8F2A89D117CB29BB0024992D /* fpf_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fpf_test; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 8F2A89DA17CB2A0A0024992D /* fpf_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fpf_test.c; path = ../../test/fpf_test.c; sourceTree = ""; }; 54 | 8F3DD02717CB19B1004C9436 /* libglfw3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libglfw3.a; path = "../../glfw-3.0.2/src/libglfw3.a"; sourceTree = ""; }; 55 | /* End PBXFileReference section */ 56 | 57 | /* Begin PBXFrameworksBuildPhase section */ 58 | 8F1E27BE17CAEC1000CB73F4 /* Frameworks */ = { 59 | isa = PBXFrameworksBuildPhase; 60 | buildActionMask = 2147483647; 61 | files = ( 62 | 8F1E27C517CAEC1000CB73F4 /* Cocoa.framework in Frameworks */, 63 | 8F3DD02817CB19B1004C9436 /* libglfw3.a in Frameworks */, 64 | 8F2A89C817CB24750024992D /* IOKit.framework in Frameworks */, 65 | 8F2A89CA17CB24BA0024992D /* OpenGL.framework in Frameworks */, 66 | ); 67 | runOnlyForDeploymentPostprocessing = 0; 68 | }; 69 | 8F2A89CE17CB29BB0024992D /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | /* End PBXFrameworksBuildPhase section */ 77 | 78 | /* Begin PBXGroup section */ 79 | 8F1E27B817CAEC1000CB73F4 = { 80 | isa = PBXGroup; 81 | children = ( 82 | 8F1E27CA17CAEC1000CB73F4 /* gl_test */, 83 | 8F2A89D217CB29BB0024992D /* fpf_test */, 84 | 8F1E27C317CAEC1000CB73F4 /* Frameworks */, 85 | 8F1E27C217CAEC1000CB73F4 /* Products */, 86 | ); 87 | sourceTree = ""; 88 | }; 89 | 8F1E27C217CAEC1000CB73F4 /* Products */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | 8F1E27C117CAEC1000CB73F4 /* fpf_test.app */, 93 | 8F2A89D117CB29BB0024992D /* fpf_test */, 94 | ); 95 | name = Products; 96 | sourceTree = ""; 97 | }; 98 | 8F1E27C317CAEC1000CB73F4 /* Frameworks */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 8F3DD02717CB19B1004C9436 /* libglfw3.a */, 102 | 8F1E27C417CAEC1000CB73F4 /* Cocoa.framework */, 103 | 8F2A89C717CB24750024992D /* IOKit.framework */, 104 | 8F2A89C917CB24BA0024992D /* OpenGL.framework */, 105 | 8F1E27C617CAEC1000CB73F4 /* Other Frameworks */, 106 | ); 107 | name = Frameworks; 108 | sourceTree = ""; 109 | }; 110 | 8F1E27C617CAEC1000CB73F4 /* Other Frameworks */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | 8F1E27C717CAEC1000CB73F4 /* AppKit.framework */, 114 | 8F1E27C817CAEC1000CB73F4 /* CoreData.framework */, 115 | 8F1E27C917CAEC1000CB73F4 /* Foundation.framework */, 116 | ); 117 | name = "Other Frameworks"; 118 | sourceTree = ""; 119 | }; 120 | 8F1E27CA17CAEC1000CB73F4 /* gl_test */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 8F2A89CB17CB28B00024992D /* gl_test.c */, 124 | 8F1E27CB17CAEC1000CB73F4 /* Supporting Files */, 125 | ); 126 | name = gl_test; 127 | path = fpf_test; 128 | sourceTree = ""; 129 | }; 130 | 8F1E27CB17CAEC1000CB73F4 /* Supporting Files */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 8F1E27CC17CAEC1000CB73F4 /* fpf_test-Info.plist */, 134 | 8F1E27CD17CAEC1000CB73F4 /* InfoPlist.strings */, 135 | ); 136 | name = "Supporting Files"; 137 | sourceTree = ""; 138 | }; 139 | 8F2A89D217CB29BB0024992D /* fpf_test */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | 8F2A89DA17CB2A0A0024992D /* fpf_test.c */, 143 | ); 144 | path = fpf_test; 145 | sourceTree = ""; 146 | }; 147 | /* End PBXGroup section */ 148 | 149 | /* Begin PBXNativeTarget section */ 150 | 8F1E27C017CAEC1000CB73F4 /* gl_test */ = { 151 | isa = PBXNativeTarget; 152 | buildConfigurationList = 8F1E27DE17CAEC1000CB73F4 /* Build configuration list for PBXNativeTarget "gl_test" */; 153 | buildPhases = ( 154 | 8F1E27BD17CAEC1000CB73F4 /* Sources */, 155 | 8F1E27BE17CAEC1000CB73F4 /* Frameworks */, 156 | 8F1E27BF17CAEC1000CB73F4 /* Resources */, 157 | ); 158 | buildRules = ( 159 | ); 160 | dependencies = ( 161 | 8F2A89DD17CB2AB60024992D /* PBXTargetDependency */, 162 | ); 163 | name = gl_test; 164 | productName = fpf_test; 165 | productReference = 8F1E27C117CAEC1000CB73F4 /* fpf_test.app */; 166 | productType = "com.apple.product-type.application"; 167 | }; 168 | 8F2A89D017CB29BB0024992D /* fpf_test */ = { 169 | isa = PBXNativeTarget; 170 | buildConfigurationList = 8F2A89D917CB29BB0024992D /* Build configuration list for PBXNativeTarget "fpf_test" */; 171 | buildPhases = ( 172 | 8F2A89CD17CB29BB0024992D /* Sources */, 173 | 8F2A89CE17CB29BB0024992D /* Frameworks */, 174 | 8F2A89CF17CB29BB0024992D /* CopyFiles */, 175 | ); 176 | buildRules = ( 177 | ); 178 | dependencies = ( 179 | ); 180 | name = fpf_test; 181 | productName = fpf_test; 182 | productReference = 8F2A89D117CB29BB0024992D /* fpf_test */; 183 | productType = "com.apple.product-type.tool"; 184 | }; 185 | /* End PBXNativeTarget section */ 186 | 187 | /* Begin PBXProject section */ 188 | 8F1E27B917CAEC1000CB73F4 /* Project object */ = { 189 | isa = PBXProject; 190 | attributes = { 191 | CLASSPREFIX = fpf; 192 | LastUpgradeCheck = 0460; 193 | }; 194 | buildConfigurationList = 8F1E27BC17CAEC1000CB73F4 /* Build configuration list for PBXProject "fpf_test" */; 195 | compatibilityVersion = "Xcode 3.2"; 196 | developmentRegion = English; 197 | hasScannedForEncodings = 0; 198 | knownRegions = ( 199 | en, 200 | ); 201 | mainGroup = 8F1E27B817CAEC1000CB73F4; 202 | productRefGroup = 8F1E27C217CAEC1000CB73F4 /* Products */; 203 | projectDirPath = ""; 204 | projectRoot = ""; 205 | targets = ( 206 | 8F1E27C017CAEC1000CB73F4 /* gl_test */, 207 | 8F2A89D017CB29BB0024992D /* fpf_test */, 208 | ); 209 | }; 210 | /* End PBXProject section */ 211 | 212 | /* Begin PBXResourcesBuildPhase section */ 213 | 8F1E27BF17CAEC1000CB73F4 /* Resources */ = { 214 | isa = PBXResourcesBuildPhase; 215 | buildActionMask = 2147483647; 216 | files = ( 217 | 8F1E27CF17CAEC1000CB73F4 /* InfoPlist.strings in Resources */, 218 | ); 219 | runOnlyForDeploymentPostprocessing = 0; 220 | }; 221 | /* End PBXResourcesBuildPhase section */ 222 | 223 | /* Begin PBXSourcesBuildPhase section */ 224 | 8F1E27BD17CAEC1000CB73F4 /* Sources */ = { 225 | isa = PBXSourcesBuildPhase; 226 | buildActionMask = 2147483647; 227 | files = ( 228 | 8F2A89CC17CB28B00024992D /* gl_test.c in Sources */, 229 | ); 230 | runOnlyForDeploymentPostprocessing = 0; 231 | }; 232 | 8F2A89CD17CB29BB0024992D /* Sources */ = { 233 | isa = PBXSourcesBuildPhase; 234 | buildActionMask = 2147483647; 235 | files = ( 236 | 8F2A89DB17CB2A0A0024992D /* fpf_test.c in Sources */, 237 | ); 238 | runOnlyForDeploymentPostprocessing = 0; 239 | }; 240 | /* End PBXSourcesBuildPhase section */ 241 | 242 | /* Begin PBXTargetDependency section */ 243 | 8F2A89DD17CB2AB60024992D /* PBXTargetDependency */ = { 244 | isa = PBXTargetDependency; 245 | target = 8F2A89D017CB29BB0024992D /* fpf_test */; 246 | targetProxy = 8F2A89DC17CB2AB60024992D /* PBXContainerItemProxy */; 247 | }; 248 | /* End PBXTargetDependency section */ 249 | 250 | /* Begin PBXVariantGroup section */ 251 | 8F1E27CD17CAEC1000CB73F4 /* InfoPlist.strings */ = { 252 | isa = PBXVariantGroup; 253 | children = ( 254 | 8F1E27CE17CAEC1000CB73F4 /* en */, 255 | ); 256 | name = InfoPlist.strings; 257 | sourceTree = ""; 258 | }; 259 | /* End PBXVariantGroup section */ 260 | 261 | /* Begin XCBuildConfiguration section */ 262 | 8F1E27DC17CAEC1000CB73F4 /* Debug */ = { 263 | isa = XCBuildConfiguration; 264 | buildSettings = { 265 | ALWAYS_SEARCH_USER_PATHS = NO; 266 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 267 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 268 | CLANG_CXX_LIBRARY = "libc++"; 269 | CLANG_ENABLE_OBJC_ARC = YES; 270 | CLANG_WARN_CONSTANT_CONVERSION = YES; 271 | CLANG_WARN_EMPTY_BODY = YES; 272 | CLANG_WARN_ENUM_CONVERSION = YES; 273 | CLANG_WARN_INT_CONVERSION = YES; 274 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 275 | COPY_PHASE_STRIP = NO; 276 | GCC_C_LANGUAGE_STANDARD = gnu99; 277 | GCC_DYNAMIC_NO_PIC = NO; 278 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 279 | GCC_OPTIMIZATION_LEVEL = 0; 280 | GCC_PREPROCESSOR_DEFINITIONS = ( 281 | "DEBUG=1", 282 | "$(inherited)", 283 | ); 284 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 285 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 286 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 287 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 288 | GCC_WARN_UNUSED_VARIABLE = YES; 289 | HEADER_SEARCH_PATHS = ( 290 | ../, 291 | "../../glfw-3.0.2/include/", 292 | ); 293 | LIBRARY_SEARCH_PATHS = ""; 294 | MACOSX_DEPLOYMENT_TARGET = 10.8; 295 | ONLY_ACTIVE_ARCH = YES; 296 | PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; 297 | SDKROOT = macosx; 298 | }; 299 | name = Debug; 300 | }; 301 | 8F1E27DD17CAEC1000CB73F4 /* Release */ = { 302 | isa = XCBuildConfiguration; 303 | buildSettings = { 304 | ALWAYS_SEARCH_USER_PATHS = NO; 305 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 306 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 307 | CLANG_CXX_LIBRARY = "libc++"; 308 | CLANG_ENABLE_OBJC_ARC = YES; 309 | CLANG_WARN_CONSTANT_CONVERSION = YES; 310 | CLANG_WARN_EMPTY_BODY = YES; 311 | CLANG_WARN_ENUM_CONVERSION = YES; 312 | CLANG_WARN_INT_CONVERSION = YES; 313 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 314 | COPY_PHASE_STRIP = YES; 315 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 316 | GCC_C_LANGUAGE_STANDARD = gnu99; 317 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 318 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 319 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 320 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 321 | GCC_WARN_UNUSED_VARIABLE = YES; 322 | HEADER_SEARCH_PATHS = ( 323 | ../, 324 | "../../glfw-3.0.2/include/", 325 | ); 326 | LIBRARY_SEARCH_PATHS = ""; 327 | MACOSX_DEPLOYMENT_TARGET = 10.8; 328 | PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; 329 | SDKROOT = macosx; 330 | }; 331 | name = Release; 332 | }; 333 | 8F1E27DF17CAEC1000CB73F4 /* Debug */ = { 334 | isa = XCBuildConfiguration; 335 | buildSettings = { 336 | COMBINE_HIDPI_IMAGES = YES; 337 | GCC_PRECOMPILE_PREFIX_HEADER = NO; 338 | GCC_PREFIX_HEADER = ""; 339 | INFOPLIST_FILE = "fpf_test/fpf_test-Info.plist"; 340 | LIBRARY_SEARCH_PATHS = ( 341 | "$(inherited)", 342 | "\"$(SRCROOT)/../../glfw-3.0.2/src\"", 343 | ); 344 | PRODUCT_NAME = "$(TARGET_NAME)"; 345 | WRAPPER_EXTENSION = app; 346 | }; 347 | name = Debug; 348 | }; 349 | 8F1E27E017CAEC1000CB73F4 /* Release */ = { 350 | isa = XCBuildConfiguration; 351 | buildSettings = { 352 | COMBINE_HIDPI_IMAGES = YES; 353 | GCC_PRECOMPILE_PREFIX_HEADER = NO; 354 | GCC_PREFIX_HEADER = ""; 355 | INFOPLIST_FILE = "fpf_test/fpf_test-Info.plist"; 356 | LIBRARY_SEARCH_PATHS = ( 357 | "$(inherited)", 358 | "\"$(SRCROOT)/../../glfw-3.0.2/src\"", 359 | ); 360 | PRODUCT_NAME = "$(TARGET_NAME)"; 361 | WRAPPER_EXTENSION = app; 362 | }; 363 | name = Release; 364 | }; 365 | 8F2A89D717CB29BB0024992D /* Debug */ = { 366 | isa = XCBuildConfiguration; 367 | buildSettings = { 368 | PRODUCT_NAME = "$(TARGET_NAME)"; 369 | }; 370 | name = Debug; 371 | }; 372 | 8F2A89D817CB29BB0024992D /* Release */ = { 373 | isa = XCBuildConfiguration; 374 | buildSettings = { 375 | PRODUCT_NAME = "$(TARGET_NAME)"; 376 | }; 377 | name = Release; 378 | }; 379 | /* End XCBuildConfiguration section */ 380 | 381 | /* Begin XCConfigurationList section */ 382 | 8F1E27BC17CAEC1000CB73F4 /* Build configuration list for PBXProject "fpf_test" */ = { 383 | isa = XCConfigurationList; 384 | buildConfigurations = ( 385 | 8F1E27DC17CAEC1000CB73F4 /* Debug */, 386 | 8F1E27DD17CAEC1000CB73F4 /* Release */, 387 | ); 388 | defaultConfigurationIsVisible = 0; 389 | defaultConfigurationName = Release; 390 | }; 391 | 8F1E27DE17CAEC1000CB73F4 /* Build configuration list for PBXNativeTarget "gl_test" */ = { 392 | isa = XCConfigurationList; 393 | buildConfigurations = ( 394 | 8F1E27DF17CAEC1000CB73F4 /* Debug */, 395 | 8F1E27E017CAEC1000CB73F4 /* Release */, 396 | ); 397 | defaultConfigurationIsVisible = 0; 398 | defaultConfigurationName = Release; 399 | }; 400 | 8F2A89D917CB29BB0024992D /* Build configuration list for PBXNativeTarget "fpf_test" */ = { 401 | isa = XCConfigurationList; 402 | buildConfigurations = ( 403 | 8F2A89D717CB29BB0024992D /* Debug */, 404 | 8F2A89D817CB29BB0024992D /* Release */, 405 | ); 406 | defaultConfigurationIsVisible = 0; 407 | }; 408 | /* End XCConfigurationList section */ 409 | }; 410 | rootObject = 8F1E27B917CAEC1000CB73F4 /* Project object */; 411 | } 412 | -------------------------------------------------------------------------------- /five_pixel_font.h: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // five-pixel-font library 3 | // by Chris Gassib 4 | // ----------------------------------------------------------------------- 5 | // This is free and unencumbered software released into the public domain. 6 | // 7 | // Anyone is free to copy, modify, publish, use, compile, sell, or 8 | // distribute this software, either in source code form or as a compiled 9 | // binary, for any purpose, commercial or non-commercial, and by any 10 | // means. 11 | // 12 | // In jurisdictions that recognize copyright laws, the author or authors 13 | // of this software dedicate any and all copyright interest in the 14 | // software to the public domain. We make this dedication for the benefit 15 | // of the public at large and to the detriment of our heirs and 16 | // successors. We intend this dedication to be an overt act of 17 | // relinquishment in perpetuity of all present and future rights to this 18 | // software under copyright law. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 24 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 25 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | // OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | // For more information, please refer to 29 | // 30 | 31 | // 32 | // Destructions: 33 | // 34 | // 1) Use fpf_create_alpha_texture() to fill a block of memory with an alpha texture of the font 35 | // atlas. Example: 36 | // unsigned char alpha_texture[FPF_TEXTURE_WIDTH * FPF_TEXTURE_HEIGHT]; 37 | // fpf_create_alpha_texture( 38 | // alpha_texture, 39 | // FPF_TEXTURE_WIDTH * FPF_TEXTURE_HEIGHT, 40 | // FPF_TEXTURE_WIDTH, 41 | // FPF_VECTOR_Y_AXIS 42 | // ); 43 | // 44 | // 2) Copy the alpha texture into graphics memory with something like glTexImage2D(). Example: 45 | // GLuint texture_name; 46 | // glGenTextures(1, &texture_name); 47 | // glBindTexture(GL_TEXTURE_2D, texture_name); 48 | // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 49 | // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 50 | // glTexImage2D( 51 | // GL_TEXTURE_2D, 52 | // 0, 53 | // GL_ALPHA, 54 | // FPF_TEXTURE_WIDTH, 55 | // FPF_TEXTURE_HEIGHT, 56 | // 0, 57 | // GL_ALPHA, 58 | // GL_UNSIGNED_BYTE, 59 | // alpha_texture 60 | // ); 61 | // 62 | // 3) Get the texture coordinates of a character glyph from fpf_get_glyph_gl_texture_coordinates(). 63 | // Example: 64 | // float left; 65 | // float top; 66 | // float right; 67 | // float bottom; 68 | // fpf_get_glyph_gl_texture_coordinates('X', &left, &top, &right, &bottom); 69 | // 70 | // 4) Render a blended, colored, textured quad to the framebuffer. Example: 71 | // const GLfloat billboard_verts[] = 72 | // { 73 | // -1.0f, -1.0f, 74 | // 1.0f, -1.0f, 75 | // -1.0f, 1.0f, 76 | // 1.0f, 1.0f 77 | // }; 78 | // const GLfloat texture_coords[] = 79 | // { 80 | // left, bottom, 81 | // right, bottom, 82 | // left, top, 83 | // right, top 84 | // }; 85 | // glEnable(GL_BLEND); 86 | // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 87 | // glEnable(GL_TEXTURE_2D); 88 | // glActiveTexture(GL_TEXTURE0); 89 | // glUniform4f(text_color_uniform_id, r, g, b, a); 90 | // glUniform1i(texture_uniform_id, 0); 91 | // glEnableVertexAttribArray(texture_coord_attr_id); 92 | // glVertexAttribPointer(texture_coord_attr_id, 2, GL_FLOAT, GL_FALSE, 0, texture_coords); 93 | // glEnableVertexAttribArray(_vertexPosVar); 94 | // glVertexAttribPointer(vertex_attr_id, 2, GL_FLOAT, GL_FALSE, 0, billboard_verts); 95 | // glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 96 | // 97 | // Notes: A fragment shader probably contains a line like this: 98 | // gl_FragColor = u_text_color * texture2D(u_texture_id, v_tex_coord).a; 99 | // 100 | 101 | #ifndef FIVEPIXELFONT_H 102 | #define FIVEPIXELFONT_H 103 | 104 | // The texture atlas may be created for raster blits or DirectX where the first byte of the texture 105 | // represents the [left, top] corner of the raster image. Or, the texture atlas may be created 106 | // Windows Bitmap (DIB) / OpenGL-style where the first byte of the texture represents the 107 | // [left, bottom] corner of the raster image. 108 | typedef enum 109 | { 110 | FPF_RASTER_Y_AXIS = 0, // First byte is at the top of the texture. 111 | FPF_VECTOR_Y_AXIS // First byte is at the bottom of the texture. 112 | } fpf_y_axis_direction; 113 | 114 | // The font's texture atlas contains three different cursor glyphs. This enumeration is used to 115 | // address a specific cursor glyph. 116 | typedef enum 117 | { 118 | FPF_UNDERLINE_CURSOR = 0, // Underline-style cursor (like the default in a cmd.exe window). 119 | FPF_BLOCK_CURSOR, // Block-style cursor (like the default iTerm style). 120 | FPF_VERTICAL_CURSOR // Vertical-style (like most modern GUIs editors). 121 | } fpf_cursor_style; 122 | 123 | // Each glyph fits within a 6x6 pixel character cell. Although, almost every glyph uses only the 124 | // top-left 5x5 pixels so there's space inbetween characters (only cursor glyphs break the rule). 125 | #define FPF_GLYPH_WIDTH 6u 126 | #define FPF_GLYPH_HEIGHT 6u 127 | 128 | // The texture atlas surface needs to be at least 64x64 bytes. 129 | #define FPF_TEXTURE_WIDTH 64u 130 | #define FPF_TEXTURE_HEIGHT 64u 131 | 132 | // Declarations. 133 | size_t fpf_create_alpha_texture(unsigned char *const p_alpha_texture, const size_t alpha_texture_size_in_bytes, 134 | const size_t line_pitch, const fpf_y_axis_direction y_axis_direction); 135 | void fpf_get_glyph_position(const char character, unsigned int *const x, unsigned int *const y); 136 | void fpf_get_glyph_dx_texture_coordinates(const char character, float *const left, float *const top, 137 | float *const right, float *const bottom); 138 | void fpf_get_glyph_gl_texture_coordinates(const char character, float *const left, float *const top, 139 | float *const right, float *const bottom); 140 | void fpf_get_cursor_glyph_position(const fpf_cursor_style cursor_style, unsigned int *const x, unsigned int *const y); 141 | void fpf_get_cursor_glyph_dx_texture_coordinates(const fpf_cursor_style cursor_style, float *const left, 142 | float *const top, float *const right, float *const bottom); 143 | void fpf_get_cursor_glyph_gl_texture_coordinates(const fpf_cursor_style cursor_style, float *const left, 144 | float *const top, float *const right, float *const bottom); 145 | 146 | #ifdef FPF_IMPLEMENTATION 147 | 148 | // #define your own FPF_memset() to override the include of memory.h for the default memset(). 149 | #ifndef FPF_memset 150 | #include // For memset() and size_t. 151 | #define FPF_memset(ptr, value, num) memset(ptr, value, num) 152 | #endif 153 | 154 | // #define your own FPF_assert() to override the include of assert.h for the default assert(). 155 | #ifndef FPF_assert 156 | #include // For parameter checking. 157 | #define FPF_assert(expression) assert(expression) 158 | #endif 159 | 160 | // This is the 5x5 pixel font image; lightly compressed. 161 | const unsigned char fpf_compressed_font[] = 162 | { 163 | 0, 1, 133, 20, 123, 34, 8, 16, 128, 0, 1, 133, 62, 163, 69, 16, 32, 64, 164 | 0, 1, 128, 20, 112, 130, 0, 1, 32, 64, 0, 2, 62, 41, 101, 0, 1, 32, 64, 165 | 0, 1, 128, 20, 242, 98, 128, 16, 128, 0, 8, 168, 0, 3, 39, 8, 49, 128, 166 | 112, 128, 0, 2, 73, 152, 72, 64, 249, 192, 28, 0, 1, 138, 136, 16, 128, 167 | 112, 130, 0, 1, 1, 12, 136, 32, 64, 168, 4, 0, 1, 34, 7, 28, 121, 128, 168 | 0, 8, 49, 194, 30, 97, 128, 0, 1, 16, 0, 1, 81, 4, 2, 146, 66, 8, 33, 169 | 192, 121, 142, 4, 97, 192, 0, 1, 64, 0, 1, 16, 73, 8, 144, 66, 8, 33, 170 | 192, 17, 134, 8, 96, 64, 16, 16, 0, 9, 65, 135, 28, 241, 239, 62, 249, 171 | 224, 32, 64, 162, 138, 8, 160, 130, 0, 1, 16, 134, 190, 242, 8, 188, 172 | 242, 96, 32, 10, 162, 138, 8, 160, 130, 32, 64, 135, 34, 241, 239, 62, 173 | 129, 224, 0, 8, 137, 195, 164, 130, 40, 156, 241, 192, 136, 129, 40, 174 | 131, 108, 162, 138, 32, 248, 129, 48, 130, 170, 162, 242, 32, 136, 137, 175 | 40, 130, 41, 162, 130, 64, 137, 198, 36, 242, 40, 156, 129, 160, 0, 8, 176 | 241, 239, 162, 138, 40, 162, 113, 192, 138, 2, 34, 138, 37, 20, 17, 0, 177 | 1, 241, 194, 34, 138, 162, 8, 33, 0, 1, 160, 34, 34, 82, 165, 8, 65, 0, 178 | 1, 147, 194, 28, 33, 72, 136, 113, 192, 0, 8, 129, 194, 0, 1, 32, 8, 0, 179 | 1, 16, 0, 1, 64, 69, 0, 1, 17, 206, 12, 16, 128, 32, 64, 0, 1, 2, 73, 180 | 16, 113, 64, 16, 64, 0, 1, 2, 73, 16, 145, 128, 9, 192, 62, 1, 174, 12, 181 | 112, 192, 0, 8, 16, 196, 8, 17, 2, 0, 3, 33, 68, 0, 1, 1, 2, 52, 96, 182 | 128, 112, 199, 8, 17, 66, 42, 81, 64, 32, 68, 136, 81, 130, 34, 81, 64, 183 | 33, 132, 136, 33, 66, 34, 80, 128, 0, 16, 96, 197, 12, 113, 37, 34, 81, 184 | 64, 81, 70, 8, 33, 37, 42, 33, 64, 96, 196, 4, 33, 37, 42, 32, 128, 64, 185 | 68, 12, 16, 194, 20, 81, 0, 10, 66, 16, 3, 224, 63, 128, 0, 1, 48, 130, 186 | 8, 82, 32, 63, 128, 0, 1, 17, 128, 12, 162, 32, 63, 128, 0, 1, 32, 130, 187 | 8, 2, 32, 63, 128, 0, 1, 48, 66, 16, 3, 239, 255, 128, 0, 5, 15, 255, 188 | 128 189 | }; 190 | 191 | unsigned char *fpf_next_line( 192 | unsigned char *const p, 193 | const size_t line_pitch, 194 | const unsigned int x, 195 | const fpf_y_axis_direction y_axis_direction 196 | ) 197 | { 198 | return (FPF_RASTER_Y_AXIS == y_axis_direction) ? 199 | p + (line_pitch - x) : 200 | p - (x + line_pitch); 201 | } 202 | 203 | // Creates an alpha texture atlas of the font glyphs from the fpf_compressed_font data. 204 | // Returns: 0 on success, otherwise it the size (in bytes) required to draw the font. 205 | size_t fpf_create_alpha_texture( 206 | unsigned char *const p_alpha_texture, // [in/out] Raw alpha texture memory to create the font atlas in. 207 | const size_t alpha_texture_size_in_bytes, // [in] Size of the texture memory in bytes. 208 | const size_t line_pitch, // [in] Line pitch of the texture memory in bytes. 209 | const fpf_y_axis_direction y_axis_direction // [in] Direction of the textures y-axis. 210 | ) 211 | { 212 | const size_t required_bytes = FPF_TEXTURE_WIDTH * FPF_TEXTURE_HEIGHT; 213 | 214 | // Get write pointer. 215 | unsigned char *p_dst = (FPF_RASTER_Y_AXIS == y_axis_direction) ? 216 | &p_alpha_texture[0] : &p_alpha_texture[FPF_TEXTURE_HEIGHT * line_pitch - line_pitch]; 217 | 218 | unsigned int x = 0; // Keep track of the current texture column index. 219 | unsigned int y = 0; // Keep track of the current texture row index. 220 | 221 | size_t byte_index = 0; // For the outer loop. 222 | unsigned int i; // For loops. 223 | 224 | FPF_assert(NULL != p_alpha_texture); 225 | 226 | // Check the line pitch. 227 | if (line_pitch < FPF_TEXTURE_WIDTH) // if (line pitch is too short) 228 | { 229 | return required_bytes; 230 | } 231 | 232 | // Check the texture size. 233 | if (alpha_texture_size_in_bytes < line_pitch * FPF_TEXTURE_HEIGHT) 234 | { 235 | return required_bytes; 236 | } 237 | 238 | // Decompress the font. 239 | for (; byte_index < sizeof(fpf_compressed_font); ++byte_index) 240 | { 241 | unsigned char byte = fpf_compressed_font[byte_index]; // Grab the next byte. 242 | 243 | if (0 == byte) // if (this byte indicates a run of zeros) 244 | { 245 | // Get the next byte, which indicates the run-length in bytes. 246 | const unsigned int run_length = fpf_compressed_font[++byte_index] * 8; 247 | 248 | // For each bit in the run. 249 | for (i = 0; i < run_length; ++i) 250 | { 251 | *p_dst++ = 0x00; 252 | 253 | if (++x == FPF_TEXTURE_WIDTH) // if (end-of-line) 254 | { 255 | p_dst = fpf_next_line(p_dst, line_pitch, x, y_axis_direction); 256 | x = 0; 257 | ++y; 258 | } 259 | } 260 | 261 | // Completed a run of zeros, start the next byte of the font. 262 | continue; 263 | } 264 | 265 | // Convert the single-byte bitmap to a string of eight bytes. 266 | for (i = 0; i < 8; ++i) 267 | { 268 | *p_dst++ = (byte & 0x80) ? 0xff : 0x00; 269 | byte <<= 1; 270 | } 271 | 272 | // Advance the texture column index. 273 | x += 8; 274 | 275 | if (x >= FPF_TEXTURE_WIDTH) 276 | { 277 | p_dst = fpf_next_line(p_dst, line_pitch, x, y_axis_direction); 278 | x = 0; 279 | ++y; 280 | } 281 | } 282 | 283 | // Fill in any trailing space at the end of the last line. 284 | FPF_memset(p_dst, 0x00, FPF_TEXTURE_WIDTH - x); 285 | p_dst = fpf_next_line(p_dst, line_pitch, x, y_axis_direction); 286 | 287 | // Clear any trailing lines. 288 | for (i = y + 1; i < FPF_TEXTURE_HEIGHT; ++i) 289 | { 290 | FPF_memset(p_dst, 0x00, FPF_TEXTURE_WIDTH); 291 | p_dst = fpf_next_line(p_dst, line_pitch, 0, y_axis_direction); 292 | } 293 | 294 | return 0; 295 | } 296 | 297 | // Gets the [column, row] position of a character's glyph in the texture atlas. 298 | void fpf_get_glyph_position( 299 | const char character, // [in] Character to locate. 300 | unsigned int *const x, // [out] Column of the glyph. 301 | unsigned int *const y // [out] Row of the glyph. 302 | ) 303 | { 304 | const int ascii_value = (character < ' ' || character > '~') ? 127 : character; 305 | const int glyph_index = ascii_value - ' '; 306 | const unsigned int glyphs_per_row = FPF_TEXTURE_WIDTH / FPF_GLYPH_WIDTH; 307 | const int texture_row = glyph_index / glyphs_per_row; 308 | const int texture_column = glyph_index - (glyphs_per_row * texture_row); 309 | FPF_assert(NULL != x); 310 | FPF_assert(NULL != y); 311 | *x = texture_column * FPF_GLYPH_WIDTH; 312 | *y = texture_row * FPF_GLYPH_HEIGHT; 313 | } 314 | 315 | // Gets the texture coordinates of a character's glyph in the texture atlas. 316 | void fpf_get_glyph_dx_texture_coordinates( 317 | const char character, // [in] Character to locate. 318 | float *const left, // [out] Left bound of the character's glyph. 319 | float *const top, // [out] Top bound of the character's glyph. 320 | float *const right, // [out] Right bound of the character's glyph. 321 | float *const bottom // [out] Bottom bound of the character's glyph. 322 | ) 323 | { 324 | unsigned int x; 325 | unsigned int y; 326 | FPF_assert(NULL != left); 327 | FPF_assert(NULL != top); 328 | FPF_assert(NULL != right); 329 | FPF_assert(NULL != bottom); 330 | fpf_get_glyph_position(character, &x, &y); 331 | *left = (float)x / FPF_TEXTURE_WIDTH; 332 | *top = (float)y / FPF_TEXTURE_HEIGHT; 333 | *right = (float)(x + FPF_GLYPH_WIDTH) / FPF_TEXTURE_WIDTH; 334 | *bottom = (float)(y + FPF_GLYPH_HEIGHT) / FPF_TEXTURE_HEIGHT; 335 | } 336 | 337 | // Gets the texture coordinates of a character's glyph in the texture atlas. 338 | void fpf_get_glyph_gl_texture_coordinates( 339 | const char character, // [in] Character to locate. 340 | float *const left, // [out] Left bound of the character's glyph. 341 | float *const top, // [out] Top bound of the character's glyph. 342 | float *const right, // [out] Right bound of the character's glyph. 343 | float *const bottom // [out] Bottom bound of the character's glyph. 344 | ) 345 | { 346 | FPF_assert(NULL != left); 347 | FPF_assert(NULL != top); 348 | FPF_assert(NULL != right); 349 | FPF_assert(NULL != bottom); 350 | fpf_get_glyph_dx_texture_coordinates(character, left, top, right, bottom); 351 | *top = 1.0f - *top; 352 | *bottom = 1.0f - *bottom; 353 | } 354 | 355 | // Gets the [column, row] position of a cursor glyph in the texture atlas. 356 | void fpf_get_cursor_glyph_position( 357 | const fpf_cursor_style cursor_style, // [in] Cursor glyph style. 358 | unsigned int *const x, // [out] Column of the glyph. 359 | unsigned int *const y // [out] Row of the glyph. 360 | ) 361 | { 362 | const int glyph_index = 96 + 363 | ((cursor_style < FPF_UNDERLINE_CURSOR || cursor_style > FPF_VERTICAL_CURSOR) ? 364 | FPF_UNDERLINE_CURSOR : cursor_style); 365 | const unsigned int glyphs_per_row = FPF_TEXTURE_WIDTH / FPF_GLYPH_WIDTH; 366 | const int texture_row = glyph_index / glyphs_per_row; 367 | const int texture_column = glyph_index - (glyphs_per_row * texture_row); 368 | FPF_assert(NULL != x); 369 | FPF_assert(NULL != y); 370 | *x = texture_column * FPF_GLYPH_WIDTH; 371 | *y = texture_row * FPF_GLYPH_HEIGHT; 372 | } 373 | 374 | // Gets the texture coordinates of a cursor glyph in the texture atlas. 375 | void fpf_get_cursor_glyph_dx_texture_coordinates( 376 | const fpf_cursor_style cursor_style, // [in] Cursor glyph style. 377 | float *const left, // [out] Left bound of the character's glyph. 378 | float *const top, // [out] Top bound of the character's glyph. 379 | float *const right, // [out] Right bound of the character's glyph. 380 | float *const bottom // [out] Bottom bound of the character's glyph. 381 | ) 382 | { 383 | unsigned int x; 384 | unsigned int y; 385 | FPF_assert(NULL != left); 386 | FPF_assert(NULL != top); 387 | FPF_assert(NULL != right); 388 | FPF_assert(NULL != bottom); 389 | fpf_get_cursor_glyph_position(cursor_style, &x, &y); 390 | *left = (float)x / FPF_TEXTURE_WIDTH; 391 | *top = (float)y / FPF_TEXTURE_HEIGHT; 392 | *right = (float)(x + FPF_GLYPH_WIDTH) / FPF_TEXTURE_WIDTH; 393 | *bottom = (float)(y + FPF_GLYPH_HEIGHT) / FPF_TEXTURE_HEIGHT; 394 | } 395 | 396 | // Gets the texture coordinates of a cursor glyph in the texture atlas. 397 | void fpf_get_cursor_glyph_gl_texture_coordinates( 398 | const fpf_cursor_style cursor_style, // [in] Cursor glyph style. 399 | float *const left, // [out] Left bound of the character's glyph. 400 | float *const top, // [out] Top bound of the character's glyph. 401 | float *const right, // [out] Right bound of the character's glyph. 402 | float *const bottom // [out] Bottom bound of the character's glyph. 403 | ) 404 | { 405 | FPF_assert(NULL != left); 406 | FPF_assert(NULL != top); 407 | FPF_assert(NULL != right); 408 | FPF_assert(NULL != bottom); 409 | fpf_get_cursor_glyph_dx_texture_coordinates(cursor_style, left, top, right, bottom); 410 | *top = 1.0f - *top; 411 | *bottom = 1.0f - *bottom; 412 | } 413 | 414 | #endif // FPF_IMPLEMENT 415 | 416 | #endif // FIVEPIXELFONT_H 417 | --------------------------------------------------------------------------------