⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 underwater.c

📁 嵌入式GUI OpenGL源代码。OpenGL是嵌入式开发中常用的一种GUI系统。
💻 C
📖 第 1 页 / 共 2 页
字号:

void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(40.0, /* field of view in degree */
     (GLfloat) w/(GLfloat) h, /* aspect ratio */
     20.0, /* Z near */
     100.0); /* Z far */
   glMatrixMode(GL_MODELVIEW);
}

void
idle(void)
{
  /* Advance the caustic pattern. */
  currentCaustic = (currentCaustic + causticIncrement) % NUM_PATTERNS;
  glutPostRedisplay();
}

void
updateIdleFunc(void)
{
  /* Must be both displaying the caustic patterns and have the
     caustics in rippling motion to need an idle callback. */
  if (showCaustics && causticMotion) {
    glutIdleFunc(idle);
  } else {
    glutIdleFunc(NULL);
  }
}

void 
visible(int vis)
{
  /* Stop the animation when the window is not visible. */
  if (vis == GLUT_VISIBLE)
    updateIdleFunc();
  else
    glutIdleFunc(NULL);
}

/* ARGSUSED2 */
static void
mouse(int button, int state, int x, int y)
{
  /* Rotate the scene with the left mouse button. */
  if (button == GLUT_LEFT_BUTTON) {
    if (state == GLUT_DOWN) {
      moving = 1;
      startx = x;
      starty = y;
    }
    if (state == GLUT_UP) {
      moving = 0;
    }
  }
  /* Rotate the light position with the middle mouse button. */
  if (button == GLUT_MIDDLE_BUTTON) {
    if (state == GLUT_DOWN) {
      lightMoving = 1;
      lightStartX = x;
      lightStartY = y;
    }
    if (state == GLUT_UP) {
      lightMoving = 0;
    }
  }
}

/* ARGSUSED1 */
static void
motion(int x, int y)
{
  if (moving) {
    angle = angle + (x - startx);
    angle2 = angle2 + (y - starty);
    startx = x;
    starty = y;
    glutPostRedisplay();
  }
  if (lightMoving) {
    lightAngle += (x - lightStartX)/40.0;
    lightHeight += (lightStartY - y)/20.0;
    lightStartX = x;
    lightStartY = y;
    glutPostRedisplay();
  }
}

/* ARGSUSED1 */
static void
keyboard(unsigned char c, int x, int y)
{
  switch (c) {
  case 27:  /* Escape quits. */
    exit(0);
    break;
  case 'R':  /* Simplistic benchmarking. */
  case 'r':
    reportSpeed = !reportSpeed;
    break;
  case ' ':  /* Spacebar toggles caustic rippling motion. */
    causticMotion = !causticMotion;
    updateIdleFunc();
    break;
  }
}

void
menuSelect(int value)
{
  switch (value) {
  case M_POSITIONAL:
    directionalLight = 0;
    break;
  case M_DIRECTIONAL:
    directionalLight = 1;
    break;
  case M_GREENISH_LIGHT:
    lightDiffuseColor[0] = 1.0;
    lightDiffuseColor[1] = 1.5;  /* XXX Green = 1.5 */
    lightDiffuseColor[2] = 1.0;
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuseColor);
    break;
  case M_WHITE_LIGHT:
    lightDiffuseColor[0] = 1.5;  /* XXX Red = 1.5 */
    lightDiffuseColor[1] = 1.5;  /* XXX Green = 1.5 */
    lightDiffuseColor[2] = 1.5;  /* XXX Blue = 1.5 */
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuseColor);
    break;
  case M_WITH_CAUSTICS:
    showCaustics = 1;
    updateIdleFunc();
    break;
  case M_NO_CAUSTICS:
    showCaustics = 0;
    updateIdleFunc();
    break;
  case M_SWITCH_MODEL:
    object = (object + 1) % 3;
    break;
  case M_INCREASE_RIPPLE_SIZE:
    causticScale /= 1.5;
    break;
  case M_DECREASE_RIPPLE_SIZE:
    causticScale *= 1.5;
    break;
  }
  glutPostRedisplay();
}

int
main(int argc, char **argv)
{
  int width, height;
  int i;
  GLubyte *imageData;

  glutInit(&argc, argv);
  for (i=1; i<argc; i++) {
    if (!strcmp("-lesstex", argv[i])) {
      /* Only use 16 caustic textures.  Saves texture memory and works
	 better on slow machines. */
      causticIncrement = 2;
    } else if (!strcmp("-evenlesstex", argv[i])) {
      /* Only use 8 caustic textures.  Saves even more texture memory for
	 slow machines.  Temporal rippling suffers. */
      causticIncrement = 4;
    } else if (!strcmp("-nomipmap", argv[i])) {
      /* Don't use linear mipmap linear texture filtering; instead
	 use linear filtering. */
      useMipmaps = 0;
    } else if (!strcmp("-fullscreen", argv[i])) {
      fullscreen = 1;
    } else {
      fprintf(stderr, "usage: caustics [-lesstex]\n");
      fprintf(stderr, "       -lesstex uses half the caustic textures.\n");
      fprintf(stderr, "       -evenlesstex uses one fourth of the caustic textures.\n");
      exit(1);
    }
  }

  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
  if (fullscreen) {
    glutGameModeString("800x600:16@60");
    glutEnterGameMode();
  } else {
    glutCreateWindow("underwater");
  }

  /* Check that renderer has the GL_EXT_texture_object
     extension or supports OpenGL 1.1 */
#ifdef TEXTURE_OBJECT
  {
    char *version = (char *) glGetString(GL_VERSION);
    if (glutExtensionSupported("GL_EXT_texture_object")
      || strncmp(version, "1.1", 3) == 0) {
      HaveTexObj = GL_TRUE;
    }
  }
#endif

  glEnable(GL_TEXTURE_2D);
#ifdef TEXTURE_OBJECT  /* Replace texture environment not in OpenGL 1.0. */
  if (HaveTexObj)
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
#endif

  /* Load the caustic ripple textures. */
  printf("loading caustics:");
  for (i=0; i<NUM_PATTERNS; i += causticIncrement) {
    char filename[80];

    sprintf(filename, "caust%02d.bw", i);
    printf(" %d", i);
    fflush(stdout);
    imageData = read_alpha_texture(filename, &width, &height);
    if (imageData == NULL) {
      fprintf(stderr, "\n%s: could not load image file\n", filename);
      exit(1);
    }
    if (HaveTexObj)
      glBindTexture(GL_TEXTURE_2D, i+1);
    else
      glNewList(i+101, GL_COMPILE);
    if (useMipmaps) {
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      gluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE, width, height,
        GL_LUMINANCE, GL_UNSIGNED_BYTE, imageData);
    } else {
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, height, width, 0,
        GL_LUMINANCE, GL_UNSIGNED_BYTE, imageData);
    }
    free(imageData);
    if (!HaveTexObj)
      glEndList();
  }
  printf(".\n");

  /* Load an RGB file for the floor texture. */
  printf("loading RGB textures: floor");
  fflush(stdout);
  imageData = read_rgb_texture(FLOOR_FILE, &width, &height);
  if (imageData == NULL) {
    fprintf(stderr, "%s: could not load image file\n", FLOOR_FILE);
    exit(1);
  }
  printf(".\n");

  if (HaveTexObj)
    glBindTexture(GL_TEXTURE_2D, 100);
  else
    glNewList(100, GL_COMPILE);
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  if (useMipmaps) {
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB,
      GL_UNSIGNED_BYTE, imageData);
  } else {
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0,
      GL_RGB, GL_UNSIGNED_BYTE, imageData);
  }
  free(imageData);
  if (!HaveTexObj)
    glEndList();

  glMatrixMode(GL_MODELVIEW);
  gluLookAt(0.0, 8.0, 60.0,  /* eye is at (0,8,60) */
    0.0, 8.0, 0.0,      /* center is at (0,8,0) */
    0.0, 1.0, 0.);      /* up is in postivie Y direction */

  /* Setup initial OpenGL rendering state. */
  glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuseColor);
  glEnable(GL_LIGHT0);
  glEnable(GL_LIGHTING);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_CULL_FACE);

  /* Register assorted GLUT callback routines. */
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);
  glutVisibilityFunc(visible);
  glutMouseFunc(mouse);
  glutMotionFunc(motion);
  glutKeyboardFunc(keyboard);

  /* Create a pop-up menu. */
  if (!fullscreen) {
    glutCreateMenu(menuSelect);
    glutAddMenuEntry("Positional light", M_POSITIONAL);
    glutAddMenuEntry("Directional light", M_DIRECTIONAL);
    glutAddMenuEntry("Greenish light", M_GREENISH_LIGHT);
    glutAddMenuEntry("White light", M_WHITE_LIGHT);
    glutAddMenuEntry("With caustics", M_WITH_CAUSTICS);
    glutAddMenuEntry("No caustics", M_NO_CAUSTICS);
    glutAddMenuEntry("Switch model", M_SWITCH_MODEL);
    glutAddMenuEntry("Increase ripple size", M_INCREASE_RIPPLE_SIZE);
    glutAddMenuEntry("Decrease ripple size", M_DECREASE_RIPPLE_SIZE);
    glutAttachMenu(GLUT_RIGHT_BUTTON);
  }

  /* For rendering the MODEL_DINO object. */
  dinoDisplayList = makeDinosaur();

  /* Enter GLUT's main loop; callback dispatching begins. */
  glutMainLoop();
  return 0;             /* ANSI C requires main to return int. */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -