void GLCgShader::UnbindShader() { cgGLUnbindProgram(m_cgProfile); cgGLDisableProfile(m_cgProfile); if (m_focus == Shader::SF_PIXEL) DisableTextures(); }
void golly_render::killrect(int x, int y, int w, int h) { #if 0 // is Tom's hashdraw code doing unnecessary work??? if (x >= currwd || y >= currht) return; if (x + w <= 0 || y + h <= 0) return; if (w <= 0 || h <= 0) return; // clip given rect so it's within viewport int clipx = x < 0 ? 0 : x; int clipy = y < 0 ? 0 : y; int clipr = x + w; int clipb = y + h; if (clipr > currwd) clipr = currwd; if (clipb > currht) clipb = currht; int clipwd = clipr - clipx; int clipht = clipb - clipy; // use a different pale color each time to see any probs glColor4ub((rand()&127)+128, (rand()&127)+128, (rand()&127)+128, 255); DisableTextures(); FillRect(clipx, clipy, clipwd, clipht); #else // no need to do anything because background has already been filled by glClear in DrawPattern #endif }
void OpenGLEngine::Disable (Shader const* shader, GLuint program) { DisableSamplers (shader, program); DisableTextureArrays (shader, program); DisableTextures (shader, program); DisableUniformBuffers (shader, program); }
void MythRenderOpenGL1::DrawRectPriv(const QRect &area, const QBrush &fillBrush, const QPen &linePen, int alpha) { SetBlend(true); DisableTextures(); glEnableClientState(GL_VERTEX_ARRAY); if (fillBrush.style() != Qt::NoBrush) { SetColor(fillBrush.color().red(), fillBrush.color().green(), fillBrush.color().blue(), fillBrush.color().alpha()); GLfloat *vertices = GetCachedVertices(GL_TRIANGLE_STRIP, area); glVertexPointer(2, GL_FLOAT, 0, vertices); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } if (linePen.style() != Qt::NoPen) { SetColor(linePen.color().red(), linePen.color().green(), linePen.color().blue(), linePen.color().alpha()); glLineWidth(linePen.width()); GLfloat *vertices = GetCachedVertices(GL_LINE_LOOP, area); glVertexPointer(2, GL_FLOAT, 0, vertices); glDrawArrays(GL_LINE_LOOP, 0, 4); } glDisableClientState(GL_VERTEX_ARRAY); }
void DrawPoints(unsigned char* rgbdata, int x, int y, int w, int h) { // called from golly_render::pixblit to draw pattern at 1:1 scale // if numstates is 2 or we're drawing the paste image const int maxcoords = 1024; // must be multiple of 2 GLfloat points[maxcoords]; int numcoords = 0; DisableTextures(); glPointSize(1); unsigned char deadr = currlayer->cellr[0]; unsigned char deadg = currlayer->cellg[0]; unsigned char deadb = currlayer->cellb[0]; unsigned char prevr = deadr; unsigned char prevg = deadg; unsigned char prevb = deadb; glColor4ub(deadr, deadg, deadb, 255); unsigned char r, g, b; int i = 0; for (int row = 0; row < h; row++) { for (int col = 0; col < w; col++) { r = rgbdata[i++]; g = rgbdata[i++]; b = rgbdata[i++]; if (r != deadr || g != deadg || b != deadb) { // we've got a live pixel bool changecolor = (r != prevr || g != prevg || b != prevb); if (changecolor || numcoords == maxcoords) { if (numcoords > 0) { glVertexPointer(2, GL_FLOAT, 0, points); glDrawArrays(GL_POINTS, 0, numcoords/2); numcoords = 0; } if (changecolor) { prevr = r; prevg = g; prevb = b; glColor4ub(r, g, b, 255); } } points[numcoords++] = x + col + 0.5; points[numcoords++] = y + row + 0.5; } } } if (numcoords > 0) { glVertexPointer(2, GL_FLOAT, 0, points); glDrawArrays(GL_POINTS, 0, numcoords/2); } }
void DrawSelection(gRect& rect, bool active) { // draw semi-transparent rectangle if (active) { glColor4ub(selectrgb.r, selectrgb.g, selectrgb.b, 128); } else { // use light gray to indicate an inactive selection glColor4f(0.7, 0.7, 0.7, 0.5); } DisableTextures(); FillRect(rect.x, rect.y, rect.width, rect.height); }
void MythRenderOpenGL2::DrawRectPriv(const QRect &area, bool drawFill, const QColor &fillColor, bool drawLine, int lineWidth, const QColor &lineColor, int prog) { if (prog && !m_shader_objects.contains(prog)) prog = 0; if (prog == 0) prog = m_shaders[kShaderSimple]; EnableShaderObject(prog); SetShaderParams(prog, &m_projection[0][0], "u_projection"); SetBlend(true); DisableTextures(); m_glEnableVertexAttribArray(VERTEX_INDEX); if (drawFill) { m_glVertexAttrib4f(COLOR_INDEX, fillColor.red() / 255.0, fillColor.green() / 255.0, fillColor.blue() / 255.0, fillColor.alpha() / 255.0); GetCachedVBO(GL_TRIANGLE_STRIP, area); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); m_glBindBuffer(GL_ARRAY_BUFFER, 0); } if (drawLine) { glLineWidth(lineWidth); m_glVertexAttrib4f(COLOR_INDEX, lineColor.red() / 255.0, lineColor.green() / 255.0, lineColor.blue() / 255.0, lineColor.alpha() / 255.0); GetCachedVBO(GL_LINE_LOOP, area); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_LINE_LOOP, 0, 4); m_glBindBuffer(GL_ARRAY_BUFFER, 0); } m_glDisableVertexAttribArray(VERTEX_INDEX); }
void DrawMagnifiedCells(unsigned char* statedata, int x, int y, int w, int h, int pmscale, int stride, int numstates) { // called from golly_render::pixblit to draw cells magnified by pmscale (2, 4, ... 2^MAX_MAG) // when numstates is > 2 int cellsize = pmscale > 2 ? pmscale - 1 : pmscale; const int maxcoords = 256; // must be multiple of 2 GLfloat points[256][maxcoords]; int numcoords[256] = {0}; DisableTextures(); glPointSize(cellsize); // following code minimizes color changes due to state changes for (int row = 0; row < h; row++) { for (int col = 0; col < w; col++) { unsigned char state = statedata[row*stride + col]; if (state > 0) { if (numcoords[state] == maxcoords) { // this shouldn't happen too often glColor4ub(currlayer->cellr[state], currlayer->cellg[state], currlayer->cellb[state], 255); glVertexPointer(2, GL_FLOAT, 0, points[state]); glDrawArrays(GL_POINTS, 0, numcoords[state]/2); numcoords[state] = 0; } // fill cellsize*cellsize pixels // FillRect(x + col * pmscale, y + row * pmscale, cellsize, cellsize); points[state][numcoords[state]++] = x + col*pmscale + cellsize/2.0; points[state][numcoords[state]++] = y + row*pmscale + cellsize/2.0; } } } for (int state = 1; state < numstates; state++) { if (numcoords[state] > 0) { glColor4ub(currlayer->cellr[state], currlayer->cellg[state], currlayer->cellb[state], 255); glVertexPointer(2, GL_FLOAT, 0, points[state]); glDrawArrays(GL_POINTS, 0, numcoords[state]/2); } } }
void DrawMagnifiedTwoStateCells(unsigned char* statedata, int x, int y, int w, int h, int pmscale, int stride) { // called from golly_render::pixblit to draw cells magnified by pmscale (2, 4, ... 2^MAX_MAG) // when number of states is 2 int cellsize = pmscale > 2 ? pmscale - 1 : pmscale; const int maxcoords = 1024; // must be multiple of 2 GLfloat points[maxcoords]; int numcoords = 0; DisableTextures(); glPointSize(cellsize); // all live cells are in state 1 so only need to set color once glColor4ub(currlayer->cellr[1], currlayer->cellg[1], currlayer->cellb[1], 255); for (int row = 0; row < h; row++) { for (int col = 0; col < w; col++) { unsigned char state = statedata[row*stride + col]; if (state > 0) { // fill cellsize*cellsize pixels // FillRect(x + col * pmscale, y + row * pmscale, cellsize, cellsize); // optimize by calling glDrawArrays less often if (numcoords == maxcoords) { glVertexPointer(2, GL_FLOAT, 0, points); glDrawArrays(GL_POINTS, 0, maxcoords/2); numcoords = 0; } // store mid point of cell points[numcoords++] = x + col*pmscale + cellsize/2.0; points[numcoords++] = y + row*pmscale + cellsize/2.0; } } } if (numcoords > 0) { glVertexPointer(2, GL_FLOAT, 0, points); glDrawArrays(GL_POINTS, 0, numcoords/2); } }
void MythRenderOpenGL1::DrawRectPriv(const QRect &area, const QBrush &fillBrush, const QPen &linePen, int alpha) { SetBlend(true); DisableTextures(); EnableShaderObject(0); glEnableClientState(GL_VERTEX_ARRAY); int lineWidth = linePen.width(); QRect r(area.left() + lineWidth, area.top() + lineWidth, area.width() - (lineWidth * 2), area.height() - (lineWidth * 2)); if (fillBrush.style() != Qt::NoBrush) { int a = 255 * (((float)alpha / 255.0f) * ((float)fillBrush.color().alpha() / 255.0f)); SetColor(fillBrush.color().red(), fillBrush.color().green(), fillBrush.color().blue(), a); GLfloat *vertices = GetCachedVertices(GL_TRIANGLE_STRIP, r); glVertexPointer(2, GL_FLOAT, 0, vertices); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } if (linePen.style() != Qt::NoPen) { int a = 255 * (((float)alpha / 255.0f) * ((float)linePen.color().alpha() / 255.0f)); SetColor(linePen.color().red(), linePen.color().green(), linePen.color().blue(), a); glLineWidth(linePen.width()); GLfloat *vertices = GetCachedVertices(GL_LINE_LOOP, r); glVertexPointer(2, GL_FLOAT, 0, vertices); glDrawArrays(GL_LINE_LOOP, 0, 4); } glDisableClientState(GL_VERTEX_ARRAY); }
void MythRenderOpenGL2::DrawRoundRectPriv(const QRect &area, int cornerRadius, const QBrush &fillBrush, const QPen &linePen, int alpha) { int lineWidth = linePen.width(); int halfline = lineWidth / 2; int rad = cornerRadius - halfline; if ((area.width() / 2) < rad) rad = area.width() / 2; if ((area.height() / 2) < rad) rad = area.height() / 2; int dia = rad * 2; QRect r(area.left() + halfline, area.top() + halfline, area.width() - (halfline * 2), area.height() - (halfline * 2)); QRect tl(r.left(), r.top(), rad, rad); QRect tr(r.left() + r.width() - rad, r.top(), rad, rad); QRect bl(r.left(), r.top() + r.height() - rad, rad, rad); QRect br(r.left() + r.width() - rad, r.top() + r.height() - rad, rad, rad); SetBlend(true); DisableTextures(); m_glEnableVertexAttribArray(VERTEX_INDEX); if (fillBrush.style() != Qt::NoBrush) { // Get the shaders int elip = m_shaders[kShaderCircle]; int fill = m_shaders[kShaderSimple]; // Set the fill color m_glVertexAttrib4f(COLOR_INDEX, fillBrush.color().red() / 255.0, fillBrush.color().green() / 255.0, fillBrush.color().blue() / 255.0, (fillBrush.color().alpha() / 255.0) * (alpha / 255.0)); // Set the radius m_parameters[0][2] = rad; m_parameters[0][3] = rad - 1.0; // Enable the Circle shader SetShaderParams(elip, &m_projection[0][0], "u_projection"); // Draw the top left segment m_parameters[0][0] = tl.left() + rad; m_parameters[0][1] = tl.top() + rad; SetShaderParams(elip, &m_parameters[0][0], "u_parameters"); GetCachedVBO(GL_TRIANGLE_STRIP, tl); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Draw the top right segment m_parameters[0][0] = tr.left(); m_parameters[0][1] = tr.top() + rad; SetShaderParams(elip, &m_parameters[0][0], "u_parameters"); GetCachedVBO(GL_TRIANGLE_STRIP, tr); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Draw the bottom left segment m_parameters[0][0] = bl.left() + rad; m_parameters[0][1] = bl.top(); SetShaderParams(elip, &m_parameters[0][0], "u_parameters"); GetCachedVBO(GL_TRIANGLE_STRIP, bl); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Draw the bottom right segment m_parameters[0][0] = br.left(); m_parameters[0][1] = br.top(); SetShaderParams(elip, &m_parameters[0][0], "u_parameters"); GetCachedVBO(GL_TRIANGLE_STRIP, br); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Fill the remaining areas QRect main(r.left() + rad, r.top(), r.width() - dia, r.height()); QRect left(r.left(), r.top() + rad, rad, r.height() - dia); QRect right(r.left() + r.width() - rad, r.top() + rad, rad, r.height() - dia); EnableShaderObject(fill); SetShaderParams(fill, &m_projection[0][0], "u_projection"); GetCachedVBO(GL_TRIANGLE_STRIP, main); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); GetCachedVBO(GL_TRIANGLE_STRIP, left); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); GetCachedVBO(GL_TRIANGLE_STRIP, right); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); m_glBindBuffer(GL_ARRAY_BUFFER, 0); } if (linePen.style() != Qt::NoPen) { // Get the shaders int edge = m_shaders[kShaderCircleEdge]; int vline = m_shaders[kShaderVertLine]; int hline = m_shaders[kShaderHorizLine]; // Set the line color m_glVertexAttrib4f(COLOR_INDEX, linePen.color().red() / 255.0, linePen.color().green() / 255.0, linePen.color().blue() / 255.0, (linePen.color().alpha() / 255.0) * (alpha / 255.0)); // Set the radius and width m_parameters[0][2] = rad - lineWidth / 2.0; m_parameters[0][3] = lineWidth / 2.0; // Enable the edge shader SetShaderParams(edge, &m_projection[0][0], "u_projection"); // Draw the top left edge segment m_parameters[0][0] = tl.left() + rad; m_parameters[0][1] = tl.top() + rad; SetShaderParams(edge, &m_parameters[0][0], "u_parameters"); GetCachedVBO(GL_TRIANGLE_STRIP, tl); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Draw the top right edge segment m_parameters[0][0] = tr.left(); m_parameters[0][1] = tr.top() + rad; SetShaderParams(edge, &m_parameters[0][0], "u_parameters"); GetCachedVBO(GL_TRIANGLE_STRIP, tr); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Draw the bottom left edge segment m_parameters[0][0] = bl.left() + rad; m_parameters[0][1] = bl.top(); SetShaderParams(edge, &m_parameters[0][0], "u_parameters"); GetCachedVBO(GL_TRIANGLE_STRIP, bl); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Draw the bottom right edge segment m_parameters[0][0] = br.left(); m_parameters[0][1] = br.top(); SetShaderParams(edge, &m_parameters[0][0], "u_parameters"); GetCachedVBO(GL_TRIANGLE_STRIP, br); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Vertical lines SetShaderParams(vline, &m_projection[0][0], "u_projection"); m_parameters[0][1] = lineWidth / 2.0; QRect vl(r.left(), r.top() + rad, lineWidth, r.height() - dia); // Draw the left line segment m_parameters[0][0] = vl.left() + lineWidth; SetShaderParams(vline, &m_parameters[0][0], "u_parameters"); GetCachedVBO(GL_TRIANGLE_STRIP, vl); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Draw the right line segment vl.translate(r.width() - lineWidth, 0); m_parameters[0][0] = vl.left(); SetShaderParams(vline, &m_parameters[0][0], "u_parameters"); GetCachedVBO(GL_TRIANGLE_STRIP, vl); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Horizontal lines SetShaderParams(hline, &m_projection[0][0], "u_projection"); QRect hl(r.left() + rad, r.top(), r.width() - dia, lineWidth); // Draw the top line segment m_parameters[0][0] = hl.top() + lineWidth; SetShaderParams(hline, &m_parameters[0][0], "u_parameters"); GetCachedVBO(GL_TRIANGLE_STRIP, hl); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Draw the bottom line segment hl.translate(0, r.height() - lineWidth); m_parameters[0][0] = hl.top(); SetShaderParams(hline, &m_parameters[0][0], "u_parameters"); GetCachedVBO(GL_TRIANGLE_STRIP, hl); m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE, VERTEX_SIZE * sizeof(GLfloat), (const void *) kVertexOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); m_glBindBuffer(GL_ARRAY_BUFFER, 0); } m_glDisableVertexAttribArray(VERTEX_INDEX); }
void DrawGridLines(int wd, int ht) { int cellsize = 1 << currlayer->view->getmag(); int h, v, i, topbold, leftbold; if (showboldlines) { // ensure that origin cell stays next to bold lines; // ie. bold lines scroll when pattern is scrolled pair<bigint, bigint> lefttop = currlayer->view->at(0, 0); leftbold = lefttop.first.mod_smallint(boldspacing); topbold = lefttop.second.mod_smallint(boldspacing); if (currlayer->originx != bigint::zero) { leftbold -= currlayer->originx.mod_smallint(boldspacing); } if (currlayer->originy != bigint::zero) { topbold -= currlayer->originy.mod_smallint(boldspacing); } if (mathcoords) topbold--; // show origin cell above bold line } else { // avoid gcc warning topbold = leftbold = 0; } // set the stroke color depending on current bg color int r = currlayer->cellr[0]; int g = currlayer->cellg[0]; int b = currlayer->cellb[0]; int gray = (int) ((r + g + b) / 3.0); if (gray > 127) { // darker lines glColor4ub(r > 32 ? r - 32 : 0, g > 32 ? g - 32 : 0, b > 32 ? b - 32 : 0, 255); } else { // lighter lines glColor4ub(r + 32 < 256 ? r + 32 : 255, g + 32 < 256 ? g + 32 : 255, b + 32 < 256 ? b + 32 : 255, 255); } DisableTextures(); glLineWidth(1.0); // draw all plain lines first // note that we need to subtract 0.5 from each coordinate to avoid uneven spacing // and get same result on iOS Simulator (non Retina) and iPad with Retina i = showboldlines ? topbold : 1; v = 0; while (true) { v += cellsize; if (v >= ht) break; if (showboldlines) i++; if (i % boldspacing != 0 && v >= 0 && v < ht) { GLfloat points[] = {-0.5, v-0.5, wd-0.5, v-0.5}; glVertexPointer(2, GL_FLOAT, 0, points); glDrawArrays(GL_LINES, 0, 2); } } i = showboldlines ? leftbold : 1; h = 0; while (true) { h += cellsize; if (h >= wd) break; if (showboldlines) i++; if (i % boldspacing != 0 && h >= 0 && h < wd) { GLfloat points[] = {h-0.5, -0.5, h-0.5, ht-0.5}; glVertexPointer(2, GL_FLOAT, 0, points); glDrawArrays(GL_LINES, 0, 2); } } if (showboldlines) { // draw bold lines in slightly darker/lighter color if (gray > 127) { // darker lines glColor4ub(r > 64 ? r - 64 : 0, g > 64 ? g - 64 : 0, b > 64 ? b - 64 : 0, 255); } else { // lighter lines glColor4ub(r + 64 < 256 ? r + 64 : 255, g + 64 < 256 ? g + 64 : 255, b + 64 < 256 ? b + 64 : 255, 255); } i = topbold; v = 0; while (true) { v += cellsize; if (v >= ht) break; i++; if (i % boldspacing == 0 && v >= 0 && v < ht) { GLfloat points[] = {-0.5, v-0.5, wd-0.5, v-0.5}; glVertexPointer(2, GL_FLOAT, 0, points); glDrawArrays(GL_LINES, 0, 2); } } i = leftbold; h = 0; while (true) { h += cellsize; if (h >= wd) break; i++; if (i % boldspacing == 0 && h >= 0 && h < wd) { GLfloat points[] = {h-0.5, -0.5, h-0.5, ht-0.5}; glVertexPointer(2, GL_FLOAT, 0, points); glDrawArrays(GL_LINES, 0, 2); } } } }
void DrawPasteImage() { // calculate pasterect SetPasteRect(pastebbox.width, pastebbox.height); int pastemag = currlayer->view->getmag(); gRect cellbox = pastebbox; // calculate intersection of pasterect and current viewport for use // as a temporary viewport int itop = pasterect.y; int ileft = pasterect.x; int ibottom = itop + pasterect.height - 1; int iright = ileft + pasterect.width - 1; if (itop < 0) { itop = 0; cellbox.y += PixelsToCells(-pasterect.y, pastemag); } if (ileft < 0) { ileft = 0; cellbox.x += PixelsToCells(-pasterect.x, pastemag); } if (ibottom > currht - 1) ibottom = currht - 1; if (iright > currwd - 1) iright = currwd - 1; int pastewd = iright - ileft + 1; int pasteht = ibottom - itop + 1; cellbox.width = PixelsToCells(pastewd, pastemag); cellbox.height = PixelsToCells(pasteht, pastemag); // create temporary viewport viewport tempview(pastewd, pasteht); int midx, midy; if (pastemag > 0) { midx = cellbox.x + cellbox.width / 2; midy = cellbox.y + cellbox.height / 2; } else { midx = cellbox.x + (cellbox.width - 1) / 2; midy = cellbox.y + (cellbox.height - 1) / 2; } tempview.setpositionmag(midx, midy, pastemag); // temporarily turn off grid lines bool saveshow = showgridlines; showgridlines = false; // temporarily change currwd and currht int savewd = currwd; int saveht = currht; currwd = tempview.getwidth(); currht = tempview.getheight(); glTranslatef(ileft, itop, 0); // draw paste pattern drawing_paste = true; pastealgo->draw(tempview, renderer); drawing_paste = false; glTranslatef(-ileft, -itop, 0); showgridlines = saveshow; currwd = savewd; currht = saveht; // overlay translucent rect to show paste area glColor4ub(pastergb.r, pastergb.g, pastergb.b, 64); DisableTextures(); FillRect(ileft, itop, pastewd, pasteht); }
void DrawGridBorder(int wd, int ht) { // universe is bounded so draw any visible border regions pair<int,int> ltpxl = currlayer->view->screenPosOf(currlayer->algo->gridleft, currlayer->algo->gridtop, currlayer->algo); pair<int,int> rbpxl = currlayer->view->screenPosOf(currlayer->algo->gridright, currlayer->algo->gridbottom, currlayer->algo); int left = ltpxl.first; int top = ltpxl.second; int right = rbpxl.first; int bottom = rbpxl.second; if (currlayer->algo->gridwd == 0) { left = 0; right = wd-1; } if (currlayer->algo->gridht == 0) { top = 0; bottom = ht-1; } // note that right and/or bottom might be INT_MAX so avoid adding to cause overflow if (currlayer->view->getmag() > 0) { // move to bottom right pixel of cell at gridright,gridbottom if (right < wd) right += (1 << currlayer->view->getmag()) - 1; if (bottom < ht) bottom += (1 << currlayer->view->getmag()) - 1; if (currlayer->view->getmag() == 1) { // there are no gaps at scale 1:2 if (right < wd) right++; if (bottom < ht) bottom++; } } else { if (right < wd) right++; if (bottom < ht) bottom++; } if (left < 0 && right >= wd && top < 0 && bottom >= ht) { // border isn't visible (ie. grid fills viewport) return; } glColor4ub(borderrgb.r, borderrgb.g, borderrgb.b, 255); DisableTextures(); if (left >= wd || right < 0 || top >= ht || bottom < 0) { // no part of grid is visible so fill viewport with border FillRect(0, 0, wd, ht); return; } // avoid drawing overlapping rects below int rtop = 0; int rheight = ht; if (currlayer->algo->gridht > 0) { if (top > 0) { // top border is visible FillRect(0, 0, wd, top); // reduce size of rect below rtop = top; rheight -= top; } if (bottom < ht) { // bottom border is visible FillRect(0, bottom, wd, ht - bottom); // reduce size of rect below rheight -= ht - bottom; } } if (currlayer->algo->gridwd > 0) { if (left > 0) { // left border is visible FillRect(0, rtop, left, rheight); } if (right < wd) { // right border is visible FillRect(right, rtop, wd - right, rheight); } } }