PMG https://forum.pmg.org.ru/ |
|
Помощь GLULookAt https://forum.pmg.org.ru/viewtopic.php?f=1&t=9456 |
Страница 1 из 1 |
Автор: | Илья Остапишен [ 08 апр 2013 21:40 ] |
Заголовок сообщения: | Помощь GLULookAt |
В-общем я написал этот код. Цель этого кода - крутить головой во все стороны. Код: #include <stdio.h> #include <stdlib.h> #include <GL/glx.h> #include <GL/gl.h> #include <GL/glu.h> #include <X11/extensions/xf86vmode.h> #include <X11/keysym.h> GLfloat eye1 = 0.0; GLfloat eye2 = 0.0; GLfloat eye3 = 0.0; GLfloat center1 = -5.0; /* - */ GLfloat center2 = 1.5; /* | */ GLfloat center3 = -10.0; GLfloat vector1 = 0.0; GLfloat vector2 = 1.0; GLfloat vector3 = 0.0; /* 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; int rotDown, rotUp; /* 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; GLfloat rotX; /* X Rotation */ GLfloat rotY; /* Y Rotation */ GLfloat rotZ; /* Z Rotation */ GLuint texture[1]; /* Storage For One Texture */ /* simple loader for 24bit bitmaps (data is in rgb-format) */ int loadBMP(char *filename, textureImage *texture) { FILE *file; unsigned short int bfType; long int bfOffBits; short int biPlanes; short int biBitCount; long 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(long int), 1, file)) { printf("Error reading file!\n"); return 0; } printf("Data at Offset: %ld\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: %ld\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/texture.bmp", texti)) { status = True; glGenTextures(1, &texture[0]); /* create the texture */ 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); /* enable linear filtering */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 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); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); /* we use resizeGLScene once to set up our initial perspective */ resizeGLScene(GLWin.width, GLWin.height); glFlush(); return True; } /* Here goes our drawing code */ int drawGLScene(GLvoid) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(eye1, eye2, eye3, center1, center2, center3, vector1, vector2, vector3); glBindTexture(GL_TEXTURE_2D, texture[0]); /* select our texture */ glBegin(GL_QUADS); /* front face */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 += 0.3f; rotY += 0.2f; rotZ += 0.4f; 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 */ 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("3D Room", 800, 800, 24, GLWin.fs); break; case XK_Up: center2 += 0.3; break; case XK_Down: center2 -= 0.3; break; case XK_Right: center1 += 0.3; break; case XK_Left: center1 -= 0.3; break; } } int main(int argc, char *argv[]) { XEvent event; KeySym key; int c; done = False; /* check for --fullscreen option */ if (argc > 1 && (*++argv)[0] == '-') switch ( c = *++argv[0]) case 'f': GLWin.fs = True; if (!createGLWindow("3D Room", 800, 600, 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; } Управление стрелками, но когда я далеко разворачиваюсь в сторону или вверх, то это движение стает плавным и останавливается. Как сделать чтобы я мог крутить камерой без ограничений, как в Quake, например. Код под Linux (GLX) |
Автор: | RomaSoft [ 10 апр 2013 19:14 ] |
Заголовок сообщения: | Re: Помощь GLULookAt |
Есть хороший пример камеры http://rghost.ru/45189355 |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |