<commit_before>#include "VertexArray.hpp"

#include "Error.hpp"
#include "InvalidObject.hpp"
#include "Primitive.hpp"
#include "Buffer.hpp"

#include "Attribute.hpp"
#include "VertexArrayAttribute.hpp"
#include "VertexArrayListAttribute.hpp"
#include "VertexArrayMatrixAttribute.hpp"

PyObject * MGLVertexArray_tp_new(PyTypeObject * type, PyObject * args, PyObject * kwargs) {
	MGLVertexArray * self = (MGLVertexArray *)type->tp_alloc(type, 0);

	#ifdef MGL_VERBOSE
	printf("MGLVertexArray_tp_new %p\n", self);
	#endif

	if (self) {
	}

	return (PyObject *)self;
}

void MGLVertexArray_tp_dealloc(MGLVertexArray * self) {

	#ifdef MGL_VERBOSE
	printf("MGLVertexArray_tp_dealloc %p\n", self);
	#endif

	MGLVertexArray_Type.tp_free((PyObject *)self);
}

int MGLVertexArray_tp_init(MGLVertexArray * self, PyObject * args, PyObject * kwargs) {
	MGLError * error = MGLError_New(TRACE, "Cannot create ModernGL.VertexArray manually");
	PyErr_SetObject((PyObject *)&MGLError_Type, (PyObject *)error);
	return -1;
}

PyObject * MGLVertexArray_tp_str(MGLVertexArray * self) {
	return PyUnicode_FromFormat("<ModernGL.VertexArray>");
}

PyObject * MGLVertexArray_render(MGLVertexArray * self, PyObject * args, PyObject * kwargs) {
	static const char * kwlist[] = {"mode", "vertices", "first", "instances", 0};

	MGLPrimitive * mode = MGL_TRIANGLES;
	int vertices = -1;
	int first = 0;
	int instances = 1;

	int args_ok = PyArg_ParseTupleAndKeywords(
		args,
		kwargs,
		"|O!I$II",
		(char **)kwlist,
		&MGLPrimitive_Type,
		&mode,
		&vertices,
		&first,
		&instances
	);

	if (!args_ok) {
		return 0;
	}

	if (vertices < 0) {
		if (self->num_vertices < 0) {
			MGLError * error = MGLError_New(TRACE, "Cannot detect the number of vertices");
			PyErr_SetObject((PyObject *)&MGLError_Type, (PyObject *)error);
			return 0;
		}

		vertices = self->num_vertices;
	}

	MGLPrimitive * gs_input = self->program->geometry_input;

	if (gs_input && gs_input->primitive != mode->geometry_primitive) {
		MGLError * error = MGLError_New(TRACE, "GeometryShader input is different from render mode");
		PyErr_SetObject((PyObject *)&MGLError_Type, (PyObject *)error);
		return 0;
	}

	const GLMethods & gl = self->context->gl;

	gl.UseProgram(self->program->program_obj);
	gl.BindVertexArray(self->vertex_array_obj);

	if (self->index_buffer != (MGLBuffer *)Py_None) {
		const void * ptr = (const void *)((GLintptr)first * 4);
		gl.DrawElementsInstanced(mode->primitive, vertices, GL_UNSIGNED_INT, ptr, instances);
	} else {
		gl.DrawArraysInstanced(mode->primitive, first, vertices, instances);
	}

	Py_RETURN_NONE;
}

const char * MGLVertexArray_render_doc = R"(
	render(mode, vertices, first, instances)

	The render primitive (mode) must be the same as the input primitive of the GeometryShader.

	Args:
		optional mode: By default :py:const:`~ModernGL.TRIANGLES` will be used.
		optional vertices: The number of vertices to transform.

	Keyword Args:
		first: The index of the first vertex to start with.
		instances: The number of instances.

	Returns:
		None
)";

PyObject * MGLVertexArray_transform(MGLVertexArray * self, PyObject * args, PyObject * kwargs) {
	static const char * kwlist[] = {"output", "mode", "vertices", "first", "instances", 0};

	MGLBuffer * output;
	MGLPrimitive * mode = MGL_TRIANGLES;
	int vertices = -1;
	int first = 0;
	int instances = 1;

	int args_ok = PyArg_ParseTupleAndKeywords(
		args,
		kwargs,
		"O!|O!I$IIO!",
		(char **)kwlist,
		&MGLBuffer_Type,
		&output,
		&MGLPrimitive_Type,
		&mode,
		&vertices,
		&first,
		&instances<commit_msg>transform points by default<commit_after>#include "VertexArray.hpp"

#include "Error.hpp"
#include "InvalidObject.hpp"
#include "Primitive.hpp"
#include "Buffer.hpp"

#include "Attribute.hpp"
#include "VertexArrayAttribute.hpp"
#include "VertexArrayListAttribute.hpp"
#include "VertexArrayMatrixAttribute.hpp"

PyObject * MGLVertexArray_tp_new(PyTypeObject * type, PyObject * args, PyObject * kwargs) {
	MGLVertexArray * self = (MGLVertexArray *)type->tp_alloc(type, 0);

	#ifdef MGL_VERBOSE
	printf("MGLVertexArray_tp_new %p\n", self);
	#endif

	if (self) {
	}

	return (PyObject *)self;
}

void MGLVertexArray_tp_dealloc(MGLVertexArray * self) {

	#ifdef MGL_VERBOSE
	printf("MGLVertexArray_tp_dealloc %p\n", self);
	#endif

	MGLVertexArray_Type.tp_free((PyObject *)self);
}

int MGLVertexArray_tp_init(MGLVertexArray * self, PyObject * args, PyObject * kwargs) {
	MGLError * error = MGLError_New(TRACE, "Cannot create ModernGL.VertexArray manually");
	PyErr_SetObject((PyObject *)&MGLError_Type, (PyObject *)error);
	return -1;
}

PyObject * MGLVertexArray_tp_str(MGLVertexArray * self) {
	return PyUnicode_FromFormat("<ModernGL.VertexArray>");
}

PyObject * MGLVertexArray_render(MGLVertexArray * self, PyObject * args, PyObject * kwargs) {
	static const char * kwlist[] = {"mode", "vertices", "first", "instances", 0};

	MGLPrimitive * mode = MGL_TRIANGLES;
	int vertices = -1;
	int first = 0;
	int instances = 1;

	int args_ok = PyArg_ParseTupleAndKeywords(
		args,
		kwargs,
		"|O!I$II",
		(char **)kwlist,
		&MGLPrimitive_Type,
		&mode,
		&vertices,
		&first,
		&instances
	);

	if (!args_ok) {
		return 0;
	}

	if (vertices < 0) {
		if (self->num_vertices < 0) {
			MGLError * error = MGLError_New(TRACE, "Cannot detect the number of vertices");
			PyErr_SetObject((PyObject *)&MGLError_Type, (PyObject *)error);
			return 0;
		}

		vertices = self->num_vertices;
	}

	MGLPrimitive * gs_input = self->program->geometry_input;

	if (gs_input && gs_input->primitive != mode->geometry_primitive) {
		MGLError * error = MGLError_New(TRACE, "GeometryShader input is different from render mode");
		PyErr_SetObject((PyObject *)&MGLError_Type, (PyObject *)error);
		return 0;
	}

	const GLMethods & gl = self->context->gl;

	gl.UseProgram(self->program->program_obj);
	gl.BindVertexArray(self->vertex_array_obj);

	if (self->index_buffer != (MGLBuffer *)Py_None) {
		const void * ptr = (const void *)((GLintptr)first * 4);
		gl.DrawElementsInstanced(mode->primitive, vertices, GL_UNSIGNED_INT, ptr, instances);
	} else {
		gl.DrawArraysInstanced(mode->primitive, first, vertices, instances);
	}

	Py_RETURN_NONE;
}

const char * MGLVertexArray_render_doc = R"(
	render(mode, vertices, first, instances)

	The render primitive (mode) must be the same as the input primitive of the GeometryShader.

	Args:
		optional mode: By default :py:const:`~ModernGL.TRIANGLES` will be used.
		optional vertices: The number of vertices to transform.

	Keyword Args:
		first: The index of the first vertex to start with.
		instances: The number of instances.

	Returns:
		None
)";

PyObject * MGLVertexArray_transform(MGLVertexArray * self, PyObject * args, PyObject * kwargs) {
	static const char * kwlist[] = {"output", "mode", "vertices", "first", "instances", 0};

	MGLBuffer * output;
	MGLPrimitive * mode = MGL_POINTS;
	int vertices = -1;
	int first = 0;
	int instances = 1;

	int args_ok = PyArg_ParseTupleAndKeywords(
		args,
		kwargs,
		"O!|O!I$IIO!",
		(char **)kwlist,
		&MGLBuffer_Type,
		&output,
		&MGLPrimitive_Type,
		&mode,
		&vertices,
		&first,
		&instances
{'fraction_non_alphanumeric': 0.12986647926914968, 'fraction_numerical': 0.0044975404075896, 'mean_word_length': 5.0613287904599655, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3471268', 'n_tokens_mistral': 2664, 'n_tokens_neox': 2554, 'n_words': 608}