9/19/2013
9/03/2013
OpenGL FOG simple. - NEHE-GL GLX
/*
* This code was created by Jeff Molofee '99
* (ported to Linux/GLX by Mihael Vrbanec '00)
*
* If you've found this code useful, please let me know.
*
* Visit Jeff at http://nehe.gamedev.net/
*
* or for port-specific comments, questions, bugreports etc.
* email to Mihael.Vrbanec@stud.uni-karlsruhe.de
*/
#include
#include
#include
#include
#include
#include
#include
/* stuff about our window grouped together */
typedef struct {
Display *dpy;
int screen;
Window win;
GLXContext ctx;
XSetWindowAttributes attr;
Bool fs;
XF86VidModeModeInfo deskMode;
int x, y;
unsigned int width, height;
unsigned int depth;
} GLWindow;
typedef struct {
int width;
int height;
unsigned char *data;
} textureImage;
/* attributes for a single buffered visual in RGBA format with at least
* 4 bits per color and a 16 bit depth buffer */
static int attrListSgl[] = {GLX_RGBA, GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_DEPTH_SIZE, 16,
None};
/* attributes for a double buffered visual in RGBA format with at least
* 4 bits per color and a 16 bit depth buffer */
static int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER,
GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_DEPTH_SIZE, 16,
None };
GLWindow GLWin;
Bool done;
Bool light; /* Lighting on/off */
GLfloat rotX; /* X Rotation */
GLfloat rotY; /* Y Rotation */
GLfloat speedX; /* X Rotation speed */
GLfloat speedY; /* Y Rotation speed */
GLfloat z; /* depth into the screen */
GLfloat lightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat lightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat lightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f };
GLuint filter; /* which filter to use */
GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR }; /* three types of fog */
GLuint fogFilter = 0; /* which fog to use */
GLfloat fogColor[] = { 0.5f, 0.5f, 0.5f, 1.0f }; /* fog color */
GLuint texture[3]; /* storage for three textures */
/* simple loader for 24bit bitmaps (data is in rgb-format) */
int loadBMP(char *filename, textureImage *texture)
{
FILE *file;
unsigned short int bfType;
int bfOffBits;
short int biPlanes;
short int biBitCount;
int biSizeImage;
int i;
unsigned char temp;
/* make sure the file is there and open it read-only (binary) */
if ((file = fopen(filename, "rb")) == NULL)
{
printf("File not found : %s\n", filename);
return 0;
}
if(!fread(&bfType, sizeof(short int), 1, file))
{
printf("Error reading file!\n");
return 0;
}
/* check if file is a bitmap */
if (bfType != 19778)
{
printf("Not a Bitmap-File!\n");
return 0;
}
/* get the file size */
/* skip file size and reserved fields of bitmap file header */
fseek(file, 8, SEEK_CUR);
/* get the position of the actual bitmap data */
if (!fread(&bfOffBits, sizeof(int), 1, file))
{
printf("Error reading file!\n");
return 0;
}
printf("Data at Offset: %d\n", bfOffBits);
/* skip size of bitmap info header */
fseek(file, 4, SEEK_CUR);
/* get the width of the bitmap */
fread(&texture->width, sizeof(int), 1, file);
printf("Width of Bitmap: %d\n", texture->width);
/* get the height of the bitmap */
fread(&texture->height, sizeof(int), 1, file);
printf("Height of Bitmap: %d\n", texture->height);
/* get the number of planes (must be set to 1) */
fread(&biPlanes, sizeof(short int), 1, file);
if (biPlanes != 1)
{
printf("Error: number of Planes not 1!\n");
return 0;
}
/* get the number of bits per pixel */
if (!fread(&biBitCount, sizeof(short int), 1, file))
{
printf("Error reading file!\n");
return 0;
}
printf("Bits per Pixel: %d\n", biBitCount);
if (biBitCount != 24)
{
printf("Bits per Pixel not 24\n");
return 0;
}
/* calculate the size of the image in bytes */
biSizeImage = texture->width * texture->height * 3;
printf("Size of the image data: %d\n", biSizeImage);
texture->data = malloc(biSizeImage);
/* seek to the actual data */
fseek(file, bfOffBits, SEEK_SET);
if (!fread(texture->data, biSizeImage, 1, file))
{
printf("Error loading file!\n");
return 0;
}
/* swap red and blue (bgr -> rgb) */
for (i = 0; i < biSizeImage; i += 3)
{
temp = texture->data[i];
texture->data[i] = texture->data[i + 2];
texture->data[i + 2] = temp;
}
return 1;
}
Bool loadGLTextures() /* Load Bitmaps And Convert To Textures */
{
Bool status;
textureImage *texti;
status = False;
texti = malloc(sizeof(textureImage));
if (loadBMP("Data/crate.bmp", texti))
{
status = True;
glGenTextures(3, &texture[0]); /* create three textures */
glBindTexture(GL_TEXTURE_2D, texture[0]);
/* actually generate the texture */
glTexImage2D(GL_TEXTURE_2D, 0, 3, texti->width, texti->height, 0,
GL_RGB, GL_UNSIGNED_BYTE, texti->data);
/* use no filtering */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
/* the second texture */
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, texti->width, texti->height, 0,
GL_RGB, GL_UNSIGNED_BYTE, texti->data);
/* use linear filtering */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
/* the third texture */
glBindTexture(GL_TEXTURE_2D, texture[2]);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texti->width,
texti->height, GL_RGB, GL_UNSIGNED_BYTE, texti->data);
/* use mipmapping */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
/* free the ram we used in our texture generation process */
if (texti)
{
if (texti->data)
free(texti->data);
free(texti);
}
return status;
}
/* function called when our window is resized (should only happen in window mode) */
void resizeGLScene(unsigned int width, unsigned int height)
{
if (height == 0) /* Prevent A Divide By Zero If The Window Is Too Small */
height = 1;
/* Reset The Current Viewport And Perspective Transformation */
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
}
/* general OpenGL initialization function */
int initGL(GLvoid)
{
if (!loadGLTextures())
{
return False;
}
glEnable(GL_TEXTURE_2D); /* Enable Texture Mapping */
glShadeModel(GL_SMOOTH);
/* clear to fog color */
glClearColor(fogColor[0], fogColor[1], fogColor[2], fogColor[3]);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
/* set up our lighting */
glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmbient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDiffuse);
glLightfv(GL_LIGHT1, GL_POSITION, lightPosition);
glEnable(GL_LIGHT1);
glFogi(GL_FOG_MODE, fogMode[fogFilter]);
glFogfv(GL_FOG_COLOR, fogColor);
glFogf(GL_FOG_DENSITY, 0.35f);
glHint(GL_FOG_HINT, GL_DONT_CARE);
glFogf(GL_FOG_START, 1.0f);
glFogf(GL_FOG_END, 5.0f);
glEnable(GL_FOG);
/* we use resizeGLScene once to set up our initial perspective */
resizeGLScene(GLWin.width, GLWin.height);
if (light)
glEnable(GL_LIGHTING);
glFlush();
return True;
}
/* Here goes our drawing code */
int drawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, z);
glRotatef(rotX, 1.0f, 0.0f, 0.0f); /* rotate on the X axis */
glRotatef(rotY, 0.0f, 1.0f, 0.0f); /* rotate on the Y axis */
glBindTexture(GL_TEXTURE_2D, texture[filter]); /* select our texture */
glBegin(GL_QUADS);
/* front face */
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
/* back face */
glNormal3f(0.0f, 0.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
/* right face */
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
/* left face */
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
/* top face */
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
/* bottom face */
glNormal3f(0.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glEnd();
/* change the rotation angles */
rotX += speedX;
rotY += speedY;
glXSwapBuffers(GLWin.dpy, GLWin.win);
return True;
}
/* function to release/destroy our resources and restoring the old desktop */
GLvoid killGLWindow(GLvoid)
{
if (GLWin.ctx)
{
if (!glXMakeCurrent(GLWin.dpy, None, NULL))
{
printf("Could not release drawing context.\n");
}
glXDestroyContext(GLWin.dpy, GLWin.ctx);
GLWin.ctx = NULL;
}
/* switch back to original desktop resolution if we were in fs */
if (GLWin.fs)
{
XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, &GLWin.deskMode);
XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
}
XCloseDisplay(GLWin.dpy);
}
/* this function creates our window and sets it up properly */
/* FIXME: bits is currently unused */
Bool createGLWindow(char* title, int width, int height, int bits,
Bool fullscreenflag)
{
XVisualInfo *vi;
Colormap cmap;
int dpyWidth, dpyHeight;
int i;
int glxMajorVersion, glxMinorVersion;
int vidModeMajorVersion, vidModeMinorVersion;
XF86VidModeModeInfo **modes;
int modeNum;
int bestMode;
Atom wmDelete;
Window winDummy;
unsigned int borderDummy;
GLWin.fs = fullscreenflag;
/* set best mode to current */
bestMode = 0;
/* get a connection */
GLWin.dpy = XOpenDisplay(0);
GLWin.screen = DefaultScreen(GLWin.dpy);
XF86VidModeQueryVersion(GLWin.dpy, &vidModeMajorVersion,
&vidModeMinorVersion);
printf("XF86VidModeExtension-Version %d.%d\n", vidModeMajorVersion,
vidModeMinorVersion);
XF86VidModeGetAllModeLines(GLWin.dpy, GLWin.screen, &modeNum, &modes);
/* save desktop-resolution before switching modes */
GLWin.deskMode = *modes[0];
/* look for mode with requested resolution */
for (i = 0; i < modeNum; i++)
{
if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height))
{
bestMode = i;
}
}
/* get an appropriate visual */
vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDbl);
if (vi == NULL)
{
vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl);
printf("Only Singlebuffered Visual!\n");
}
else
{
printf("Got Doublebuffered Visual!\n");
}
glXQueryVersion(GLWin.dpy, &glxMajorVersion, &glxMinorVersion);
printf("glX-Version %d.%d\n", glxMajorVersion, glxMinorVersion);
/* create a GLX context */
GLWin.ctx = glXCreateContext(GLWin.dpy, vi, 0, GL_TRUE);
/* create a color map */
cmap = XCreateColormap(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
vi->visual, AllocNone);
GLWin.attr.colormap = cmap;
GLWin.attr.border_pixel = 0;
if (GLWin.fs)
{
XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, modes[bestMode]);
XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
dpyWidth = modes[bestMode]->hdisplay;
dpyHeight = modes[bestMode]->vdisplay;
printf("Resolution %dx%d\n", dpyWidth, dpyHeight);
XFree(modes);
/* create a fullscreen window */
GLWin.attr.override_redirect = True;
GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
StructureNotifyMask;
GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual,
CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
&GLWin.attr);
XWarpPointer(GLWin.dpy, None, GLWin.win, 0, 0, 0, 0, 0, 0);
XMapRaised(GLWin.dpy, GLWin.win);
XGrabKeyboard(GLWin.dpy, GLWin.win, True, GrabModeAsync,
GrabModeAsync, CurrentTime);
XGrabPointer(GLWin.dpy, GLWin.win, True, ButtonPressMask,
GrabModeAsync, GrabModeAsync, GLWin.win, None, CurrentTime);
}
else
{
/* create a window in window mode*/
GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
StructureNotifyMask;
GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
CWBorderPixel | CWColormap | CWEventMask, &GLWin.attr);
/* only set window title and handle wm_delete_events if in windowed mode */
wmDelete = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True);
XSetWMProtocols(GLWin.dpy, GLWin.win, &wmDelete, 1);
XSetStandardProperties(GLWin.dpy, GLWin.win, title,
title, None, NULL, 0, NULL);
XMapRaised(GLWin.dpy, GLWin.win);
}
/* connect the glx-context to the window */
glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y,
&GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth);
printf("Depth %d\n", GLWin.depth);
if (glXIsDirect(GLWin.dpy, GLWin.ctx))
printf("Congrats, you have Direct Rendering!\n");
else
printf("Sorry, no Direct Rendering possible!\n");
if (!initGL())
{
printf("Could not initialize OpenGL.\nAborting...\n");
return False;
}
return True;
}
void keyPressed(KeySym key)
{
switch (key)
{
case XK_Escape:
done = True;
break;
case XK_F1:
killGLWindow();
GLWin.fs = !GLWin.fs;
createGLWindow("NeHe's Cool Looking Fog Tutorial",
640, 480, 24, GLWin.fs);
break;
case XK_f:
filter += 1;
if (filter > 2)
filter = 0;
break;
case XK_l:
light = !light;
if (!light)
glDisable(GL_LIGHTING);
else
glEnable(GL_LIGHTING);
break;
case XK_g:
fogFilter += 1;
if (fogFilter > 2)
{
fogFilter = 0;
}
glFogi(GL_FOG_MODE, fogMode[fogFilter]);
break;
case XK_Page_Up:
z -= 0.02f;
break;
case XK_Page_Down:
z += 0.02f;
break;
case XK_Up:
speedX -= 0.01f;
break;
case XK_Down:
speedX += 0.01f;
break;
case XK_Right:
speedY += 0.01f;
break;
case XK_Left:
speedY -= 0.01f;
break;
}
}
int main(int argc, char **argv)
{
XEvent event;
KeySym key;
done = False;
z = -5.0f; /* set the initial depth to 5 units */
filter = 0; /* initialize filter to no filter */
light = False;
/* default to fullscreen */
GLWin.fs = True;
if (!createGLWindow("NeHe's Cool Looking Fog Tutorial",
640, 480, 24, GLWin.fs))
{
done = True;
}
/* wait for events*/
while (!done)
{
/* handle the events in the queue */
while (XPending(GLWin.dpy) > 0)
{
XNextEvent(GLWin.dpy, &event);
switch (event.type)
{
case Expose:
if (event.xexpose.count != 0)
break;
drawGLScene();
break;
case ConfigureNotify:
/* call resizeGLScene only if our window-size changed */
if ((event.xconfigure.width != GLWin.width) ||
(event.xconfigure.height != GLWin.height))
{
GLWin.width = event.xconfigure.width;
GLWin.height = event.xconfigure.height;
printf("Resize event\n");
resizeGLScene(event.xconfigure.width,
event.xconfigure.height);
}
break;
/* exit in case of a mouse button press */
case ButtonPress:
done = True;
break;
case KeyPress:
key = XLookupKeysym(&event.xkey, 0);
keyPressed(key);
break;
case ClientMessage:
if (*XGetAtomName(GLWin.dpy, event.xclient.message_type)
== *"WM_PROTOCOLS")
{
printf("Exiting sanely...\n");
done = True;
}
break;
default:
break;
}
}
drawGLScene();
}
killGLWindow();
return 0;
}
* This code was created by Jeff Molofee '99
* (ported to Linux/GLX by Mihael Vrbanec '00)
*
* If you've found this code useful, please let me know.
*
* Visit Jeff at http://nehe.gamedev.net/
*
* or for port-specific comments, questions, bugreports etc.
* email to Mihael.Vrbanec@stud.uni-karlsruhe.de
*/
#include
#include
#include
#include
#include
#include
#include
/* stuff about our window grouped together */
typedef struct {
Display *dpy;
int screen;
Window win;
GLXContext ctx;
XSetWindowAttributes attr;
Bool fs;
XF86VidModeModeInfo deskMode;
int x, y;
unsigned int width, height;
unsigned int depth;
} GLWindow;
typedef struct {
int width;
int height;
unsigned char *data;
} textureImage;
/* attributes for a single buffered visual in RGBA format with at least
* 4 bits per color and a 16 bit depth buffer */
static int attrListSgl[] = {GLX_RGBA, GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_DEPTH_SIZE, 16,
None};
/* attributes for a double buffered visual in RGBA format with at least
* 4 bits per color and a 16 bit depth buffer */
static int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER,
GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_DEPTH_SIZE, 16,
None };
GLWindow GLWin;
Bool done;
Bool light; /* Lighting on/off */
GLfloat rotX; /* X Rotation */
GLfloat rotY; /* Y Rotation */
GLfloat speedX; /* X Rotation speed */
GLfloat speedY; /* Y Rotation speed */
GLfloat z; /* depth into the screen */
GLfloat lightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat lightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat lightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f };
GLuint filter; /* which filter to use */
GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR }; /* three types of fog */
GLuint fogFilter = 0; /* which fog to use */
GLfloat fogColor[] = { 0.5f, 0.5f, 0.5f, 1.0f }; /* fog color */
GLuint texture[3]; /* storage for three textures */
/* simple loader for 24bit bitmaps (data is in rgb-format) */
int loadBMP(char *filename, textureImage *texture)
{
FILE *file;
unsigned short int bfType;
int bfOffBits;
short int biPlanes;
short int biBitCount;
int biSizeImage;
int i;
unsigned char temp;
/* make sure the file is there and open it read-only (binary) */
if ((file = fopen(filename, "rb")) == NULL)
{
printf("File not found : %s\n", filename);
return 0;
}
if(!fread(&bfType, sizeof(short int), 1, file))
{
printf("Error reading file!\n");
return 0;
}
/* check if file is a bitmap */
if (bfType != 19778)
{
printf("Not a Bitmap-File!\n");
return 0;
}
/* get the file size */
/* skip file size and reserved fields of bitmap file header */
fseek(file, 8, SEEK_CUR);
/* get the position of the actual bitmap data */
if (!fread(&bfOffBits, sizeof(int), 1, file))
{
printf("Error reading file!\n");
return 0;
}
printf("Data at Offset: %d\n", bfOffBits);
/* skip size of bitmap info header */
fseek(file, 4, SEEK_CUR);
/* get the width of the bitmap */
fread(&texture->width, sizeof(int), 1, file);
printf("Width of Bitmap: %d\n", texture->width);
/* get the height of the bitmap */
fread(&texture->height, sizeof(int), 1, file);
printf("Height of Bitmap: %d\n", texture->height);
/* get the number of planes (must be set to 1) */
fread(&biPlanes, sizeof(short int), 1, file);
if (biPlanes != 1)
{
printf("Error: number of Planes not 1!\n");
return 0;
}
/* get the number of bits per pixel */
if (!fread(&biBitCount, sizeof(short int), 1, file))
{
printf("Error reading file!\n");
return 0;
}
printf("Bits per Pixel: %d\n", biBitCount);
if (biBitCount != 24)
{
printf("Bits per Pixel not 24\n");
return 0;
}
/* calculate the size of the image in bytes */
biSizeImage = texture->width * texture->height * 3;
printf("Size of the image data: %d\n", biSizeImage);
texture->data = malloc(biSizeImage);
/* seek to the actual data */
fseek(file, bfOffBits, SEEK_SET);
if (!fread(texture->data, biSizeImage, 1, file))
{
printf("Error loading file!\n");
return 0;
}
/* swap red and blue (bgr -> rgb) */
for (i = 0; i < biSizeImage; i += 3)
{
temp = texture->data[i];
texture->data[i] = texture->data[i + 2];
texture->data[i + 2] = temp;
}
return 1;
}
Bool loadGLTextures() /* Load Bitmaps And Convert To Textures */
{
Bool status;
textureImage *texti;
status = False;
texti = malloc(sizeof(textureImage));
if (loadBMP("Data/crate.bmp", texti))
{
status = True;
glGenTextures(3, &texture[0]); /* create three textures */
glBindTexture(GL_TEXTURE_2D, texture[0]);
/* actually generate the texture */
glTexImage2D(GL_TEXTURE_2D, 0, 3, texti->width, texti->height, 0,
GL_RGB, GL_UNSIGNED_BYTE, texti->data);
/* use no filtering */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
/* the second texture */
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, texti->width, texti->height, 0,
GL_RGB, GL_UNSIGNED_BYTE, texti->data);
/* use linear filtering */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
/* the third texture */
glBindTexture(GL_TEXTURE_2D, texture[2]);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texti->width,
texti->height, GL_RGB, GL_UNSIGNED_BYTE, texti->data);
/* use mipmapping */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
/* free the ram we used in our texture generation process */
if (texti)
{
if (texti->data)
free(texti->data);
free(texti);
}
return status;
}
/* function called when our window is resized (should only happen in window mode) */
void resizeGLScene(unsigned int width, unsigned int height)
{
if (height == 0) /* Prevent A Divide By Zero If The Window Is Too Small */
height = 1;
/* Reset The Current Viewport And Perspective Transformation */
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
}
/* general OpenGL initialization function */
int initGL(GLvoid)
{
if (!loadGLTextures())
{
return False;
}
glEnable(GL_TEXTURE_2D); /* Enable Texture Mapping */
glShadeModel(GL_SMOOTH);
/* clear to fog color */
glClearColor(fogColor[0], fogColor[1], fogColor[2], fogColor[3]);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
/* set up our lighting */
glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmbient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDiffuse);
glLightfv(GL_LIGHT1, GL_POSITION, lightPosition);
glEnable(GL_LIGHT1);
glFogi(GL_FOG_MODE, fogMode[fogFilter]);
glFogfv(GL_FOG_COLOR, fogColor);
glFogf(GL_FOG_DENSITY, 0.35f);
glHint(GL_FOG_HINT, GL_DONT_CARE);
glFogf(GL_FOG_START, 1.0f);
glFogf(GL_FOG_END, 5.0f);
glEnable(GL_FOG);
/* we use resizeGLScene once to set up our initial perspective */
resizeGLScene(GLWin.width, GLWin.height);
if (light)
glEnable(GL_LIGHTING);
glFlush();
return True;
}
/* Here goes our drawing code */
int drawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, z);
glRotatef(rotX, 1.0f, 0.0f, 0.0f); /* rotate on the X axis */
glRotatef(rotY, 0.0f, 1.0f, 0.0f); /* rotate on the Y axis */
glBindTexture(GL_TEXTURE_2D, texture[filter]); /* select our texture */
glBegin(GL_QUADS);
/* front face */
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
/* back face */
glNormal3f(0.0f, 0.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
/* right face */
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
/* left face */
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
/* top face */
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
/* bottom face */
glNormal3f(0.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glEnd();
/* change the rotation angles */
rotX += speedX;
rotY += speedY;
glXSwapBuffers(GLWin.dpy, GLWin.win);
return True;
}
/* function to release/destroy our resources and restoring the old desktop */
GLvoid killGLWindow(GLvoid)
{
if (GLWin.ctx)
{
if (!glXMakeCurrent(GLWin.dpy, None, NULL))
{
printf("Could not release drawing context.\n");
}
glXDestroyContext(GLWin.dpy, GLWin.ctx);
GLWin.ctx = NULL;
}
/* switch back to original desktop resolution if we were in fs */
if (GLWin.fs)
{
XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, &GLWin.deskMode);
XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
}
XCloseDisplay(GLWin.dpy);
}
/* this function creates our window and sets it up properly */
/* FIXME: bits is currently unused */
Bool createGLWindow(char* title, int width, int height, int bits,
Bool fullscreenflag)
{
XVisualInfo *vi;
Colormap cmap;
int dpyWidth, dpyHeight;
int i;
int glxMajorVersion, glxMinorVersion;
int vidModeMajorVersion, vidModeMinorVersion;
XF86VidModeModeInfo **modes;
int modeNum;
int bestMode;
Atom wmDelete;
Window winDummy;
unsigned int borderDummy;
GLWin.fs = fullscreenflag;
/* set best mode to current */
bestMode = 0;
/* get a connection */
GLWin.dpy = XOpenDisplay(0);
GLWin.screen = DefaultScreen(GLWin.dpy);
XF86VidModeQueryVersion(GLWin.dpy, &vidModeMajorVersion,
&vidModeMinorVersion);
printf("XF86VidModeExtension-Version %d.%d\n", vidModeMajorVersion,
vidModeMinorVersion);
XF86VidModeGetAllModeLines(GLWin.dpy, GLWin.screen, &modeNum, &modes);
/* save desktop-resolution before switching modes */
GLWin.deskMode = *modes[0];
/* look for mode with requested resolution */
for (i = 0; i < modeNum; i++)
{
if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height))
{
bestMode = i;
}
}
/* get an appropriate visual */
vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDbl);
if (vi == NULL)
{
vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl);
printf("Only Singlebuffered Visual!\n");
}
else
{
printf("Got Doublebuffered Visual!\n");
}
glXQueryVersion(GLWin.dpy, &glxMajorVersion, &glxMinorVersion);
printf("glX-Version %d.%d\n", glxMajorVersion, glxMinorVersion);
/* create a GLX context */
GLWin.ctx = glXCreateContext(GLWin.dpy, vi, 0, GL_TRUE);
/* create a color map */
cmap = XCreateColormap(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
vi->visual, AllocNone);
GLWin.attr.colormap = cmap;
GLWin.attr.border_pixel = 0;
if (GLWin.fs)
{
XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, modes[bestMode]);
XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
dpyWidth = modes[bestMode]->hdisplay;
dpyHeight = modes[bestMode]->vdisplay;
printf("Resolution %dx%d\n", dpyWidth, dpyHeight);
XFree(modes);
/* create a fullscreen window */
GLWin.attr.override_redirect = True;
GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
StructureNotifyMask;
GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual,
CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
&GLWin.attr);
XWarpPointer(GLWin.dpy, None, GLWin.win, 0, 0, 0, 0, 0, 0);
XMapRaised(GLWin.dpy, GLWin.win);
XGrabKeyboard(GLWin.dpy, GLWin.win, True, GrabModeAsync,
GrabModeAsync, CurrentTime);
XGrabPointer(GLWin.dpy, GLWin.win, True, ButtonPressMask,
GrabModeAsync, GrabModeAsync, GLWin.win, None, CurrentTime);
}
else
{
/* create a window in window mode*/
GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
StructureNotifyMask;
GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
CWBorderPixel | CWColormap | CWEventMask, &GLWin.attr);
/* only set window title and handle wm_delete_events if in windowed mode */
wmDelete = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True);
XSetWMProtocols(GLWin.dpy, GLWin.win, &wmDelete, 1);
XSetStandardProperties(GLWin.dpy, GLWin.win, title,
title, None, NULL, 0, NULL);
XMapRaised(GLWin.dpy, GLWin.win);
}
/* connect the glx-context to the window */
glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y,
&GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth);
printf("Depth %d\n", GLWin.depth);
if (glXIsDirect(GLWin.dpy, GLWin.ctx))
printf("Congrats, you have Direct Rendering!\n");
else
printf("Sorry, no Direct Rendering possible!\n");
if (!initGL())
{
printf("Could not initialize OpenGL.\nAborting...\n");
return False;
}
return True;
}
void keyPressed(KeySym key)
{
switch (key)
{
case XK_Escape:
done = True;
break;
case XK_F1:
killGLWindow();
GLWin.fs = !GLWin.fs;
createGLWindow("NeHe's Cool Looking Fog Tutorial",
640, 480, 24, GLWin.fs);
break;
case XK_f:
filter += 1;
if (filter > 2)
filter = 0;
break;
case XK_l:
light = !light;
if (!light)
glDisable(GL_LIGHTING);
else
glEnable(GL_LIGHTING);
break;
case XK_g:
fogFilter += 1;
if (fogFilter > 2)
{
fogFilter = 0;
}
glFogi(GL_FOG_MODE, fogMode[fogFilter]);
break;
case XK_Page_Up:
z -= 0.02f;
break;
case XK_Page_Down:
z += 0.02f;
break;
case XK_Up:
speedX -= 0.01f;
break;
case XK_Down:
speedX += 0.01f;
break;
case XK_Right:
speedY += 0.01f;
break;
case XK_Left:
speedY -= 0.01f;
break;
}
}
int main(int argc, char **argv)
{
XEvent event;
KeySym key;
done = False;
z = -5.0f; /* set the initial depth to 5 units */
filter = 0; /* initialize filter to no filter */
light = False;
/* default to fullscreen */
GLWin.fs = True;
if (!createGLWindow("NeHe's Cool Looking Fog Tutorial",
640, 480, 24, GLWin.fs))
{
done = True;
}
/* wait for events*/
while (!done)
{
/* handle the events in the queue */
while (XPending(GLWin.dpy) > 0)
{
XNextEvent(GLWin.dpy, &event);
switch (event.type)
{
case Expose:
if (event.xexpose.count != 0)
break;
drawGLScene();
break;
case ConfigureNotify:
/* call resizeGLScene only if our window-size changed */
if ((event.xconfigure.width != GLWin.width) ||
(event.xconfigure.height != GLWin.height))
{
GLWin.width = event.xconfigure.width;
GLWin.height = event.xconfigure.height;
printf("Resize event\n");
resizeGLScene(event.xconfigure.width,
event.xconfigure.height);
}
break;
/* exit in case of a mouse button press */
case ButtonPress:
done = True;
break;
case KeyPress:
key = XLookupKeysym(&event.xkey, 0);
keyPressed(key);
break;
case ClientMessage:
if (*XGetAtomName(GLWin.dpy, event.xclient.message_type)
== *"WM_PROTOCOLS")
{
printf("Exiting sanely...\n");
done = True;
}
break;
default:
break;
}
}
drawGLScene();
}
killGLWindow();
return 0;
}
8/01/2013
safe erase
psaudo
it = list1.begin();
while( it != list1.end() )
{
if( *it == (waste?) )
list1.erase(it++);
else
++it;
}
it = list1.begin();
while( it != list1.end() )
{
if( *it == (waste?) )
list1.erase(it++);
else
++it;
}
7/16/2013
Generating Mesh Shadows On Terrain Using OpenGL
Original post :
http://content.gpwiki.org/index.php/Generating_Mesh_Shadows_On_Terrain_Using_OpenGL
//
// complete function.
//
// unsigned char *lightmap
// int lightmapSize
// unsigned char shadowColor[3]
// float lightdir[3]
void MeshShadows(unsigned char *lightmap, int lightmapSize, unsigned char shadowColor[3], float lightDir[3]) { // variable initialization int lightmapChunkSize = 128; if(lightmapSize < lightmapChunkSize) lightmapChunkSize = lightmapSize; float terrainDivisions = lightmapSize / lightmapChunkSize; int terrainChunkSize = Terrain.size() / terrainDivisions; unsigned char *chunk = new unsigned char[(lightmapChunkSize)*(lightmapChunkSize)*3]; // create shadow texture GLuint shadowChunk; glGenTextures(1, &shadowChunk); glBindTexture(GL_TEXTURE_2D, shadowChunk); glEnable(GL_TEXTURE_2D); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, lightmapChunkSize, lightmapChunkSize, 0); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); int terrainCol = 0; int terrainRow = 0; float x0 = 0; float y0 = 0; float x1 = terrainChunkSize; float y1 = terrainChunkSize; for(terrainRow = 0; terrainRow < terrainDivisions; terrainRow++) { for(terrainCol = 0; terrainCol < terrainDivisions; terrainCol++) { // setup orthogonal view glViewport(0, 0, terrainChunkSize * Terrain.size(), terrainChunkSize * Terrain.size()); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, terrainChunkSize, 0, terrainChunkSize, -10000, 10000); glMatrixMode(GL_MODELVIEW); // apply light's direction to modelview matrix gluLookAt(lightDir[0], lightDir[1], lightDir[2], 0, 0, 0, 0, 1, 0); // loop through all vertices in terrain and find min and max points with respect to screen space float minX = 999999, maxX = -999999; float minY = 999999, maxY = -999999; double X, Y, Z; // get pointer to terrain vertices float *vertices = Terrain.vertices()->lock(); for(int i = y0-1; i < y1+1; i++) { if(i < 0) continue; for(int j = x0-1; j < x1+1; j++) { if(j < 0) continue; int index = i * Terrain.size() + j; // get screen coordinates for current vertex static GLint viewport[4]; static GLdouble modelview[16]; static GLdouble projection[16]; static GLfloat winX, winY, winZ; glGetDoublev( GL_MODELVIEW_MATRIX, modelview ); glGetDoublev( GL_PROJECTION_MATRIX, projection ); glGetIntegerv( GL_VIEWPORT, viewport ); gluProject(vertices[index*3+0], vertices[index*3+1], vertices[index*3+2], modelview, projection, viewport, &X, &Y, &Z); if(X < minX) minX = X; if(X > maxX) maxX = X; if(Y < minY) minY = Y; if(Y > maxY) maxY = Y; } } // clear min and max values static float minX2, minY2, maxX2, maxY2; minX2 = minX; minY2 = minY; maxX2 = maxX; maxY2 = maxY; // clear screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, lightmapChunkSize, lightmapChunkSize); // orient viewport so that terrain chunk fits inside glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(minX, maxX, minY, maxY, -10000, 10000); glMatrixMode(GL_MODELVIEW); // apply light's direction vector to model view transformation glLoadIdentity(); gluLookAt(lightDir[0], lightDir[1], lightDir[2], 0, 0, 0, 0, 1, 0); // disable writing to the color buffer glColorMask(false, false, false, false); // render terrain Terrain.render(); // enable writing to the color buffer glColorMask(true, true, true, true); // render scene meshes '''BLACK''' RenderAllSceneMeshes(); // bind shadowChunk texture and copy frame buffer data glBindTexture(GL_TEXTURE_2D, shadowChunk); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, lightmapChunkSize, lightmapChunkSize); glBindTexture(GL_TEXTURE_2D, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, terrainChunkSize * Terrain.size(), terrainChunkSize * Terrain.size()); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, 0, terrainChunkSize, terrainChunkSize, -10000, 10000); glMatrixMode(GL_MODELVIEW); // rotate view so that xz plane becomes the xy plane glLoadIdentity(); glRotatef(90, 1, 0, 0); // reset max and min values minX = minY = 999999; maxX = maxY = -999999; glGetDoublev( GL_MODELVIEW_MATRIX, modelview ); glGetDoublev( GL_PROJECTION_MATRIX, projection ); glGetIntegerv( GL_VIEWPORT, viewport ); // project each corner onto the screen // the corners are represented by the x0, y0, x1 and y1 values gluProject(x0, y0, modelview, projection, viewport, &X, &Y, &Z); if(X < minX) minX = X; if(X > maxX) maxX = X; if(Y < minY) minY = Y; if(Y > maxY) maxY = Y; gluProject(x1, y0, modelview, projection, viewport, &X, &Y, &Z); if(X < minX) minX = X; if(X > maxX) maxX = X; if(Y < minY) minY = Y; if(Y > maxY) maxY = Y; gluProject(x1, y1, modelview, projection, viewport, &X, &Y, &Z); if(X < minX) minX = X; if(X > maxX) maxX = X; if(Y < minY) minY = Y; if(Y > maxY) maxY = Y; gluProject(x0, y1, modelview, projection, viewport, &X, &Y, &Z); if(X < minX) minX = X; if(X > maxX) maxX = X; if(Y < minY) minY = Y; if(Y > maxY) maxY = Y; // resize and re-orient the viewport glViewport(0, 0, terrainChunkSize * Terrain.size(), terrainChunkSize * Terrain.size()); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(minX, minY, maxX, maxY, -10000, 10000); glMatrixMode(GL_MODELVIEW); // rotate view so that xz plane becomes the xy plane glLoadIdentity(); glRotatef(90, 1, 0, 0); // setup projective texturing float PS[] = {1, 0, 0, 0}; float PT[] = {0, 1, 0, 0}; float PR[] = {0, 0, 1, 0}; float PQ[] = {0, 0, 0, 1}; glTexGenfv(GL_S, GL_EYE_PLANE, PS); glTexGenfv(GL_T, GL_EYE_PLANE, PT); glTexGenfv(GL_R, GL_EYE_PLANE, PR); glTexGenfv(GL_Q, GL_EYE_PLANE, PQ); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_GEN_R); glEnable(GL_TEXTURE_GEN_Q); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); // setup texture matrix glBindTexture(GL_TEXTURE_2D, shadowChunk); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glTranslatef(0.5, 0.5, 0); glScalef(0.5, 0.5, 1); glOrtho(minX2, maxX2, minY2, maxY2, -10000, 10000); gluLookAt(lightDir[0], lightDir[1], lightDir[2], 0, 0, 0, 0, 1, 0); glMatrixMode(GL_MODELVIEW); // render the terrain Terrain.render(); glBindTexture(GL_TEXTURE_2D, shadowChunk); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, lightmapChunkSize, lightmapChunkSize); // disable projective texturing glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); glDisable(GL_TEXTURE_GEN_Q); // reset texture matrix glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); // get shadow texture data glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels); for(int a = 0; a < lightmapChunkSize; a++) { for(int b = 0; b < lightmapChunkSize; b++) { int a2 = a + lightmapChunkSize * terrainRow; int b2 = b + lightmapChunkSize * terrainCol; lightmap[(a2 * lightmapSize + b2) * 3 + 0] = pixels[(a * lightmapChunkSize + b) * 3 + 0]; lightmap[(a2 * lightmapSize + b2) * 3 + 1] = pixels[(a * lightmapChunkSize + b) * 3 + 1]; lightmap[(a2 * lightmapSize + b2) * 3 + 2] = pixels[(a * lightmapChunkSize + b) * 3 + 2]; } } } } // increment which section on the terrain we are looking at x0 += terrainChunkSize; x1 += terrainChunkSize; } x0 = 0; x1 = terrainChunkSize; y0 += terrainChunkSize; y1 += terrainChunkSize; } // free memory glDeleteTextures(1, &shadowTexture); delete [] pixels; }
7/15/2013
google admob adView
1. https://kr.admob.com/
2. https://developers.google.com/mobile-ads-sdk/
3. bottom adView.
default center AdView, ignored android:gravity attribute
2. https://developers.google.com/mobile-ads-sdk/
3. bottom adView.
default center AdView, ignored android:gravity attribute
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:id="@+id/adview"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
ads:adSize="BANNER"
ads:adUnitId="xxxxxxxxxxxxx"
android:gravity="bottom|center" >
피드 구독하기:
덧글 (Atom)
