Related
So I am trying to draw two triangles, but at the end I just get the white window without any triangles. I have set up the libraries correctly but I believe there could be a mistake somewhere in the code and since I am fairly new I cannot figure it out. The code complies with no errors or warnings, but the outcome is not what I have expected the window is white and there is no drawing shown in the window.
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <cstdlib>
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
int main(void)
{
GLFWwindow* window;
// initialize the library
if (!glfwInit())
{
return -1;
}
// Create a window and its context
window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "kk", NULL, NULL);
int screenWidth, screenHeight;
glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
if (!window)
{
glfwTerminate();
return -1;
}
// make the window's context current
glfwMakeContextCurrent(window);
glViewport(0, 0, screenWidth, screenHeight); //specifies part of the window OpenGL can draw on
glMatrixMode(GL_PROJECTION); //controls the camera
glLoadIdentity(); //put us at (0, 0, 0)
glOrtho(0, SCREEN_WIDTH, 0, SCREEN_HEIGHT, 0, 600); //cordinate system
glMatrixMode(GL_MODELVIEW); //defines how objects are trasformed
glLoadIdentity(); //put us at (0, 0, 0)
GLfloat first_triangle[] = {
0, 0, 0,
0,300,0,
200,300,0,
};
GLfloat second_triangle[] = {
200,300,0,
400,300,0,
400,600,0,
};
GLfloat color[] =
{
255,0,0,
0,255,0,
0,0,255
};
// Loop until the window is closed by the user
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
//OpenGL rendering
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, first_triangle); // points to the vertices to be used
glColorPointer(3, GL_FLOAT, 0, color); // color to be used
glDrawArrays(GL_TRIANGLES, 0, 3); // draw the vetices
glVertexPointer(3, GL_FLOAT, 0, second_triangle); // points to the vertices to be used
glColorPointer(3, GL_FLOAT, 0, color); // color to be used
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
};
}
You have to call glfwSwapBuffers and glfwPollEvents at the end of the application loop:
while (!glfwWindowShouldClose(window))
{
// [...]
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwSwapBuffers swaps the front and back buffers and causes the window to be updated.
glfwPollEvents process the events.
This is my texture
This is how it is showing up
I am only getting this distorted result when using array textures.
Do I need to create mipmaps?
I am using the wrong image type?
bmp's might bot be an idea for images but I am using for the time being for their simplicity.
Code
#include <iostream>
using namespace std;
#include <cstdlib>
#include <stdio.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
GLFWwindow* window;
#define WINDOW_HEIGHT 768
#define WINDOW_WIDTH 1024
#include "common/shaders.h"
#include "common/texture.h"
#include "common/controls.h"
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
static void error_callback(int error, const char* description);
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
int main(void)
{
if (!glfwInit()) {
fprintf( stderr, "Failed to initialize GLFW\n" );
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_OPENGL_PROFILE , GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Ortho", NULL, NULL);
if (!window) {
fprintf(stderr, "Failed to create window\n");
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
glfwSetErrorCallback(error_callback);
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
glfwSetCursorPos(window, WINDOW_WIDTH/2, WINDOW_HEIGHT/2);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
glfwTerminate();
exit(EXIT_FAILURE);
}
if (GL_EXT_texture_array){
fprintf(stderr, "GL_EXT_texture_array\n");
}
glClearColor(0.0f, 0.0f, 255.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
GLuint vai; // vertex array id
glGenVertexArrays(1, &vai);
glBindVertexArray(vai);
char vert[] = "shaders/triangles.vert";
char frag[] = "shaders/triangles.frag";
GLuint program = load_shaders(vert,frag);
GLuint matrix_id = glGetUniformLocation(program, "MVP");
GLuint texture_id = glGetUniformLocation(program, "material");
GLsizei width = 16;
GLsizei height = 16;
GLsizei layerCount = 2;
GLsizei mipLevelCount = 1;
unsigned char* data = bmp_data("tiles.bmp");
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D_ARRAY, texture_id);
//GLubyte texels[32] =
//{
////Texels for first image.
//0, 0, 0, 255,
//255, 0, 0, 255,
//0, 255, 0, 255,
//0, 0, 255, 255,
////Texels for second image.
//255, 255, 255, 255,
//255, 255, 0, 255,
//0, 255, 255, 255,
//255, 0, 255, 255,
//};
//glTexStorage3D(GL_TEXTURE_2D_ARRAY, mipLevelCount, GL_RGBA8, width, height, layerCount);
//glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, width, height, layerCount, GL_RGBA, GL_UNSIGNED_BYTE, texels);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 16);
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGB8, width, height, layerCount);
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, width, height, layerCount, GL_RGB, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
delete [] data;
GLuint vbo;
GLuint uvbo;
glGenBuffers(1, &vbo);
glGenBuffers(1, &uvbo);
// prep tile
GLfloat vertex[] = {
0, 1, 0,
1, 1, 0,
1, 0, 0,
0, 1, 0,
0, 0, 0,
1, 0, 0,
};
GLfloat uv[] = {
0.0f , 16.0f,
16.0f, 16.0f,
16.0f, 0.0f ,
0.0f , 16.0f,
0.0f , 0.0f ,
16.0f, 0.0f ,
};
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, uvbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(uv), uv, GL_STATIC_DRAW);
glUseProgram(program);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
computeMatricesFromInputs();
glm::mat4 ProjectionMatrix = getProjectionMatrix();
glm::mat4 ViewMatrix = getViewMatrix();
glm::mat4 ModelMatrix = glm::mat4(1.0);
glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;
glUniformMatrix4fv(matrix_id, 1, GL_FALSE, &MVP[0][0]);
glUniform1i(texture_id, 0);
// render tile
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glBindBuffer(GL_ARRAY_BUFFER, uvbo);
glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,0,(void*)0);
glDrawArrays(GL_TRIANGLES, 0, 2*3);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glDeleteProgram(program);
glDeleteVertexArrays(2, &vai);
glfwTerminate();
exit(EXIT_SUCCESS);
}
static void error_callback(int error, const char* description){
fputs(description, stderr);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods){
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, 1);
}
fragment shader
#version 400 core
in vec2 uv; // Interpolated values from the vertex shaders
out vec3 color; // Ouput data
uniform sampler2DArray material; // Values that stay constant for the whole mesh.
void main(){
color = texture(material,vec3(uv,0)).rgb;
}
vert shader
#version 400 core
layout(location = 0) in vec3 vertex_pos;
layout(location = 1) in vec2 vertex_uv;
out vec2 uv;
uniform mat4 MVP;
void main(){
gl_Position = MVP * vec4(vertex_pos,1);
uv = vertex_uv;
}
I ended up paying to get someone to solve this problem for me.
I needed to update my texture vertex's. Also I didn't need to call glPixelStorei so I remove that.
GLfloat vertex[] = {
0, 1, 0,
1, 1, 0,
1, 0, 0,
0, 1, 0,
0, 0, 0,
1, 0, 0,
};
A texture files boundaries (uv coordinates) are from 0.0 to 1.0 on the x and y axis. If you want to map the whole texture to a quad you set the four corners to the quad's four corners. The following image is a good example:
http://www.c-jump.com/bcc/common/Talk3/OpenGL/Wk07_texture/const_images/textureMap.png
I am trying to wrap a texture on a quad.
All I see is a white rectangle:
To load the texture I used freeimage.
I need help in order to fix this very simple demo:
#include <GL/glut.h>
#include <GL/gl.h>
#include <FreeImage.h>
#include <stdio.h>
GLfloat coordinates[] =
{
-0.5, 0.5, 1,
-0.5, -0.5, 0,
0.5, -0.5, 0,
0.5, 0.5, 0
};
GLfloat texCoords[] =
{
0, 1,
0, 0,
1, 0,
1, 1
};
BYTE* data;
FIBITMAP* bitmap;
GLuint texture;
void initGlutCallbacks();
void initGL();
void onReshape(int w, int h);
void display();
FIBITMAP* loadTexture(const char* fileName);
int main(int argc, char** argv){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(512, 512);
glutInitWindowPosition(64, 64);
glutCreateWindow("arrays");
initGlutCallbacks();
initGL();
// texture
bitmap = loadTexture("rufol.png");
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
data = FreeImage_GetBits(bitmap);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0,
GL_RGBA8, GL_UNSIGNED_BYTE,
data
);
// enable arrays
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// specifying data for the arrays
glVertexPointer
(
3, GL_FLOAT, 0, coordinates
);
glTexCoordPointer
(
2, GL_FLOAT, 0, texCoords
);
glutMainLoop();
}
void initGlutCallbacks(){
glutReshapeFunc(onReshape);
glutDisplayFunc(display);
}
void initGL(){
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(1.0);
glEnable ( GL_TEXTURE_2D );
}
void onReshape(int w, int h){
}
void display(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glDrawArrays(GL_QUADS, 0, 4);
glFlush();
glutSwapBuffers();
}
FIBITMAP* loadTexture(const char* fileName){
FIBITMAP *bitmap = FreeImage_Load(FIF_PNG, "rufol.png");
if(bitmap == 0) printf("error loading the image\n");
FIBITMAP *fbitmap = FreeImage_ConvertTo32Bits(bitmap);
FreeImage_Unload(bitmap);
return fbitmap;
}
As you can see I am not even using perspective. Also lighting is not enabled(I don't know if it is required to display textures). I have tested a very similar code but using colors for each vertex instead of texture coordinates and it worked. So I think it might be something wrong when loading the image.
Have you tried using GL_RGBA instead of GL_RGBA8 as second parameter (format)?
I'm having a problem rendering my sprite even though I have initialized glew.
Here's my code:
#include <glew.h>
#include <wglew.h>
#include <stdio.h>
#include <iostream>
#include <gl\GL.h>
#include <SDL.h>
#include "SDL_image.h"
GLuint _texturebufferID;
GLuint _vertexBufferID;
GLuint texturebufferID;
int SCREEN_WIDTH = 740;
int SCREEN_HEIGHT = 520;
int mode;
bool processing = true;
SDL_Surface* image;
SDL_Window* window;
SDL_Renderer* renderer;
SDL_GLContext context;
SDL_Surface* surface;
SDL_Event window_key;
typedef struct {
GLfloat positionCoordinates[3];
GLfloat textureCoordinates[2];
} Texture;
Texture vertices[] =
{
// | Pixels |--|coords|
{{1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
{{0.0f, 43.0f, 0.0f}, {0.0f, 1.0f}},
{{168.0f, 43.0f, 0.0f}, {1.0f, 1.0f}},
{{168.0f, 0.0f, 0.0f}, {1.0f, 0.0f}}
};
GLuint loadandbuffersprite(const char *filename)
{
image = IMG_Load(filename);
if (image->format->BytesPerPixel == 3)
{
mode = GL_RGB;
}
else if (image->format->BytesPerPixel == 4)
{
mode = GL_RGBA;
}
else
{
SDL_FreeSurface(image);
return 0;
}
glGenTextures(1, &texturebufferID);
glBindTexture(GL_TEXTURE_2D, texturebufferID);
glTexImage2D(GL_TEXTURE_2D, 0, mode, image->w, image->h,
0, mode, GL_UNSIGNED_BYTE, image->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
SDL_FreeSurface( image );
return texturebufferID;
}
void render()
{
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
glGenBuffers(1, &_vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,
GL_STATIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Texture), (GLvoid *)
offsetof(Texture, positionCoordinates));
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Texture), (GLvoid *)
offsetof(Texture, textureCoordinates));
glLoadIdentity();
_texturebufferID = loadandbuffersprite("hane_stand.png");
}
// |----------------------------------------|
// | Main function |
// |----------------------------------------|
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);
// Intialize everything.
window = SDL_CreateWindow
(
"render example",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
);
// Create window for rendering.
glewInit();
renderer = SDL_CreateRenderer(window, -1, 0);
context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, context);
SDL_GL_LoadLibrary( NULL );
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
// Clearing color
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
// Set viewport
// |----------------------------------------|
// | Game loop |
// |----------------------------------------|
while (processing)
{
glClear(GL_COLOR_BUFFER_BIT);
render();
glDrawArrays(GL_QUADS, 0, 4);
SDL_RenderPresent(renderer);
SDL_GL_SwapWindow(window);
}
glDeleteTextures( 1, &texturebufferID);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
It's just this problem that's been hammering my coding progression for months and really need help. Anyone have any ideas on how I could fix this?
As for my computer information I use a Toshiba satellite with an AMD C-50 Processor and 2.0 GB of RAM.
I'm using SDL_ttf for rendering text with OpenGL. However, I'm getting nasty artifacts at edges of text:
Here's the code:
#include <string>
#include "SDL.h"
#include "SDL_opengl.h"
#include <SDL_ttf.h>
using namespace std;
#define WINDOW_WIDTH 1280
#define WINDOW_HEIGHT 1024
struct Color
{
unsigned char R, G, B, A;
Color(unsigned char r, unsigned char g, unsigned char b, unsigned char a) :
R(r), G(g), B(b), A(a)
{}
};
void DrawRectangle(int left, int right, int top, int bottom, Color c, GLuint Texture);
void DrawTextGL(int left, int top, TTF_Font* font, string text);
GLuint SDLSurfaceToTexture(SDL_Surface* surface);
int main(int argc, char** argv)
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Surface* screen = SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 32, SDL_OPENGL);
TTF_Init();
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
glEnable(GL_TEXTURE_2D);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, WINDOW_WIDTH, WINDOW_HEIGHT, 0.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Enabling transparency
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
SDL_Surface* temp = SDL_LoadBMP("New Bitmap Image.bmp");
GLuint WhiteTexture = SDLSurfaceToTexture(temp);
TTF_Font* Font;
Font = TTF_OpenFont("FreeSerif.ttf", 36);
DrawRectangle(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, Color(0, 0, 0, 255), WhiteTexture);
SDL_GL_SwapBuffers();
DrawTextGL(300, 300, Font, "graveyard");
DrawTextGL(600, 600, Font, "graveyard");
SDL_GL_SwapBuffers();
system("pause");
SDL_Quit();
return 0;
}
void DrawRectangle(int left, int right, int top, int bottom, Color c, GLuint Texture)
{
glBindTexture(GL_TEXTURE_2D, Texture);
glColor4f(c.R/255.0f, c.G/255.0f, c.B/255.0f, c.A/255.0f);
glBegin(GL_QUADS);
//Top-left vertex (corner)
glTexCoord2i(0, 0);
glVertex2f(GLfloat(left), GLfloat(top));
//Top-right vertex (corner)
glTexCoord2i(1, 0);
glVertex2f(GLfloat(right), GLfloat(top));
//Bottom-right vertex (corner)
glTexCoord2i(1, 1);
glVertex2f(GLfloat(right), GLfloat(bottom));
//Bottom-left vertex (corner)
glTexCoord2i(0, 1);
glVertex2f(GLfloat(left), GLfloat(bottom));
glEnd();
}
void DrawTextGL(int left, int top, TTF_Font* font, string text)
{
SDL_Color color = {255, 255, 255, 255};
SDL_Surface* textSurface;
textSurface = TTF_RenderText_Blended(font, text.c_str(), color);
GLuint Texture = SDLSurfaceToTexture(textSurface);
DrawRectangle(left, left + 260, top, top + 80, Color(255, 255, 255, 255), Texture);
SDL_FreeSurface(textSurface);
glDeleteTextures(1, &Texture);
}
GLuint SDLSurfaceToTexture(SDL_Surface* surface)
{
GLuint texture;
GLint nOfColors;
GLenum texture_format;
// get the number of channels in the SDL surface
nOfColors = surface->format->BytesPerPixel;
if (nOfColors == 4) // contains an alpha channel
{
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGBA;
else
texture_format = GL_BGRA;
}
else if (nOfColors == 3)
{
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGB;
else
texture_format = GL_BGR;
}
else
{
printf("Picture with less than 24-bit color depth detected.\n");
return 0;
}
// Have OpenGL generate a texture object handle for us
glGenTextures(1, &texture);
// Bind the texture object
glBindTexture(GL_TEXTURE_2D, texture);
// Set the texture's stretching properties
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Edit the texture object's image data using the information SDL_Surface gives us
glTexImage2D(GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
texture_format, GL_UNSIGNED_BYTE, surface->pixels);
// Bind the texture to which subsequent calls refer to
glBindTexture(GL_TEXTURE_2D, texture);
return texture;
}
"New Bitmap Image.bmp" is just a bitmap with one white pixel in it. "FreeSerif.ttf" is a font taken from here.