void GL3CharacterRenderer::buildHead() {
	GL(GenVertexArrays(1, &headVao));
	GL(GenBuffers(1, &headVbo));
	GL(BindVertexArray(headVao));
	GL(BindBuffer(GL_ARRAY_BUFFER, headVbo));
	GL(VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 40, 0));
	GL(VertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 40, (void *) 12));
	GL(VertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 40, (void *) 24));
	GL(EnableVertexAttribArray(0));
	GL(EnableVertexAttribArray(1));
	GL(EnableVertexAttribArray(2));
	GL(BindVertexArray(0));

	VertexData vertexData[36];
	int vertexIndices[6] = {0, 1, 2, 0, 2, 3};
	int index = 0;
	for (int d = 0; d < 6; d++) {
		vec3f normal(0.0);
		normal[d % 3] = DIRS[d][d % 3];
		vec3f vertices[4];
		for (int i = 0; i < 4; i++) {
			vertices[i] = vec3f(
				(DIR_QUAD_CORNER_CYCLES_3D[d][i][0] - 0.5f) * HEAD_SIZE[0],
				(DIR_QUAD_CORNER_CYCLES_3D[d][i][1] - 0.5f) * HEAD_SIZE[1],
				(DIR_QUAD_CORNER_CYCLES_3D[d][i][2] - 0.5f) * HEAD_SIZE[2] + HEAD_Z_OFFSET
			) * (1.0f / RESOLUTION);
		}
		for (int j = 0; j < 6; j++) {
			vertexData[index].xyz[0] = vertices[vertexIndices[j]][0];
			vertexData[index].xyz[1] = vertices[vertexIndices[j]][1];
			vertexData[index].xyz[2] = vertices[vertexIndices[j]][2];
			vertexData[index].nxyz[0] = normal[0];
			vertexData[index].nxyz[1] = normal[1];
			vertexData[index].nxyz[2] = normal[2];
			vertexData[index].rgba[0] = CHARACTER_COLOR[0];
			vertexData[index].rgba[1] = CHARACTER_COLOR[1];
			vertexData[index].rgba[2] = CHARACTER_COLOR[2];
			vertexData[index].rgba[3] = 1.0f;
			index++;
		}
	}

	GL(BufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW));
	GL(BindBuffer(GL_ARRAY_BUFFER, 0));
}
Exemple #2
0
/*******************************************************************************
 *
 * Vertex array functions.
 *
 ******************************************************************************/
int
rb_create_vertex_array
  (struct rb_context* ctxt,
   struct rb_vertex_array** out_array)
{
  struct rb_vertex_array* array = NULL;

  if(!ctxt || !out_array)
    return -1;

  array = MEM_ALLOC(ctxt->allocator, sizeof(struct rb_vertex_array));
  if(!array)
    return -1;
  ref_init(&array->ref);
  RB(context_ref_get(ctxt));
  array->ctxt = ctxt;

  OGL(GenVertexArrays(1, &array->name));
  *out_array = array;
  return 0;
}
void GLCpuPosInstancedArraysBench::setup(const GrGLContext* ctx) {
    const GrGLInterface* gl = ctx->interface();
    fTexture = SetupFramebuffer(gl, kScreenWidth, kScreenHeight);

    fProgram = this->setupShader(ctx);

    // setup matrices
    int index = 0;
    SkMatrix viewMatrices[kNumTri];
    setup_matrices(kNumTri, [&index, &viewMatrices](const SkMatrix& m) {
        viewMatrices[index++] = m;
    });

    // setup VAO
    GR_GL_CALL(gl, GenVertexArrays(1, &fVAO));
    GR_GL_CALL(gl, BindVertexArray(fVAO));

    switch (fVboSetup) {
        case kUseOne_VboSetup:
            this->setupSingleVbo(gl, viewMatrices);
            break;
        case kUseTwo_VboSetup:
            this->setupDoubleVbo(gl, viewMatrices);
            break;
        case kUseInstance_VboSetup:
            this->setupInstanceVbo(gl, viewMatrices);
            break;
    }

    // clear screen
    GR_GL_CALL(gl, ClearColor(0.03f, 0.03f, 0.03f, 1.0f));
    GR_GL_CALL(gl, Clear(GR_GL_COLOR_BUFFER_BIT));

    // set us up to draw
    GR_GL_CALL(gl, UseProgram(fProgram));
    GR_GL_CALL(gl, BindVertexArray(fVAO));
}
void GLInstancedRendering::onBeginFlush(GrResourceProvider* rp) {
    // Count what there is to draw.
    BatchList::Iter iter;
    iter.init(this->trackedBatches(), BatchList::Iter::kHead_IterStart);
    int numGLInstances = 0;
    int numGLDrawCmds = 0;
    while (Batch* b = iter.get()) {
        GLBatch* batch = static_cast<GLBatch*>(b);
        iter.next();

        numGLInstances += batch->fNumDraws;
        numGLDrawCmds += batch->numGLCommands();
    }
    if (!numGLDrawCmds) {
        return;
    }
    SkASSERT(numGLInstances);

    // Lazily create a vertex array object.
    if (!fVertexArrayID) {
        GL_CALL(GenVertexArrays(1, &fVertexArrayID));
        if (!fVertexArrayID) {
            return;
        }
        this->glGpu()->bindVertexArray(fVertexArrayID);

        // Attach our index buffer to the vertex array.
        SkASSERT(!this->indexBuffer()->isCPUBacked());
        GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER,
                           static_cast<const GrGLBuffer*>(this->indexBuffer())->bufferID()));

        // Set up the non-instanced attribs.
        this->glGpu()->bindBuffer(kVertex_GrBufferType, this->vertexBuffer());
        GL_CALL(EnableVertexAttribArray((int)Attrib::kShapeCoords));
        GL_CALL(VertexAttribPointer((int)Attrib::kShapeCoords, 2, GR_GL_FLOAT, GR_GL_FALSE,
                                    sizeof(ShapeVertex), (void*) offsetof(ShapeVertex, fX)));
        GL_CALL(EnableVertexAttribArray((int)Attrib::kVertexAttrs));
        GL_CALL(VertexAttribIPointer((int)Attrib::kVertexAttrs, 1, GR_GL_INT, sizeof(ShapeVertex),
                                     (void*) offsetof(ShapeVertex, fAttrs)));

        SkASSERT(SK_InvalidUniqueID == fInstanceAttribsBufferUniqueId);
    }

    // Create and map instance and draw-indirect buffers.
    SkASSERT(!fInstanceBuffer);
    fInstanceBuffer.reset(
        rp->createBuffer(sizeof(Instance) * numGLInstances, kVertex_GrBufferType,
                         kDynamic_GrAccessPattern,
                         GrResourceProvider::kNoPendingIO_Flag |
                         GrResourceProvider::kRequireGpuMemory_Flag));
    if (!fInstanceBuffer) {
        return;
    }

    SkASSERT(!fDrawIndirectBuffer);
    fDrawIndirectBuffer.reset(
        rp->createBuffer(sizeof(GrGLDrawElementsIndirectCommand) * numGLDrawCmds,
                         kDrawIndirect_GrBufferType, kDynamic_GrAccessPattern,
                         GrResourceProvider::kNoPendingIO_Flag |
                         GrResourceProvider::kRequireGpuMemory_Flag));
    if (!fDrawIndirectBuffer) {
        return;
    }

    Instance* glMappedInstances = static_cast<Instance*>(fInstanceBuffer->map());
    int glInstancesIdx = 0;

    auto* glMappedCmds = static_cast<GrGLDrawElementsIndirectCommand*>(fDrawIndirectBuffer->map());
    int glDrawCmdsIdx = 0;

    bool baseInstanceSupport = this->glGpu()->glCaps().baseInstanceSupport();

    if (GR_GL_LOG_INSTANCED_BATCHES || !baseInstanceSupport) {
        fGLDrawCmdsInfo.reset(numGLDrawCmds);
    }

    // Generate the instance and draw-indirect buffer contents based on the tracked batches.
    iter.init(this->trackedBatches(), BatchList::Iter::kHead_IterStart);
    while (Batch* b = iter.get()) {
        GLBatch* batch = static_cast<GLBatch*>(b);
        iter.next();

        batch->fEmulatedBaseInstance = baseInstanceSupport ? 0 : glInstancesIdx;
        batch->fGLDrawCmdsIdx = glDrawCmdsIdx;

        const Batch::Draw* draw = batch->fHeadDraw;
        SkASSERT(draw);
        do {
            int instanceCount = 0;
            IndexRange geometry = draw->fGeometry;
            SkASSERT(!geometry.isEmpty());

            do {
                glMappedInstances[glInstancesIdx + instanceCount++] = draw->fInstance;
                draw = draw->fNext;
            } while (draw && draw->fGeometry == geometry);

            GrGLDrawElementsIndirectCommand& glCmd = glMappedCmds[glDrawCmdsIdx];
            glCmd.fCount = geometry.fCount;
            glCmd.fInstanceCount = instanceCount;
            glCmd.fFirstIndex = geometry.fStart;
            glCmd.fBaseVertex = 0;
            glCmd.fBaseInstance = baseInstanceSupport ? glInstancesIdx : 0;

            if (GR_GL_LOG_INSTANCED_BATCHES || !baseInstanceSupport) {
                fGLDrawCmdsInfo[glDrawCmdsIdx].fInstanceCount = instanceCount;
#if GR_GL_LOG_INSTANCED_BATCHES
                fGLDrawCmdsInfo[glDrawCmdsIdx].fGeometry = geometry;
#endif
            }

            glInstancesIdx += instanceCount;
            ++glDrawCmdsIdx;
        } while (draw);
    }

    SkASSERT(glDrawCmdsIdx == numGLDrawCmds);
    fDrawIndirectBuffer->unmap();

    SkASSERT(glInstancesIdx == numGLInstances);
    fInstanceBuffer->unmap();
}
void GLGpuPosInstancedArraysBench::setup(const GrGLInterface* gl) {
    setup_framebuffer(gl, kScreenWidth, kScreenHeight);

    // compile and use shaders
    GrGLint shaderProgram = compile_shader(gl, gpu_vertex_shader, fragment_shader);

    // translations
    int index = 0;
    GrGLfloat viewMatrices[fNumQuads * fSkMatrixNumCells];
    setup_matrices(fNumQuads, [&index, &viewMatrices](const SkMatrix& m) {
        GrGLGetMatrix<3>(&viewMatrices[index], m);
        index += fSkMatrixNumCells;
    });

    // Constants for our various shader programs
    GrGLfloat quad_vertices[] = {
            // Positions // Colors
            -1.0f,  1.0f,  1.0f, 0.0f, 0.0f,
             1.0f, -1.0f,  0.0f, 1.0f, 0.0f,
            -1.0f, -1.0f,  0.0f, 0.0f, 1.0f,

            -1.0f,  1.0f,  1.0f, 0.0f, 0.0f,
             1.0f, -1.0f,  0.0f, 1.0f, 0.0f,
             1.0f,  1.0f,  0.0f, 1.0f, 1.0f
    };

    // update vertex data
    GrGLuint quadVAO, quadVBO;
    GR_GL_CALL(gl, GenVertexArrays(1, &quadVAO));
    GR_GL_CALL(gl, GenBuffers(1, &quadVBO));
    GR_GL_CALL(gl, BindVertexArray(quadVAO));
    GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, quadVBO));
    GR_GL_CALL(gl, EnableVertexAttribArray(0));
    GR_GL_CALL(gl, VertexAttribPointer(0, 2, GR_GL_FLOAT, GR_GL_FALSE, 5 * sizeof(GrGLfloat), (GrGLvoid*)0));
    GR_GL_CALL(gl, EnableVertexAttribArray(1));
    GR_GL_CALL(gl, VertexAttribPointer(1, 3, GR_GL_FLOAT, GR_GL_FALSE, 5 * sizeof(GrGLfloat), (GrGLvoid*)(2 * sizeof(GrGLfloat))));
    GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(quad_vertices), quad_vertices, GR_GL_STATIC_DRAW));

    // Also set instance data
    GrGLuint instanceVBO;
    GR_GL_CALL(gl, GenBuffers(1, &instanceVBO));
    GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, instanceVBO));
    GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(GrGLfloat) * fSkMatrixNumCells * fNumQuads,
                              &viewMatrices[0], GR_GL_STATIC_DRAW));
    GR_GL_CALL(gl, EnableVertexAttribArray(2));
    GR_GL_CALL(gl, EnableVertexAttribArray(3));
    GR_GL_CALL(gl, EnableVertexAttribArray(4));
    GR_GL_CALL(gl, VertexAttribPointer(2, 3, GR_GL_FLOAT, GR_GL_FALSE, 9 * sizeof(GrGLfloat), (GrGLvoid*)0));
    GR_GL_CALL(gl, VertexAttribPointer(3, 3, GR_GL_FLOAT, GR_GL_FALSE, 9 * sizeof(GrGLfloat), (GrGLvoid*)(3 * sizeof(GrGLfloat))));
    GR_GL_CALL(gl, VertexAttribPointer(4, 3, GR_GL_FLOAT, GR_GL_FALSE, 9 * sizeof(GrGLfloat), (GrGLvoid*)(6 * sizeof(GrGLfloat))));
    GR_GL_CALL(gl, VertexAttribDivisor(2, 1));
    GR_GL_CALL(gl, VertexAttribDivisor(3, 1));
    GR_GL_CALL(gl, VertexAttribDivisor(4, 1));

    // draw
    GR_GL_CALL(gl, ClearColor(0.03f, 0.03f, 0.03f, 1.0f));
    GR_GL_CALL(gl, Clear(GR_GL_COLOR_BUFFER_BIT));

    // set us up to draw
    GR_GL_CALL(gl, UseProgram(shaderProgram));
    GR_GL_CALL(gl, BindVertexArray(quadVAO));
}
 inline void glGenVertexArrays(GLsizei n, GLuint *arrays)
 {
     GenVertexArrays(n, arrays);
 }