Get ready...
Do your work in your Odin directory: 3480/d/
Copy the starting files from Odin /home/fac/gordon/p/3480/code/lab13/*
Build the program: make
Run the program: ./a.out
Follow along with Gordon as we code...
Lab...
For this lab we need some text, but text rendering using a font is outside
the scope of this graphics course. We will create a texture-map image using
Gimp that stores our text using a font.
1. use gimp to create some text using a font
2. save it in a png file
3. bring the file into your 3480/d/ folder
Programming the curved text
Follow along with Gordon as we code...
1. pixel-first rendering
2. establish the components of a ring
3. check if pixel is inside the ring
4. deepness in the ring gives a y-value
5. angle around the ring gives an x-value
6. get data offset at data + ( (y*width*3) + (x*3) )
7. get RGB color components at data offset
8. draw the pixel
Lab work and Homework...
1. create your own text
2. use an image from one of your labs
3. highlight your image in a logo
Sample of Gordon's work...
This image was generated with lab13.cpp.
Post your own logo image on your project web page.
texture maps used:
//code from class...
//curved text
for (int i=0; i<g.yres; i++) {
for (int j=0; j<g.xres; j++) {
x11.set_color_3i(0, 0, 0);
x11.drawPoint(j, i);
double xc = g.xres/2.0;
double yc = g.yres/2.0;
double radius1 = 200.0;
double radius2 = 250.0;
double dx = xc - (double)j;
double dy = yc - (double)i;
double dist = sqrt(dx*dx + dy*dy);
if (dist >= radius1 && dist <= radius2) {
//distance tells us the text y-coordinate.
double ycoord = (dist - radius1) / (radius2 - radius1);
int row = (int)(ycoord * (double)text.h);
double angle = atan2(dy, dx);
//normalize the angle
angle = (angle + PI) * 0.5;
double xcoord = angle / PI;
int column = (int)(xcoord * (double)text.w);
column = text.w - column - 1;
//go get a text color.
//unsigned char *p = data + (row * w * 3 + column * 3);
unsigned char *p = text.data +
(row * text.w * 3 + column * 3);
int red = *(p+0);
int grn = *(p+1);
int blu = *(p+2);
if (red==255 && grn==255 && blu==255)
red = grn = blu = 0;
x11.set_color_3i(red,grn,blu);
x11.drawPoint(j, i);
}
}
//image in center
for (int i=0; i<g.yres; i++) {
for (int j=0; j<g.xres; j++) {
double xc = g.xres/2.0;
double yc = g.yres/2.0;
double radius0 = 160.0;
double dx = xc - (double)j;
double dy = yc - (double)i;
double dist = sqrt(dx*dx + dy*dy);
if (dist <= radius0) {
x11.set_color_3i(200, 50, 50);
x11.drawPoint(j, i);
double angle = atan2(dy, dx);
double howfar = dist / radius0;
double x0 = -cos(angle) * howfar * mani.w * 0.5;
double y0 = sin(angle) * howfar * mani.h * 0.5;
int x1 = (mani.w/2) + (int)x0;
int y1 = (mani.h/2) + (int)y0;
unsigned char *p = mani.data + (y1 * mani.w * 3 + x1 * 3);
int red = *(p+0);
int grn = *(p+1);
int blu = *(p+2);
x11.set_color_3i(red,grn,blu);
x11.drawPoint(j, i);
}
}
}
//Image class
#include <iostream>
#include <fstream>
using namespace std;
class Image {
public:
unsigned char *data;
int w, h;
Image(const char *fname) {
data = get_image_stream(fname);
}
unsigned char *get_image_stream(const char *fname) {
ifstream fin(fname);
char P, six;
fin >> P >> six;
cout << "P: " << P << " six: " << six << endl;
int width, height, max;
fin >> width >> height >> max;
cout << width << "x" << height << endl;
unsigned char *d = new unsigned char [width * height * 3];
fin.read((char *)d, width*height*3);
fin.close();
w = width;
h = height;
return d + 1;
}
}
text("text.ppm");
For a project...
Curved text can be brought into our lab-8 lab-9 ray trace programs, and applied
to a ring object much like we did in this lab.
Text can be curved across the top of an arch also.
Text can be transparent such as in the Ai logo above. The orange text is
slightly transparent.
In a our ray-tracers, the text of a texture-map can act as an object, with the
non-text areas discarded as non-hits similar to clipping. This allows you to
have the text itself cast a shadow or other effects.
Spherical texture-mapping...
The calculations to produce curved text are very similar to the calculations
needed in spherical texture-mapping.
• Going around the sphere is the texture-map x-value.
• Going up and down the sphere is the texture-map y-value.
The element of a sphere that determines up, down, and around is the
surface normal.
If you know the surface normal of a spot on the sphere, then you know how to
go get the texture-map color.
surface normal is a vector: { x, y, z }
y value is up/down
angle formed by x, z is right/left
What to turn in...
Gordon will collect your work.
3480/d/lab13.cpp the lab program
3480/d/Makefile the make file
3480/d/text.png your text to curve