This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/gpu/gawain/batch.c
Mike Erwin 0f759da370 Gawain: batch drawing works
Forgot to tell OpenGL which shader program the batch is using. Now it works!
2016-09-20 18:03:59 +02:00

125 lines
3.0 KiB
C

// Gawain geometry batch
//
// This code is part of the Gawain library, with modifications
// specific to integration with Blender.
//
// Copyright 2016 Mike Erwin
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
#include "batch.h"
#include <stdlib.h>
Batch* Batch_create(GLenum prim_type, VertexBuffer* verts, ElementList* elem)
{
#if TRUST_NO_ONE
assert(verts != NULL);
assert(prim_type == GL_POINTS || prim_type == GL_LINES || prim_type == GL_TRIANGLES);
// we will allow other primitive types in a future update
#endif
Batch* batch = calloc(1, sizeof(Batch));
batch->verts = verts;
batch->elem = elem;
batch->prim_type = prim_type;
batch->phase = READY_TO_DRAW;
return batch;
}
void Batch_set_program(Batch* batch, GLuint program)
{
batch->program = program;
batch->program_dirty = true;
}
static void Batch_update_program_bindings(Batch* batch)
{
#if TRUST_NO_ONE
assert(glIsProgram(batch->program));
#endif
const VertexFormat* format = &batch->verts->format;
const unsigned attrib_ct = format->attrib_ct;
const unsigned stride = format->stride;
for (unsigned a_idx = 0; a_idx < attrib_ct; ++a_idx)
{
const Attrib* a = format->attribs + a_idx;
const GLvoid* pointer = (const GLubyte*)0 + a->offset;
const unsigned loc = glGetAttribLocation(batch->program, a->name);
glEnableVertexAttribArray(loc);
switch (a->fetch_mode)
{
case KEEP_FLOAT:
case CONVERT_INT_TO_FLOAT:
glVertexAttribPointer(loc, a->comp_ct, a->comp_type, GL_FALSE, stride, pointer);
break;
case NORMALIZE_INT_TO_FLOAT:
glVertexAttribPointer(loc, a->comp_ct, a->comp_type, GL_TRUE, stride, pointer);
break;
case KEEP_INT:
glVertexAttribIPointer(loc, a->comp_ct, a->comp_type, stride, pointer);
}
}
batch->program_dirty = false;
}
static void Batch_prime(Batch* batch)
{
glGenVertexArrays(1, &batch->vao_id);
glBindVertexArray(batch->vao_id);
VertexBuffer_use(batch->verts);
if (batch->elem)
ElementList_use(batch->elem);
// vertex attribs and element list remain bound to this VAO
}
void Batch_draw(Batch* batch)
{
#if TRUST_NO_ONE
assert(batch->phase == READY_TO_DRAW);
#endif
if (batch->vao_id)
glBindVertexArray(batch->vao_id);
else
Batch_prime(batch);
if (batch->program_dirty)
Batch_update_program_bindings(batch);
glUseProgram(batch->program);
if (batch->elem)
{
const ElementList* el = batch->elem;
#if TRACK_INDEX_RANGE
if (el->base_index)
glDrawRangeElementsBaseVertex(batch->prim_type, el->min_index, el->max_index, el->index_ct, el->index_type, 0, el->base_index);
else
glDrawRangeElements(batch->prim_type, el->min_index, el->max_index, el->index_ct, el->index_type, 0);
#else
glDrawElements(batch->prim_type, el->index_ct, GL_UNSIGNED_INT, 0);
#endif
}
else
glDrawArrays(batch->prim_type, 0, batch->verts->vertex_ct);
glUseProgram(0);
glBindVertexArray(0);
}