/// 绘制矩形 void CZUtil::drawRect(const CZRect &rect, const CZAffineTransform &transform) { CZ2DPoint corners[4]; GLuint vbo = 0; corners[0] = rect.origin; corners[1] = CZ2DPoint(rect.getMaxX(), rect.getMinY()); corners[2] = CZ2DPoint(rect.getMaxX(), rect.getMaxY()); corners[3] = CZ2DPoint(rect.getMinX(), rect.getMaxY()); for (int i = 0; i < 4; i++) { corners[i] = transform.applyTo2DPoint(corners[i]); } const GLfloat quadVertices[] = { corners[0].x, corners[0].y, 0.0, 0.0, corners[1].x, corners[1].y, 1.0, 0.0, corners[3].x, corners[3].y, 0.0, 1.0, corners[2].x, corners[2].y, 1.0, 1.0, }; // create, bind, and populate VBO glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 16, quadVertices, GL_STATIC_DRAW); // set up attrib pointers glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, (void*)8); glEnableVertexAttribArray(1); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDeleteBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, 0); }
/// 应用于矩形 CZRect CZAffineTransform::applyToRect(CZRect & rect_) { CZ2DPoint a = CZ2DPoint(rect_.getMinX(), rect_.getMinY()); CZ2DPoint b = CZ2DPoint(rect_.getMaxX(), rect_.getMinY()); CZ2DPoint c = CZ2DPoint(rect_.getMinX(), rect_.getMaxY()); CZ2DPoint d = CZ2DPoint(rect_.getMaxX(), rect_.getMaxY()); a = this->applyTo2DPoint(a); b = this->applyTo2DPoint(b); c = this->applyTo2DPoint(c); d = this->applyTo2DPoint(d); float minX = CZUtil::Min(a.x, CZUtil::Min(b.x, CZUtil::Min(c.x,d.x))); float maxX = CZUtil::Max(a.x, CZUtil::Max(b.x, CZUtil::Max(c.x,d.x))); float minY = CZUtil::Min(a.y, CZUtil::Min(b.y, CZUtil::Min(c.y,d.y))); float maxY = CZUtil::Max(a.y, CZUtil::Max(b.y, CZUtil::Max(c.y,d.y))); return CZRect(minX,minY, maxX-minX, maxY-minY); }
/// 绘制图案 void CZBristleGenerator::renderStamp(CZRandom* randomizer) { if (!randomizer) { LOG_ERROR("randomizer is null\n"); return; } if(ptrGLContext == NULL) { LOG_ERROR("ptrGLContext is NULL!\n"); return; } CZShader *shader = getShader("drawCircle"); if (shader == NULL) { ptrGLContext->setAsCurrent(); vector<string> attributes, uniforms; attributes.push_back("inPosition"); uniforms.push_back("mvpMat"); uniforms.push_back("intensity"); shader = new CZShader("basic","basicColor",attributes,uniforms); shaders.insert(make_pair("drawCircle",shader)); } float width = baseDimension; float height = baseDimension; CZRect bounds = CZRect(0, 0, width, height); CZ2DPoint center = bounds.getCenter(); int numBristles = bristleDensity.value * 980 + 20; int s = bristleSize.value * (size.width * 0.05) + 5; GLuint mVertexBufferObject; // 装载顶点 glGenBuffers(1, &mVertexBufferObject); glBindBuffer(GL_ARRAY_BUFFER, mVertexBufferObject); glEnableVertexAttribArray(0); shader->begin(); glUniformMatrix4fv(shader->getUniformLocation("mvpMat"),1,GL_FALSE,projMat); // make some bristles long maxRadius = (long)width / 2; for (int i = 0; i < numBristles; i++) { int radius = randomizer->nextInt() % s; float tempMax = (maxRadius - (radius + 1)); float n = randomizer->nextFloat(); float r = n * tempMax; float a = randomizer->nextFloat() * (M_PI * 2); float x = center.x + cos(a) * r; float y = center.y + sin(a) * r; glUniform1f(shader->getUniformLocation("intensity"),randomizer->nextFloat()); CZ2DPoint center(x,y); drawCircle(center, radius); } glDisableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); /// 消除 glDeleteBuffers(1, &mVertexBufferObject); shader->end(); CZCheckGLError(); }
/// 绘制数据 /// /// 以最小粒度的离散点(points_)为中心,形成小矩形,委托render绘制,并将此矩形数据返回。 /// CZRect CZPath::drawData() { size_t iPointSize = points.size(); CZRect dataBounds = CZRect(0.0f,0.0f,0.0f,0.0f); if (iPointSize <= 0) return dataBounds; vertexData *vertexD = new vertexData[iPointSize * 4 + (iPointSize - 1) * 2]; int n = 0; for (int i = 0; i < iPointSize; i++) { CZ2DPoint result = points[i]; float angle = angles[i]; float size = sizes[i] / 2; float alpha = alphas[i]; // get the four corners of the dot CZRect rect = CZRect(result.x - size, result.y - size, size*2, size*2); CZ2DPoint a = CZ2DPoint(rect.getMinX(), rect.getMinY()); CZ2DPoint b = CZ2DPoint(rect.getMaxX(), rect.getMinY()); CZ2DPoint c = CZ2DPoint(rect.getMinX(), rect.getMaxY()); CZ2DPoint d = CZ2DPoint(rect.getMaxX(), rect.getMaxY()); // rotate the dot CZ2DPoint center = rect.getCenter(); CZAffineTransform t = CZAffineTransform::makeFromTranslation(center.x, center.y); t.rotate(angle); t.translate(-center.x, -center.y); a = t.applyTo2DPoint(a); b = t.applyTo2DPoint(b); c = t.applyTo2DPoint(c); d = t.applyTo2DPoint(d); // update the bounds box of data CZRect boxBounds = t.applyToRect(rect); dataBounds = dataBounds.unionWith(boxBounds.expandToIntergral()); if (n != 0) { // dup 1st vertex vertexD[n].x = a.x; vertexD[n].y = a.y; vertexD[n].s = 0; vertexD[n].t = 0; vertexD[n].a = alpha; n++; } vertexD[n].x = a.x; vertexD[n].y = a.y; vertexD[n].s = 0; vertexD[n].t = 0; vertexD[n].a = alpha; n++; vertexD[n].x = b.x; vertexD[n].y = b.y; vertexD[n].s = 1; vertexD[n].t = 0; vertexD[n].a = alpha; n++; vertexD[n].x = c.x; vertexD[n].y = c.y; vertexD[n].s = 0; vertexD[n].t = 1; vertexD[n].a = alpha; n++; vertexD[n].x = d.x; vertexD[n].y = d.y; vertexD[n].s = 1; vertexD[n].t = 1; vertexD[n].a = alpha; n++; if (i != (iPointSize - 1)) { // dup last vertex vertexD[n].x = d.x; vertexD[n].y = d.y; vertexD[n].s = 1; vertexD[n].t = 1; vertexD[n].a = alpha; n++; } } #ifdef USE_OPENGL_ES glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(vertexData), &vertexD[0].x); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_TRUE, sizeof(vertexData), &vertexD[0].s); glEnableVertexAttribArray(1); glVertexAttribPointer(2, 1, GL_FLOAT, GL_TRUE, sizeof(vertexData), &vertexD[0].a); glEnableVertexAttribArray(2); glDrawArrays(GL_TRIANGLE_STRIP, 0, n); #endif #ifdef USE_OPENGL /* // 对于opengl属性数组形式, 顶点位置必须通过以下方式导入 glEnableClientState (GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT , sizeof(vertexData), &data[0].x); glVertexAttribPointer(1, 2, GL_FLOAT, GL_TRUE, sizeof(vertexData), &data[0].s); glEnableVertexAttribArray(1); glVertexAttribPointer(2, 1, GL_FLOAT, GL_TRUE, sizeof(vertexData), &data[0].a); glEnableVertexAttribArray(2); /// 绘制 glDrawArrays(GL_TRIANGLE_STRIP,0,n); */ GLuint mVertexBufferObject, mTexCoordBufferObject, mAttributeBufferObject; // 装载顶点 glGenBuffers(1, &mVertexBufferObject); glBindBuffer(GL_ARRAY_BUFFER, mVertexBufferObject); glBufferData(GL_ARRAY_BUFFER, n * sizeof(vertexData), &vertexD[0].x, GL_STREAM_DRAW); // 装载纹理 glGenBuffers(1, &mTexCoordBufferObject); glBindBuffer(GL_ARRAY_BUFFER, mTexCoordBufferObject); glBufferData(GL_ARRAY_BUFFER, n * sizeof(vertexData), &vertexD[0].s, GL_STREAM_DRAW); // 装载属性 glGenBuffers(1, &mAttributeBufferObject); glBindBuffer(GL_ARRAY_BUFFER, mAttributeBufferObject); glBufferData(GL_ARRAY_BUFFER, n * sizeof(vertexData), &vertexD[0].a, GL_STREAM_DRAW); // 绑定顶点 glBindBuffer(GL_ARRAY_BUFFER, mVertexBufferObject); glEnableVertexAttribArray(0); glVertexAttribPointer(0,2,GL_FLOAT, GL_FALSE, sizeof(vertexData),0); // 绑定纹理 glBindBuffer(GL_ARRAY_BUFFER, mTexCoordBufferObject); glEnableVertexAttribArray(1); glVertexAttribPointer(1,2,GL_FLOAT, GL_TRUE, sizeof(vertexData),0); // 绑定属性 glBindBuffer(GL_ARRAY_BUFFER, mAttributeBufferObject); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 1, GL_FLOAT, GL_TRUE, sizeof(vertexData), NULL); /// 绘制 glDrawArrays(GL_TRIANGLE_STRIP,0,n); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); glBindBuffer(GL_ARRAY_BUFFER, 0); /// 消除 glDeleteBuffers(1, &mVertexBufferObject); glDeleteBuffers(1, &mTexCoordBufferObject); glDeleteBuffers(1, &mAttributeBufferObject); #endif CZCheckGLError(); delete [] vertexD; return dataBounds; }