surface.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. auto OpenGLSurface::allocate() -> void {
  2. glGenVertexArrays(1, &vao);
  3. glBindVertexArray(vao);
  4. glGenBuffers(3, &vbo[0]);
  5. }
  6. auto OpenGLSurface::size(uint w, uint h) -> void {
  7. if(width == w && height == h) return;
  8. width = w, height = h;
  9. w = glrSize(w), h = glrSize(h);
  10. if(texture) { glDeleteTextures(1, &texture); texture = 0; }
  11. if(buffer) { delete[] buffer; buffer = nullptr; }
  12. buffer = new uint32_t[w * h]();
  13. glGenTextures(1, &texture);
  14. glBindTexture(GL_TEXTURE_2D, texture);
  15. glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, getFormat(), getType(), buffer);
  16. if(framebuffer) {
  17. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
  18. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
  19. delete[] buffer;
  20. buffer = nullptr;
  21. }
  22. }
  23. auto OpenGLSurface::release() -> void {
  24. if(vbo[0]) { glDeleteBuffers(3, &vbo[0]); for(auto &o : vbo) o = 0; }
  25. if(vao) { glDeleteVertexArrays(1, &vao); vao = 0; }
  26. if(vertex) { glDetachShader(program, vertex); glDeleteShader(vertex); vertex = 0; }
  27. if(geometry) { glDetachShader(program, geometry); glDeleteShader(geometry); geometry = 0; }
  28. if(fragment) { glDetachShader(program, fragment); glDeleteShader(fragment); fragment = 0; }
  29. if(texture) { glDeleteTextures(1, &texture); texture = 0; }
  30. if(framebuffer) { glDeleteFramebuffers(1, &framebuffer); framebuffer = 0; }
  31. if(program) { glDeleteProgram(program); program = 0; }
  32. width = 0, height = 0;
  33. }
  34. auto OpenGLSurface::render(uint sourceWidth, uint sourceHeight, uint targetX, uint targetY, uint targetWidth, uint targetHeight) -> void {
  35. glViewport(targetX, targetY, targetWidth, targetHeight);
  36. float w = (float)sourceWidth / (float)glrSize(sourceWidth);
  37. float h = (float)sourceHeight / (float)glrSize(sourceHeight);
  38. float u = (float)targetWidth;
  39. float v = (float)targetHeight;
  40. GLfloat modelView[] = {
  41. 1, 0, 0, 0,
  42. 0, 1, 0, 0,
  43. 0, 0, 1, 0,
  44. 0, 0, 0, 1,
  45. };
  46. GLfloat projection[] = {
  47. 2.0f/u, 0.0f, 0.0f, 0.0f,
  48. 0.0f, 2.0f/v, 0.0f, 0.0f,
  49. 0.0f, 0.0f, -1.0f, 0.0f,
  50. -1.0f, -1.0f, 0.0f, 1.0f,
  51. };
  52. GLfloat modelViewProjection[4 * 4];
  53. MatrixMultiply(modelViewProjection, modelView, 4, 4, projection, 4, 4);
  54. GLfloat vertices[] = {
  55. 0, 0, 0, 1,
  56. u, 0, 0, 1,
  57. 0, v, 0, 1,
  58. u, v, 0, 1,
  59. };
  60. GLfloat positions[4 * 4];
  61. for(uint n = 0; n < 16; n += 4) {
  62. MatrixMultiply(&positions[n], &vertices[n], 1, 4, modelViewProjection, 4, 4);
  63. }
  64. GLfloat texCoords[] = {
  65. 0, 0,
  66. w, 0,
  67. 0, h,
  68. w, h,
  69. };
  70. glrUniformMatrix4fv("modelView", modelView);
  71. glrUniformMatrix4fv("projection", projection);
  72. glrUniformMatrix4fv("modelViewProjection", modelViewProjection);
  73. glBindVertexArray(vao);
  74. glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
  75. glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
  76. GLint locationVertex = glGetAttribLocation(program, "vertex");
  77. glEnableVertexAttribArray(locationVertex);
  78. glVertexAttribPointer(locationVertex, 4, GL_FLOAT, GL_FALSE, 0, 0);
  79. glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
  80. glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(GLfloat), positions, GL_STATIC_DRAW);
  81. GLint locationPosition = glGetAttribLocation(program, "position");
  82. glEnableVertexAttribArray(locationPosition);
  83. glVertexAttribPointer(locationPosition, 4, GL_FLOAT, GL_FALSE, 0, 0);
  84. glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
  85. glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), texCoords, GL_STATIC_DRAW);
  86. GLint locationTexCoord = glGetAttribLocation(program, "texCoord");
  87. glEnableVertexAttribArray(locationTexCoord);
  88. glVertexAttribPointer(locationTexCoord, 2, GL_FLOAT, GL_FALSE, 0, 0);
  89. glBindFragDataLocation(program, 0, "fragColor");
  90. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  91. glDisableVertexAttribArray(locationVertex);
  92. glDisableVertexAttribArray(locationPosition);
  93. glDisableVertexAttribArray(locationTexCoord);
  94. }