void DisplayOzone::drawBuffer(Buffer *buffer) { if (!mDrawing) { // get buffer on which to draw window if (mUnused) { mDrawing = mUnused; mUnused = nullptr; } else { mDrawing = new Buffer(this, GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT, GBM_FORMAT_ARGB8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888, true, true); // XXX shouldn't need stencil if (!mDrawing || !mDrawing->initialize(mWidth, mHeight)) { return; } } StateManagerGL *sm = getRenderer()->getStateManager(); sm->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawing->getGLFB()); sm->setClearColor(gl::ColorF(0, 0, 0, 1)); sm->setClearDepth(1); sm->setScissorTestEnabled(false); sm->setColorMask(true, true, true, true); sm->setDepthMask(true); mFunctionsGL->clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } drawWithTexture(buffer); presentScreen(); }
void DisplayOzone::drawWithTexture(Buffer *buffer) { FunctionsGL *gl = mFunctionsGL; StateManagerGL *sm = getRenderer()->getStateManager(); if (!mProgram) { const GLchar *vertexSource = "#version 100\n" "attribute vec3 vertex;\n" "uniform vec2 center;\n" "uniform vec2 windowSize;\n" "uniform vec2 borderSize;\n" "uniform float depth;\n" "varying vec3 texCoord;\n" "void main()\n" "{\n" " vec2 pos = vertex.xy * (windowSize + borderSize * vertex.z);\n" " gl_Position = vec4(center + pos, depth, 1);\n" " texCoord = vec3(pos / windowSize * vec2(.5, -.5) + vec2(.5, .5), vertex.z);\n" "}\n"; const GLchar *fragmentSource = "#version 100\n" "precision mediump float;\n" "uniform sampler2D tex;\n" "varying vec3 texCoord;\n" "void main()\n" "{\n" " if (texCoord.z > 0.)\n" " {\n" " float c = abs((texCoord.z * 2.) - 1.);\n" " gl_FragColor = vec4(c, c, c, 1);\n" " }\n" " else\n" " {\n" " gl_FragColor = texture2D(tex, texCoord.xy);\n" " }\n" "}\n"; mVertexShader = makeShader(GL_VERTEX_SHADER, vertexSource); mFragmentShader = makeShader(GL_FRAGMENT_SHADER, fragmentSource); mProgram = gl->createProgram(); gl->attachShader(mProgram, mVertexShader); gl->attachShader(mProgram, mFragmentShader); gl->bindAttribLocation(mProgram, 0, "vertex"); gl->linkProgram(mProgram); GLint linked; gl->getProgramiv(mProgram, GL_LINK_STATUS, &linked); ASSERT(linked); mCenterUniform = gl->getUniformLocation(mProgram, "center"); mWindowSizeUniform = gl->getUniformLocation(mProgram, "windowSize"); mBorderSizeUniform = gl->getUniformLocation(mProgram, "borderSize"); mDepthUniform = gl->getUniformLocation(mProgram, "depth"); GLint texUniform = gl->getUniformLocation(mProgram, "tex"); sm->useProgram(mProgram); gl->uniform1i(texUniform, 0); // clang-format off const GLfloat vertices[] = { // window corners, and window border inside corners 1, -1, 0, -1, -1, 0, 1, 1, 0, -1, 1, 0, // window border outside corners 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, }; // clang-format on gl->genBuffers(1, &mVertexBuffer); sm->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); gl->bufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // window border triangle strip const GLuint borderStrip[] = {5, 0, 4, 2, 6, 3, 7, 1, 5, 0}; gl->genBuffers(1, &mIndexBuffer); sm->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); gl->bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(borderStrip), borderStrip, GL_STATIC_DRAW); } else { sm->useProgram(mProgram); sm->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); sm->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); } // convert from pixels to "-1 to 1" space const NativeWindow *n = buffer->getNative(); double x = n->x * 2. / mWidth - 1; double y = n->y * 2. / mHeight - 1; double halfw = n->width * 1. / mWidth; double halfh = n->height * 1. / mHeight; double borderw = n->borderWidth * 2. / mWidth; double borderh = n->borderHeight * 2. / mHeight; gl->uniform2f(mCenterUniform, x + halfw, y + halfh); gl->uniform2f(mWindowSizeUniform, halfw, halfh); gl->uniform2f(mBorderSizeUniform, borderw, borderh); gl->uniform1f(mDepthUniform, n->depth / 1e6); sm->setBlendEnabled(false); sm->setCullFaceEnabled(false); sm->setStencilTestEnabled(false); sm->setScissorTestEnabled(false); sm->setDepthTestEnabled(true); sm->setColorMask(true, true, true, true); sm->setDepthMask(true); sm->setDepthRange(0, 1); sm->setDepthFunc(GL_LESS); sm->setViewport(gl::Rectangle(0, 0, mWidth, mHeight)); sm->activeTexture(0); GLuint tex = buffer->getTexture(); sm->bindTexture(GL_TEXTURE_2D, tex); gl->vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); gl->enableVertexAttribArray(0); sm->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawing->getGLFB()); gl->drawArrays(GL_TRIANGLE_STRIP, 0, 4); gl->drawElements(GL_TRIANGLE_STRIP, 10, GL_UNSIGNED_INT, 0); sm->deleteTexture(tex); }