You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

143 line
3.0 KiB

  1. //
  2. // Deus Hax (working title)
  3. // Copyright (c) 2010 Sam Hocevar <sam@hocevar.net>
  4. //
  5. #if defined HAVE_CONFIG_H
  6. # include "config.h"
  7. #endif
  8. #include <cmath>
  9. #ifdef WIN32
  10. # define WIN32_LEAN_AND_MEAN
  11. # include <windows.h>
  12. #endif
  13. #if defined __APPLE__ && defined __MACH__
  14. # include <OpenGL/gl.h>
  15. #else
  16. # define GL_GLEXT_PROTOTYPES
  17. # include <GL/gl.h>
  18. #endif
  19. #include "core.h"
  20. /*
  21. * Public Video class
  22. */
  23. void Video::Setup(int width, int height)
  24. {
  25. /* Initialise OpenGL */
  26. glViewport(0, 0, width, height);
  27. glEnable(GL_TEXTURE_2D);
  28. glShadeModel(GL_SMOOTH);
  29. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  30. glClearDepth(1.0);
  31. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  32. }
  33. void Video::SetFov(float theta)
  34. {
  35. #undef near /* Fuck Microsoft */
  36. #undef far /* Fuck Microsoft again */
  37. glMatrixMode(GL_PROJECTION);
  38. glLoadIdentity();
  39. float width = GetWidth();
  40. float height = GetHeight();
  41. float near = -width - height;
  42. float far = width + height;
  43. /* Set the projection matrix */
  44. if (theta < 1e-4f)
  45. {
  46. /* The easy way: purely orthogonal projection. */
  47. glOrtho(0, width, 0, height, near, far);
  48. }
  49. else
  50. {
  51. /* Compute a view that approximates the glOrtho view when theta
  52. * approaches zero. This view ensures that the z=0 plane fills
  53. * the screen. */
  54. float t1 = tanf(theta / 2);
  55. float t2 = t1 * height / width;
  56. float dist = (float)width / (2.0f * t1);
  57. near += dist;
  58. far += dist;
  59. if (near <= 0.0f)
  60. {
  61. far -= (near - 1.0f);
  62. near = 1.0f;
  63. }
  64. glFrustum(-near * t1, near * t1, -near * t2, near * t2, near, far);
  65. glTranslatef(-0.5f * width, -0.5f * height, -dist);
  66. }
  67. /* Reset the model view matrix, just in case */
  68. glMatrixMode(GL_MODELVIEW);
  69. glLoadIdentity();
  70. }
  71. void Video::SetDepth(bool set)
  72. {
  73. if (set)
  74. glEnable(GL_DEPTH_TEST);
  75. else
  76. glDisable(GL_DEPTH_TEST);
  77. }
  78. void Video::Clear()
  79. {
  80. glEnable(GL_DEPTH_TEST);
  81. glDepthFunc(GL_LEQUAL);
  82. glEnable(GL_ALPHA_TEST);
  83. glAlphaFunc(GL_GEQUAL, 0.01f);
  84. glEnable(GL_BLEND);
  85. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  86. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  87. SetFov(0.0f);
  88. }
  89. void Video::Capture(uint32_t *buffer)
  90. {
  91. GLint v[4];
  92. glGetIntegerv(GL_VIEWPORT, v);
  93. int width = v[2], height = v[3];
  94. glPixelStorei(GL_PACK_ROW_LENGTH, 0);
  95. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  96. glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
  97. for (int j = 0; j < height / 2; j++)
  98. for (int i = 0; i < width; i++)
  99. {
  100. uint32_t tmp = buffer[j * width + i];
  101. buffer[j * width + i] = buffer[(height - j - 1) * width + i];
  102. buffer[(height - j - 1) * width + i] = tmp;
  103. }
  104. }
  105. int Video::GetWidth()
  106. {
  107. GLint v[4];
  108. glGetIntegerv(GL_VIEWPORT, v);
  109. return v[2];
  110. }
  111. int Video::GetHeight()
  112. {
  113. GLint v[4];
  114. glGetIntegerv(GL_VIEWPORT, v);
  115. return v[3];
  116. }