123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- auto OpenGLSurface::allocate() -> void {
- glGenVertexArrays(1, &vao);
- glBindVertexArray(vao);
- glGenBuffers(3, &vbo[0]);
- }
- auto OpenGLSurface::size(uint w, uint h) -> void {
- if(width == w && height == h) return;
- width = w, height = h;
- w = glrSize(w), h = glrSize(h);
- if(texture) { glDeleteTextures(1, &texture); texture = 0; }
- if(buffer) { delete[] buffer; buffer = nullptr; }
- buffer = new uint32_t[w * h]();
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, getFormat(), getType(), buffer);
- if(framebuffer) {
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
- delete[] buffer;
- buffer = nullptr;
- }
- }
- auto OpenGLSurface::release() -> void {
- if(vbo[0]) { glDeleteBuffers(3, &vbo[0]); for(auto &o : vbo) o = 0; }
- if(vao) { glDeleteVertexArrays(1, &vao); vao = 0; }
- if(vertex) { glDetachShader(program, vertex); glDeleteShader(vertex); vertex = 0; }
- if(geometry) { glDetachShader(program, geometry); glDeleteShader(geometry); geometry = 0; }
- if(fragment) { glDetachShader(program, fragment); glDeleteShader(fragment); fragment = 0; }
- if(texture) { glDeleteTextures(1, &texture); texture = 0; }
- if(framebuffer) { glDeleteFramebuffers(1, &framebuffer); framebuffer = 0; }
- if(program) { glDeleteProgram(program); program = 0; }
- width = 0, height = 0;
- }
- auto OpenGLSurface::render(uint sourceWidth, uint sourceHeight, uint targetX, uint targetY, uint targetWidth, uint targetHeight) -> void {
- glViewport(targetX, targetY, targetWidth, targetHeight);
- float w = (float)sourceWidth / (float)glrSize(sourceWidth);
- float h = (float)sourceHeight / (float)glrSize(sourceHeight);
- float u = (float)targetWidth;
- float v = (float)targetHeight;
- GLfloat modelView[] = {
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1,
- };
- GLfloat projection[] = {
- 2.0f/u, 0.0f, 0.0f, 0.0f,
- 0.0f, 2.0f/v, 0.0f, 0.0f,
- 0.0f, 0.0f, -1.0f, 0.0f,
- -1.0f, -1.0f, 0.0f, 1.0f,
- };
- GLfloat modelViewProjection[4 * 4];
- MatrixMultiply(modelViewProjection, modelView, 4, 4, projection, 4, 4);
- GLfloat vertices[] = {
- 0, 0, 0, 1,
- u, 0, 0, 1,
- 0, v, 0, 1,
- u, v, 0, 1,
- };
- GLfloat positions[4 * 4];
- for(uint n = 0; n < 16; n += 4) {
- MatrixMultiply(&positions[n], &vertices[n], 1, 4, modelViewProjection, 4, 4);
- }
- GLfloat texCoords[] = {
- 0, 0,
- w, 0,
- 0, h,
- w, h,
- };
- glrUniformMatrix4fv("modelView", modelView);
- glrUniformMatrix4fv("projection", projection);
- glrUniformMatrix4fv("modelViewProjection", modelViewProjection);
- glBindVertexArray(vao);
- glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
- glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
- GLint locationVertex = glGetAttribLocation(program, "vertex");
- glEnableVertexAttribArray(locationVertex);
- glVertexAttribPointer(locationVertex, 4, GL_FLOAT, GL_FALSE, 0, 0);
- glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
- glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(GLfloat), positions, GL_STATIC_DRAW);
- GLint locationPosition = glGetAttribLocation(program, "position");
- glEnableVertexAttribArray(locationPosition);
- glVertexAttribPointer(locationPosition, 4, GL_FLOAT, GL_FALSE, 0, 0);
- glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
- glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), texCoords, GL_STATIC_DRAW);
- GLint locationTexCoord = glGetAttribLocation(program, "texCoord");
- glEnableVertexAttribArray(locationTexCoord);
- glVertexAttribPointer(locationTexCoord, 2, GL_FLOAT, GL_FALSE, 0, 0);
- glBindFragDataLocation(program, 0, "fragColor");
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- glDisableVertexAttribArray(locationVertex);
- glDisableVertexAttribArray(locationPosition);
- glDisableVertexAttribArray(locationTexCoord);
- }
|