> I want to make a cuboid look like a block of wood by applying
> a woody image to it's surfaces. I know from Erco's Cheat Page
> how to apply a texture to a surface but I don't know how to
> make that texture be an image that is loaded from a file.
OK - here's Greg's previous example from a few days ago, tweaked up to
load an image from a file and use that as the texture.
This is not the most elegant solution possible, but should show you how
to proceed. This is a complete example, compiled using fltk-config as
shown.
The big challenge is probably fixing all the wrapped lines that Outlook
will have applied...
Also, the code has no error checking or etc, so that is left as an
exercise...
HTH,
--
Ian
---------------------------------------
// Tweak Greg's cube example to add an image texture
// fltk-config --use-gl --use-images --compile gl_texture_cube.cxx
#include <stdio.h>
#include <math.h>
#include <FL/Fl.h>
#include <FL/Fl_Window.h>
#include <FL/Fl_Gl_Window.h>
#include <FL/gl.h>
#include <FL/Fl_Shared_Image.H>
#define WIN_W 400 // window width
#define WIN_H 400 // window height
#define TEX_W 64 // texturemap width
#define TEX_H 64 // texturemap height
#define FPS (1.0/24.0) // frames per second playback
Fl_Shared_Image *img = NULL; // Holds a loaded image, PNG, JPEG, etc.
const char *datap = NULL; // points to the raw image data
//
// OpenGL class to show texturemapped cube
//
class MyGlWindow : public Fl_Gl_Window {
double spin;
GLuint TexID;
// TIMER CALLBACK
// Handles rotation the object
//
static void Timer_CB(void *userdata) {
MyGlWindow *mygl = (MyGlWindow*)userdata;
mygl->spin += 2.0; // spin
mygl->redraw();
Fl::repeat_timeout(FPS, Timer_CB, userdata);
}
public:
// CTOR
MyGlWindow(int x,int y,int w,int h,const char *l=0) :
Fl_Gl_Window(x,y,w,h,l) {
spin = 0.0;
Fl::add_timeout(FPS, Timer_CB, (void*)this); // 24fps
timer
}
// PERSPECTIVE VIEW
// Same as gluPerspective()..
//
void Perspective(GLdouble fovy, GLdouble aspect, GLdouble zNear,
GLdouble zFar) {
GLdouble xmin, xmax, ymin, ymax;
ymax = zNear * tan(fovy * M_PI / 360.0);
ymin = -ymax;
xmin = ymin * aspect;
xmax = ymax * aspect;
glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
}
// RESHAPED VIEWPORT
// OpenGL stuff to do whenever window changes size
//
void ReshapeViewport() {
// Viewport
glViewport(0, 0, w(), h());
// Projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLfloat ratio = w() / h();
Perspective(30.0, 1.0*ratio, 1.0, 30.0);
glTranslatef(0.0, 0.0, -8.0);
// Model view
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// OPENGL INITIALIZATION
// OpenGL stuff to do *only once* on startup.
//
void GlInit() {
// Make sure we only do this once
static int first_time = 1;
if ( first_time ) {
first_time = 0;
// Texture Map Init
GLubyte glimg[TEX_W][TEX_H][3]; // after glTexImage2D(),
array is no longer needed
glGenTextures(1, &TexID);
glBindTexture(GL_TEXTURE_2D, TexID);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
// use actual texture colors
if(img) // we have loaded an image to use as a
texture
{
int idx = 0;
for (int x=0; x<TEX_W; x++) {
for (int y=0; y<TEX_H; y++) {
glimg[x][y][0] =
(GLubyte)datap[idx++]; // R - probably?
glimg[x][y][1] =
(GLubyte)datap[idx++]; // G
glimg[x][y][2] =
(GLubyte)datap[idx++]; // B
}
}
}
else // fallback to using the checkerboard
{
for (int x=0; x<TEX_W; x++) {
for (int y=0; y<TEX_H; y++) {
GLubyte c =
((x&16)^(y&16)) ? 255 : 0; // checkerboard
glimg[x][y][0] = c;
glimg[x][y][1] = c;
glimg[x][y][2] = c;
}
}
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEX_W, TEX_H, 0,
GL_RGB, GL_UNSIGNED_BYTE, &glimg[0][0][0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
glEnable(GL_TEXTURE_2D);
// Misc OpenGL settings
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
}
}
// FLTK DRAW
// Called by FLTK to draw the scene.
//
void draw() {
// Initialize/handle reshaped viewport
if ( !valid() ) {
valid(1);
GlInit();
ReshapeViewport();
}
// Clear
glClearColor(.5,.5,.5, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Setup model matrix
glLoadIdentity();
glRotatef(spin, 0.5, 1.0, 0.0); // show all sides of cube
// Draw cube with texture assigned to each face
glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); //
Top Left Of The Texture and Quad
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); //
Top Right Of The Texture and Quad
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0); //
Bottom Right Of The Texture and Quad
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0); //
Bottom Left Of The Texture and Quad
// Back Face
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, -1.0); //
Top Left Of The Texture and Quad
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0); //
Top Right Of The Texture and Quad
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); //
Bottom Right Of The Texture and Quad
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0); //
Bottom Left Of The Texture and Quad
// Top Face
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0); //
Top Left Of The Texture and Quad
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0); //
Top Right Of The Texture and Quad
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, 1.0); //
Bottom Right Of The Texture and Quad
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 1.0); //
Bottom Left Of The Texture and Quad
// Bottom Face
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0); //
Top Left Of The Texture and Quad
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0); //
Top Right Of The Texture and Quad
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0); //
Bottom Right Of The Texture and Quad
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0); //
Bottom Left Of The Texture and Quad
// Right face
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); //
Top Left Of The Texture and Quad
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0); //
Top Right Of The Texture and Quad
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0); //
Bottom Right Of The Texture and Quad
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0); //
Bottom Left Of The Texture and Quad
// Left Face
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0); //
Top Left Of The Texture and Quad
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); //
Top Right Of The Texture and Quad
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0); //
Bottom Right Of The Texture and Quad
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); //
Bottom Left Of The Texture and Quad
glEnd();
// DEBUG: CHECK FOR ERRORS
GLenum err = glGetError();
if ( err != GL_NO_ERROR ) {
fprintf(stderr, "GLGETERROR=%d\n", (int)err);
}
}
};
/***********************************************************************
*/
void load_file(const char *n) {
if (img) img->release();
img = Fl_Shared_Image::get(n);
if (!img) {
puts("Image file format not recognized!");
fflush(stdout);
return;
}
if (img->w() > TEX_W || img->h() > TEX_H) {
Fl_Image *temp;
if (img->w() > img->h()) temp = img->copy(TEX_W, TEX_H *
img->h() / img->w());
else temp = img->copy(TEX_W * img->w() / img->h(),
TEX_H);
img->release();
img = (Fl_Shared_Image *)temp;
}
} // load_file
/***********************************************************************
*/
int main(int argc, char *argv[]) {
fl_register_images();
if (argv[1]) {
load_file(argv[1]);
datap = img->data()[0];
}
MyGlWindow* mygl = new MyGlWindow(10, 10, WIN_W-20, WIN_H-20,
"Texture Test");
mygl->end();
mygl->show();
return Fl::run();
}
/* end of file */
SELEX Sensors and Airborne Systems Limited
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14
3EL
A company registered in England & Wales. Company no. 02426132
********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk