| 
									
										
										
										
											2016-09-15 18:41:28 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  |  * The Original Code is Copyright (C) 2016 by Mike Erwin. | 
					
						
							| 
									
										
										
										
											2016-09-15 18:41:28 +02:00
										 |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup gpu | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-07-18 00:12:21 +02:00
										 |  |  |  * GPU immediate mode work-alike | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-11 14:52:57 +11:00
										 |  |  | #ifndef GPU_STANDALONE
 | 
					
						
							|  |  |  | #  include "UI_resources.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-10-12 23:01:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #include "GPU_attr_binding.h"
 | 
					
						
							|  |  |  | #include "GPU_immediate.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "gpu_attr_binding_private.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-19 15:48:13 +02:00
										 |  |  | #include "gpu_context_private.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #include "gpu_primitive_private.h"
 | 
					
						
							| 
									
										
										
										
											2016-09-15 18:41:28 +02:00
										 |  |  | #include "gpu_shader_private.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #include "gpu_vertex_format_private.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* necessary functions from matrix API */ | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | extern void GPU_matrix_bind(const GPUShaderInterface *); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | extern bool GPU_matrix_dirty_get(void); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* TODO: organize this struct by frequency of change (run-time) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GPUBatch *batch; | 
					
						
							|  |  |  |   GPUContext *context; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* current draw call */ | 
					
						
							|  |  |  |   GLubyte *buffer_data; | 
					
						
							|  |  |  |   uint buffer_offset; | 
					
						
							|  |  |  |   uint buffer_bytes_mapped; | 
					
						
							|  |  |  |   uint vertex_len; | 
					
						
							|  |  |  |   bool strict_vertex_len; | 
					
						
							|  |  |  |   GPUPrimType prim_type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GPUVertFormat vertex_format; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* current vertex */ | 
					
						
							|  |  |  |   uint vertex_idx; | 
					
						
							|  |  |  |   GLubyte *vertex_data; | 
					
						
							|  |  |  |   uint16_t | 
					
						
							|  |  |  |       unassigned_attr_bits; /* which attributes of current vertex have not been given values? */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GLuint vbo_id; | 
					
						
							|  |  |  |   GLuint vao_id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GLuint bound_program; | 
					
						
							|  |  |  |   const GPUShaderInterface *shader_interface; | 
					
						
							|  |  |  |   GPUAttrBinding attr_binding; | 
					
						
							|  |  |  |   uint16_t prev_enabled_attr_bits; /* <-- only affects this VAO, so we're ok */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } Immediate; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-06 17:01:33 +02:00
										 |  |  | /* size of internal buffer */ | 
					
						
							|  |  |  | #define DEFAULT_INTERNAL_BUFFER_SIZE (4 * 1024 * 1024)
 | 
					
						
							|  |  |  | static uint imm_buffer_size = DEFAULT_INTERNAL_BUFFER_SIZE; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | static bool initialized = false; | 
					
						
							|  |  |  | static Immediate imm; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void immInit(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(!initialized); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   memset(&imm, 0, sizeof(Immediate)); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.vbo_id = GPU_buf_alloc(); | 
					
						
							|  |  |  |   glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id); | 
					
						
							| 
									
										
										
										
											2019-09-06 17:01:33 +02:00
										 |  |  |   glBufferData(GL_ARRAY_BUFFER, imm_buffer_size, NULL, GL_DYNAMIC_DRAW); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.prim_type = GPU_PRIM_NONE; | 
					
						
							|  |  |  |   imm.strict_vertex_len = true; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   glBindBuffer(GL_ARRAY_BUFFER, 0); | 
					
						
							|  |  |  |   initialized = true; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void immActivate(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(initialized); | 
					
						
							|  |  |  |   assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we're not between a Begin/End pair */ | 
					
						
							|  |  |  |   assert(imm.vao_id == 0); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.vao_id = GPU_vao_alloc(); | 
					
						
							|  |  |  |   imm.context = GPU_context_active_get(); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void immDeactivate(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(initialized); | 
					
						
							|  |  |  |   assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we're not between a Begin/End pair */ | 
					
						
							|  |  |  |   assert(imm.vao_id != 0); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPU_vao_free(imm.vao_id, imm.context); | 
					
						
							|  |  |  |   imm.vao_id = 0; | 
					
						
							|  |  |  |   imm.prev_enabled_attr_bits = 0; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void immDestroy(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPU_buf_free(imm.vbo_id); | 
					
						
							|  |  |  |   initialized = false; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | GPUVertFormat *immVertexFormat(void) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPU_vertformat_clear(&imm.vertex_format); | 
					
						
							|  |  |  |   return &imm.vertex_format; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void immBindProgram(GLuint program, const GPUShaderInterface *shaderface) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(imm.bound_program == 0); | 
					
						
							|  |  |  |   assert(glIsProgram(program)); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.bound_program = program; | 
					
						
							|  |  |  |   imm.shader_interface = shaderface; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-22 09:32:37 +10:00
										 |  |  |   if (!imm.vertex_format.packed) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     VertexFormat_pack(&imm.vertex_format); | 
					
						
							| 
									
										
										
										
											2019-04-22 09:32:37 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   glUseProgram(program); | 
					
						
							|  |  |  |   get_attr_locations(&imm.vertex_format, &imm.attr_binding, shaderface); | 
					
						
							|  |  |  |   GPU_matrix_bind(shaderface); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-15 18:41:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-23 14:15:43 +11:00
										 |  |  | void immBindBuiltinProgram(eGPUBuiltinShader shader_id) | 
					
						
							| 
									
										
										
										
											2016-09-15 18:41:28 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPUShader *shader = GPU_shader_get_builtin_shader(shader_id); | 
					
						
							|  |  |  |   immBindProgram(shader->program, shader->interface); | 
					
						
							| 
									
										
										
										
											2016-09-15 18:41:28 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-10-12 23:01:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | void immUnbindProgram(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(imm.bound_program != 0); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #if PROGRAM_NO_OPTI
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   glUseProgram(0); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.bound_program = 0; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-11 15:18:55 +01:00
										 |  |  | /* XXX do not use it. Special hack to use OCIO with batch API. */ | 
					
						
							|  |  |  | void immGetProgram(GLuint *program, GPUShaderInterface **shaderface) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   *program = imm.bound_program; | 
					
						
							|  |  |  |   *shaderface = (GPUShaderInterface *)imm.shader_interface; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2018-07-18 00:12:21 +02:00
										 |  |  | static bool vertex_count_makes_sense_for_primitive(uint vertex_len, GPUPrimType prim_type) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* does vertex_len make sense for this primitive type? */ | 
					
						
							|  |  |  |   if (vertex_len == 0) { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (prim_type) { | 
					
						
							|  |  |  |     case GPU_PRIM_POINTS: | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     case GPU_PRIM_LINES: | 
					
						
							|  |  |  |       return vertex_len % 2 == 0; | 
					
						
							|  |  |  |     case GPU_PRIM_LINE_STRIP: | 
					
						
							|  |  |  |     case GPU_PRIM_LINE_LOOP: | 
					
						
							|  |  |  |       return vertex_len >= 2; | 
					
						
							|  |  |  |     case GPU_PRIM_LINE_STRIP_ADJ: | 
					
						
							|  |  |  |       return vertex_len >= 4; | 
					
						
							|  |  |  |     case GPU_PRIM_TRIS: | 
					
						
							|  |  |  |       return vertex_len % 3 == 0; | 
					
						
							|  |  |  |     case GPU_PRIM_TRI_STRIP: | 
					
						
							|  |  |  |     case GPU_PRIM_TRI_FAN: | 
					
						
							|  |  |  |       return vertex_len >= 3; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 00:12:21 +02:00
										 |  |  | void immBegin(GPUPrimType prim_type, uint vertex_len) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(initialized); | 
					
						
							|  |  |  |   assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we haven't already begun */ | 
					
						
							|  |  |  |   assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type)); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.prim_type = prim_type; | 
					
						
							|  |  |  |   imm.vertex_len = vertex_len; | 
					
						
							|  |  |  |   imm.vertex_idx = 0; | 
					
						
							|  |  |  |   imm.unassigned_attr_bits = imm.attr_binding.enabled_bits; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* how many bytes do we need for this draw call? */ | 
					
						
							|  |  |  |   const uint bytes_needed = vertex_buffer_size(&imm.vertex_format, vertex_len); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* does the current buffer have enough room? */ | 
					
						
							| 
									
										
										
										
											2019-09-06 17:01:33 +02:00
										 |  |  |   const uint available_bytes = imm_buffer_size - imm.buffer_offset; | 
					
						
							| 
									
										
										
										
											2019-08-14 23:29:46 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-06 17:01:33 +02:00
										 |  |  |   bool recreate_buffer = false; | 
					
						
							|  |  |  |   if (bytes_needed > imm_buffer_size) { | 
					
						
							|  |  |  |     /* expand the internal buffer */ | 
					
						
							|  |  |  |     imm_buffer_size = bytes_needed; | 
					
						
							|  |  |  |     recreate_buffer = true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (bytes_needed < DEFAULT_INTERNAL_BUFFER_SIZE && | 
					
						
							|  |  |  |            imm_buffer_size > DEFAULT_INTERNAL_BUFFER_SIZE) { | 
					
						
							|  |  |  |     /* shrink the internal buffer */ | 
					
						
							|  |  |  |     imm_buffer_size = DEFAULT_INTERNAL_BUFFER_SIZE; | 
					
						
							|  |  |  |     recreate_buffer = true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* ensure vertex data is aligned */ | 
					
						
							| 
									
										
										
										
											2019-08-14 23:29:46 +10:00
										 |  |  |   /* Might waste a little space, but it's safe. */ | 
					
						
							|  |  |  |   const uint pre_padding = padding(imm.buffer_offset, imm.vertex_format.stride); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-06 17:01:33 +02:00
										 |  |  |   if (!recreate_buffer && ((bytes_needed + pre_padding) <= available_bytes)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     imm.buffer_offset += pre_padding; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     /* orphan this buffer & start with a fresh one */ | 
					
						
							|  |  |  |     /* this method works on all platforms, old & new */ | 
					
						
							| 
									
										
										
										
											2019-09-06 17:01:33 +02:00
										 |  |  |     glBufferData(GL_ARRAY_BUFFER, imm_buffer_size, NULL, GL_DYNAMIC_DRAW); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     imm.buffer_offset = 0; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /*  printf("mapping %u to %u\n", imm.buffer_offset, imm.buffer_offset + bytes_needed - 1); */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.buffer_data = glMapBufferRange(GL_ARRAY_BUFFER, | 
					
						
							|  |  |  |                                      imm.buffer_offset, | 
					
						
							|  |  |  |                                      bytes_needed, | 
					
						
							|  |  |  |                                      GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | | 
					
						
							|  |  |  |                                          (imm.strict_vertex_len ? 0 : GL_MAP_FLUSH_EXPLICIT_BIT)); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(imm.buffer_data != NULL); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.buffer_bytes_mapped = bytes_needed; | 
					
						
							|  |  |  |   imm.vertex_data = imm.buffer_data; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 00:12:21 +02:00
										 |  |  | void immBeginAtMost(GPUPrimType prim_type, uint vertex_len) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(vertex_len > 0); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.strict_vertex_len = false; | 
					
						
							|  |  |  |   immBegin(prim_type, vertex_len); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | GPUBatch *immBeginBatch(GPUPrimType prim_type, uint vertex_len) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(initialized); | 
					
						
							|  |  |  |   assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we haven't already begun */ | 
					
						
							|  |  |  |   assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type)); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.prim_type = prim_type; | 
					
						
							|  |  |  |   imm.vertex_len = vertex_len; | 
					
						
							|  |  |  |   imm.vertex_idx = 0; | 
					
						
							|  |  |  |   imm.unassigned_attr_bits = imm.attr_binding.enabled_bits; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPUVertBuf *verts = GPU_vertbuf_create_with_format(&imm.vertex_format); | 
					
						
							|  |  |  |   GPU_vertbuf_data_alloc(verts, vertex_len); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.buffer_bytes_mapped = GPU_vertbuf_size_get(verts); | 
					
						
							|  |  |  |   imm.vertex_data = verts->data; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.batch = GPU_batch_create_ex(prim_type, verts, NULL, GPU_BATCH_OWNS_VBO); | 
					
						
							|  |  |  |   imm.batch->phase = GPU_BATCH_BUILDING; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return imm.batch; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | GPUBatch *immBeginBatchAtMost(GPUPrimType prim_type, uint vertex_len) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.strict_vertex_len = false; | 
					
						
							|  |  |  |   return immBeginBatch(prim_type, vertex_len); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void immDrawSetup(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* set up VAO -- can be done during Begin or End really */ | 
					
						
							|  |  |  |   glBindVertexArray(imm.vao_id); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* Enable/Disable vertex attributes as needed. */ | 
					
						
							|  |  |  |   if (imm.attr_binding.enabled_bits != imm.prev_enabled_attr_bits) { | 
					
						
							| 
									
										
										
										
											2019-09-08 00:12:26 +10:00
										 |  |  |     for (uint loc = 0; loc < GPU_VERT_ATTR_MAX_LEN; loc++) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       bool is_enabled = imm.attr_binding.enabled_bits & (1 << loc); | 
					
						
							|  |  |  |       bool was_enabled = imm.prev_enabled_attr_bits & (1 << loc); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       if (is_enabled && !was_enabled) { | 
					
						
							|  |  |  |         glEnableVertexAttribArray(loc); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if (was_enabled && !is_enabled) { | 
					
						
							|  |  |  |         glDisableVertexAttribArray(loc); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     imm.prev_enabled_attr_bits = imm.attr_binding.enabled_bits; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const uint stride = imm.vertex_format.stride; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-08 00:12:26 +10:00
										 |  |  |   for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; a_idx++) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     const GPUVertAttr *a = &imm.vertex_format.attrs[a_idx]; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     const uint offset = imm.buffer_offset + a->offset; | 
					
						
							|  |  |  |     const GLvoid *pointer = (const GLubyte *)0 + offset; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     const uint loc = read_attr_location(&imm.attr_binding, a_idx); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     switch (a->fetch_mode) { | 
					
						
							|  |  |  |       case GPU_FETCH_FLOAT: | 
					
						
							|  |  |  |       case GPU_FETCH_INT_TO_FLOAT: | 
					
						
							|  |  |  |         glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case GPU_FETCH_INT_TO_FLOAT_UNIT: | 
					
						
							|  |  |  |         glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_TRUE, stride, pointer); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case GPU_FETCH_INT: | 
					
						
							|  |  |  |         glVertexAttribIPointer(loc, a->comp_len, a->gl_comp_type, stride, pointer); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (GPU_matrix_dirty_get()) { | 
					
						
							|  |  |  |     GPU_matrix_bind(imm.shader_interface); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void immEnd(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   uint buffer_bytes_used; | 
					
						
							|  |  |  |   if (imm.strict_vertex_len) { | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     assert(imm.vertex_idx == imm.vertex_len); /* with all vertices defined */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     buffer_bytes_used = imm.buffer_bytes_mapped; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     assert(imm.vertex_idx <= imm.vertex_len); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (imm.vertex_idx == imm.vertex_len) { | 
					
						
							|  |  |  |       buffer_bytes_used = imm.buffer_bytes_mapped; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       assert(imm.vertex_idx == 0 || | 
					
						
							|  |  |  |              vertex_count_makes_sense_for_primitive(imm.vertex_idx, imm.prim_type)); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |       imm.vertex_len = imm.vertex_idx; | 
					
						
							|  |  |  |       buffer_bytes_used = vertex_buffer_size(&imm.vertex_format, imm.vertex_len); | 
					
						
							|  |  |  |       /* unused buffer bytes are available to the next immBegin */ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /* tell OpenGL what range was modified so it doesn't copy the whole mapped range */ | 
					
						
							|  |  |  |     glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, buffer_bytes_used); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (imm.batch) { | 
					
						
							|  |  |  |     if (buffer_bytes_used != imm.buffer_bytes_mapped) { | 
					
						
							|  |  |  |       GPU_vertbuf_data_resize(imm.batch->verts[0], imm.vertex_len); | 
					
						
							|  |  |  |       /* TODO: resize only if vertex count is much smaller */ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     GPU_batch_program_set(imm.batch, imm.bound_program, imm.shader_interface); | 
					
						
							|  |  |  |     imm.batch->phase = GPU_BATCH_READY_TO_DRAW; | 
					
						
							|  |  |  |     imm.batch = NULL; /* don't free, batch belongs to caller */ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     glUnmapBuffer(GL_ARRAY_BUFFER); | 
					
						
							| 
									
										
										
										
											2019-06-06 17:21:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (imm.vertex_len > 0) { | 
					
						
							|  |  |  |       immDrawSetup(); | 
					
						
							| 
									
										
										
										
											2019-06-06 17:21:12 +02:00
										 |  |  | #ifdef __APPLE__
 | 
					
						
							|  |  |  |       glDisable(GL_PRIMITIVE_RESTART); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       glDrawArrays(convert_prim_type_to_gl(imm.prim_type), 0, imm.vertex_len); | 
					
						
							| 
									
										
										
										
											2019-06-06 17:21:12 +02:00
										 |  |  | #ifdef __APPLE__
 | 
					
						
							|  |  |  |       glEnable(GL_PRIMITIVE_RESTART); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     /* These lines are causing crash on startup on some old GPU + drivers.
 | 
					
						
							|  |  |  |      * They are not required so just comment them. (T55722) */ | 
					
						
							|  |  |  |     // glBindBuffer(GL_ARRAY_BUFFER, 0);
 | 
					
						
							|  |  |  |     // glBindVertexArray(0);
 | 
					
						
							|  |  |  |     /* prep for next immBegin */ | 
					
						
							|  |  |  |     imm.buffer_offset += buffer_bytes_used; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* prep for next immBegin */ | 
					
						
							|  |  |  |   imm.prim_type = GPU_PRIM_NONE; | 
					
						
							|  |  |  |   imm.strict_vertex_len = true; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | static void setAttrValueBit(uint attr_id) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   uint16_t mask = 1 << attr_id; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(imm.unassigned_attr_bits & mask); /* not already set */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.unassigned_attr_bits &= ~mask; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --- generic attribute functions --- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttr1f(uint attr_id, float x) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id]; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(attr_id < imm.vertex_format.attr_len); | 
					
						
							|  |  |  |   assert(attr->comp_type == GPU_COMP_F32); | 
					
						
							|  |  |  |   assert(attr->comp_len == 1); | 
					
						
							|  |  |  |   assert(imm.vertex_idx < imm.vertex_len); | 
					
						
							|  |  |  |   assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   setAttrValueBit(attr_id); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float *data = (float *)(imm.vertex_data + attr->offset); | 
					
						
							|  |  |  |   /*  printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   data[0] = x; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttr2f(uint attr_id, float x, float y) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id]; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(attr_id < imm.vertex_format.attr_len); | 
					
						
							|  |  |  |   assert(attr->comp_type == GPU_COMP_F32); | 
					
						
							|  |  |  |   assert(attr->comp_len == 2); | 
					
						
							|  |  |  |   assert(imm.vertex_idx < imm.vertex_len); | 
					
						
							|  |  |  |   assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   setAttrValueBit(attr_id); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float *data = (float *)(imm.vertex_data + attr->offset); | 
					
						
							|  |  |  |   /*  printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   data[0] = x; | 
					
						
							|  |  |  |   data[1] = y; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttr3f(uint attr_id, float x, float y, float z) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id]; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(attr_id < imm.vertex_format.attr_len); | 
					
						
							|  |  |  |   assert(attr->comp_type == GPU_COMP_F32); | 
					
						
							|  |  |  |   assert(attr->comp_len == 3); | 
					
						
							|  |  |  |   assert(imm.vertex_idx < imm.vertex_len); | 
					
						
							|  |  |  |   assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   setAttrValueBit(attr_id); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float *data = (float *)(imm.vertex_data + attr->offset); | 
					
						
							|  |  |  |   /*  printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   data[0] = x; | 
					
						
							|  |  |  |   data[1] = y; | 
					
						
							|  |  |  |   data[2] = z; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttr4f(uint attr_id, float x, float y, float z, float w) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id]; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(attr_id < imm.vertex_format.attr_len); | 
					
						
							|  |  |  |   assert(attr->comp_type == GPU_COMP_F32); | 
					
						
							|  |  |  |   assert(attr->comp_len == 4); | 
					
						
							|  |  |  |   assert(imm.vertex_idx < imm.vertex_len); | 
					
						
							|  |  |  |   assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   setAttrValueBit(attr_id); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float *data = (float *)(imm.vertex_data + attr->offset); | 
					
						
							|  |  |  |   /*  printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   data[0] = x; | 
					
						
							|  |  |  |   data[1] = y; | 
					
						
							|  |  |  |   data[2] = z; | 
					
						
							|  |  |  |   data[3] = w; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttr1u(uint attr_id, uint x) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id]; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(attr_id < imm.vertex_format.attr_len); | 
					
						
							|  |  |  |   assert(attr->comp_type == GPU_COMP_U32); | 
					
						
							|  |  |  |   assert(attr->comp_len == 1); | 
					
						
							|  |  |  |   assert(imm.vertex_idx < imm.vertex_len); | 
					
						
							|  |  |  |   assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   setAttrValueBit(attr_id); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   uint *data = (uint *)(imm.vertex_data + attr->offset); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   data[0] = x; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttr2i(uint attr_id, int x, int y) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id]; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(attr_id < imm.vertex_format.attr_len); | 
					
						
							|  |  |  |   assert(attr->comp_type == GPU_COMP_I32); | 
					
						
							|  |  |  |   assert(attr->comp_len == 2); | 
					
						
							|  |  |  |   assert(imm.vertex_idx < imm.vertex_len); | 
					
						
							|  |  |  |   assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   setAttrValueBit(attr_id); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int *data = (int *)(imm.vertex_data + attr->offset); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   data[0] = x; | 
					
						
							|  |  |  |   data[1] = y; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttr2s(uint attr_id, short x, short y) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id]; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(attr_id < imm.vertex_format.attr_len); | 
					
						
							|  |  |  |   assert(attr->comp_type == GPU_COMP_I16); | 
					
						
							|  |  |  |   assert(attr->comp_len == 2); | 
					
						
							|  |  |  |   assert(imm.vertex_idx < imm.vertex_len); | 
					
						
							|  |  |  |   assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   setAttrValueBit(attr_id); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   short *data = (short *)(imm.vertex_data + attr->offset); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   data[0] = x; | 
					
						
							|  |  |  |   data[1] = y; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttr2fv(uint attr_id, const float data[2]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immAttr2f(attr_id, data[0], data[1]); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttr3fv(uint attr_id, const float data[3]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immAttr3f(attr_id, data[0], data[1], data[2]); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttr4fv(uint attr_id, const float data[4]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immAttr4f(attr_id, data[0], data[1], data[2], data[3]); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttr3ub(uint attr_id, uchar r, uchar g, uchar b) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id]; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(attr_id < imm.vertex_format.attr_len); | 
					
						
							|  |  |  |   assert(attr->comp_type == GPU_COMP_U8); | 
					
						
							|  |  |  |   assert(attr->comp_len == 3); | 
					
						
							|  |  |  |   assert(imm.vertex_idx < imm.vertex_len); | 
					
						
							|  |  |  |   assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   setAttrValueBit(attr_id); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GLubyte *data = imm.vertex_data + attr->offset; | 
					
						
							|  |  |  |   /*  printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data); */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   data[0] = r; | 
					
						
							|  |  |  |   data[1] = g; | 
					
						
							|  |  |  |   data[2] = b; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttr4ub(uint attr_id, uchar r, uchar g, uchar b, uchar a) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GPUVertAttr *attr = &imm.vertex_format.attrs[attr_id]; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(attr_id < imm.vertex_format.attr_len); | 
					
						
							|  |  |  |   assert(attr->comp_type == GPU_COMP_U8); | 
					
						
							|  |  |  |   assert(attr->comp_len == 4); | 
					
						
							|  |  |  |   assert(imm.vertex_idx < imm.vertex_len); | 
					
						
							|  |  |  |   assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   setAttrValueBit(attr_id); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GLubyte *data = imm.vertex_data + attr->offset; | 
					
						
							|  |  |  |   /*  printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data); */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   data[0] = r; | 
					
						
							|  |  |  |   data[1] = g; | 
					
						
							|  |  |  |   data[2] = b; | 
					
						
							|  |  |  |   data[3] = a; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttr3ubv(uint attr_id, const uchar data[3]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immAttr3ub(attr_id, data[0], data[1], data[2]); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttr4ubv(uint attr_id, const uchar data[4]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immAttr4ub(attr_id, data[0], data[1], data[2], data[3]); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immAttrSkip(uint attr_id) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(attr_id < imm.vertex_format.attr_len); | 
					
						
							|  |  |  |   assert(imm.vertex_idx < imm.vertex_len); | 
					
						
							|  |  |  |   assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   setAttrValueBit(attr_id); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void immEndVertex(void) /* and move on to the next vertex */ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ | 
					
						
							|  |  |  |   assert(imm.vertex_idx < imm.vertex_len); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* Have all attributes been assigned values?
 | 
					
						
							|  |  |  |    * If not, copy value from previous vertex. */ | 
					
						
							|  |  |  |   if (imm.unassigned_attr_bits) { | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     assert(imm.vertex_idx > 0); /* first vertex must have all attributes specified */ | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-09-08 00:12:26 +10:00
										 |  |  |     for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; a_idx++) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       if ((imm.unassigned_attr_bits >> a_idx) & 1) { | 
					
						
							|  |  |  |         const GPUVertAttr *a = &imm.vertex_format.attrs[a_idx]; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-22 01:45:43 +10:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  |         printf("copying %s from vertex %u to %u\n", a->name, imm.vertex_idx - 1, imm.vertex_idx); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         GLubyte *data = imm.vertex_data + a->offset; | 
					
						
							|  |  |  |         memcpy(data, data - imm.vertex_format.stride, a->sz); | 
					
						
							|  |  |  |         /* TODO: consolidate copy of adjacent attributes */ | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   imm.vertex_idx++; | 
					
						
							|  |  |  |   imm.vertex_data += imm.vertex_format.stride; | 
					
						
							|  |  |  |   imm.unassigned_attr_bits = imm.attr_binding.enabled_bits; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immVertex2f(uint attr_id, float x, float y) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immAttr2f(attr_id, x, y); | 
					
						
							|  |  |  |   immEndVertex(); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immVertex3f(uint attr_id, float x, float y, float z) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immAttr3f(attr_id, x, y, z); | 
					
						
							|  |  |  |   immEndVertex(); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immVertex4f(uint attr_id, float x, float y, float z, float w) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immAttr4f(attr_id, x, y, z, w); | 
					
						
							|  |  |  |   immEndVertex(); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immVertex2i(uint attr_id, int x, int y) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immAttr2i(attr_id, x, y); | 
					
						
							|  |  |  |   immEndVertex(); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immVertex2s(uint attr_id, short x, short y) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immAttr2s(attr_id, x, y); | 
					
						
							|  |  |  |   immEndVertex(); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immVertex2fv(uint attr_id, const float data[2]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immAttr2f(attr_id, data[0], data[1]); | 
					
						
							|  |  |  |   immEndVertex(); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immVertex3fv(uint attr_id, const float data[3]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immAttr3f(attr_id, data[0], data[1], data[2]); | 
					
						
							|  |  |  |   immEndVertex(); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 07:46:25 +11:00
										 |  |  | void immVertex2iv(uint attr_id, const int data[2]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immAttr2i(attr_id, data[0], data[1]); | 
					
						
							|  |  |  |   immEndVertex(); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --- generic uniform functions --- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2018-07-19 16:06:37 +10:00
										 |  |  | #  if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #    define GET_UNIFORM \
 | 
					
						
							|  |  |  |       const GPUShaderInput *uniform = GPU_shaderinterface_uniform_ensure(imm.shader_interface, \ | 
					
						
							|  |  |  |                                                                          name); \ | 
					
						
							|  |  |  |       assert(uniform); | 
					
						
							| 
									
										
										
										
											2018-07-19 16:06:37 +10:00
										 |  |  | #  else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #    define GET_UNIFORM \
 | 
					
						
							|  |  |  |       const GPUShaderInput *uniform = GPU_shaderinterface_uniform_ensure(imm.shader_interface, \ | 
					
						
							|  |  |  |                                                                          name); | 
					
						
							| 
									
										
										
										
											2018-07-19 16:06:37 +10:00
										 |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | /* NOTE: It is possible to have uniform fully optimized out from the shader.
 | 
					
						
							| 
									
										
										
										
											2019-04-18 07:21:26 +02:00
										 |  |  |  *       In this case we can't assert failure or allow NULL-pointer dereference. | 
					
						
							|  |  |  |  * TODO(sergey): How can we detect existing-but-optimized-out uniform but still | 
					
						
							|  |  |  |  *               catch typos in uniform names passed to immUniform*() functions? */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  define GET_UNIFORM \
 | 
					
						
							|  |  |  |     const GPUShaderInput *uniform = GPU_shaderinterface_uniform_ensure(imm.shader_interface, \ | 
					
						
							|  |  |  |                                                                        name); \ | 
					
						
							|  |  |  |     if (uniform == NULL) \ | 
					
						
							|  |  |  |       return; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void immUniform1f(const char *name, float x) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GET_UNIFORM | 
					
						
							|  |  |  |   glUniform1f(uniform->location, x); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void immUniform2f(const char *name, float x, float y) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GET_UNIFORM | 
					
						
							|  |  |  |   glUniform2f(uniform->location, x, y); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void immUniform2fv(const char *name, const float data[2]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GET_UNIFORM | 
					
						
							|  |  |  |   glUniform2fv(uniform->location, 1, data); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void immUniform3f(const char *name, float x, float y, float z) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GET_UNIFORM | 
					
						
							|  |  |  |   glUniform3f(uniform->location, x, y, z); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void immUniform3fv(const char *name, const float data[3]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GET_UNIFORM | 
					
						
							|  |  |  |   glUniform3fv(uniform->location, 1, data); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* can increase this limit or move to another file */ | 
					
						
							|  |  |  | #define MAX_UNIFORM_NAME_LEN 60
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void immUniformArray3fv(const char *bare_name, const float *data, int count) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* look up "name[0]" when given "name" */ | 
					
						
							|  |  |  |   const size_t len = strlen(bare_name); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(len <= MAX_UNIFORM_NAME_LEN); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   char name[MAX_UNIFORM_NAME_LEN]; | 
					
						
							|  |  |  |   strcpy(name, bare_name); | 
					
						
							|  |  |  |   name[len + 0] = '['; | 
					
						
							|  |  |  |   name[len + 1] = '0'; | 
					
						
							|  |  |  |   name[len + 2] = ']'; | 
					
						
							|  |  |  |   name[len + 3] = '\0'; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GET_UNIFORM | 
					
						
							|  |  |  |   glUniform3fv(uniform->location, count, data); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void immUniform4f(const char *name, float x, float y, float z, float w) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GET_UNIFORM | 
					
						
							|  |  |  |   glUniform4f(uniform->location, x, y, z, w); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void immUniform4fv(const char *name, const float data[4]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GET_UNIFORM | 
					
						
							|  |  |  |   glUniform4fv(uniform->location, 1, data); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void immUniformArray4fv(const char *bare_name, const float *data, int count) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* look up "name[0]" when given "name" */ | 
					
						
							|  |  |  |   const size_t len = strlen(bare_name); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(len <= MAX_UNIFORM_NAME_LEN); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   char name[MAX_UNIFORM_NAME_LEN]; | 
					
						
							|  |  |  |   strcpy(name, bare_name); | 
					
						
							|  |  |  |   name[len + 0] = '['; | 
					
						
							|  |  |  |   name[len + 1] = '0'; | 
					
						
							|  |  |  |   name[len + 2] = ']'; | 
					
						
							|  |  |  |   name[len + 3] = '\0'; | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GET_UNIFORM | 
					
						
							|  |  |  |   glUniform4fv(uniform->location, count, data); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void immUniformMatrix4fv(const char *name, const float data[4][4]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GET_UNIFORM | 
					
						
							|  |  |  |   glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (float *)data); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void immUniform1i(const char *name, int x) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GET_UNIFORM | 
					
						
							|  |  |  |   glUniform1i(uniform->location, x); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 23:09:31 +10:00
										 |  |  | void immUniform4iv(const char *name, const int data[4]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   GET_UNIFORM | 
					
						
							|  |  |  |   glUniform4iv(uniform->location, 1, data); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --- convenience functions for setting "uniform vec4 color" --- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void immUniformColor4f(float r, float g, float b, float a) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const GPUShaderInput *uniform = GPU_shaderinterface_uniform_builtin(imm.shader_interface, | 
					
						
							|  |  |  |                                                                       GPU_UNIFORM_COLOR); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #if TRUST_NO_ONE
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   assert(uniform != NULL); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   glUniform4f(uniform->location, r, g, b, a); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void immUniformColor4fv(const float rgba[4]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immUniformColor4f(rgba[0], rgba[1], rgba[2], rgba[3]); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void immUniformColor3f(float r, float g, float b) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immUniformColor4f(r, g, b, 1.0f); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void immUniformColor3fv(const float rgb[3]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immUniformColor4f(rgb[0], rgb[1], rgb[2], 1.0f); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void immUniformColor3fvAlpha(const float rgb[3], float a) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immUniformColor4f(rgb[0], rgb[1], rgb[2], a); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* TODO: v-- treat as sRGB? --v */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 12:18:35 +10:00
										 |  |  | void immUniformColor3ub(uchar r, uchar g, uchar b) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const float scale = 1.0f / 255.0f; | 
					
						
							|  |  |  |   immUniformColor4f(scale * r, scale * g, scale * b, 1.0f); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 12:18:35 +10:00
										 |  |  | void immUniformColor4ub(uchar r, uchar g, uchar b, uchar a) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const float scale = 1.0f / 255.0f; | 
					
						
							|  |  |  |   immUniformColor4f(scale * r, scale * g, scale * b, scale * a); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 12:18:35 +10:00
										 |  |  | void immUniformColor3ubv(const uchar rgb[3]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immUniformColor3ub(rgb[0], rgb[1], rgb[2]); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 12:18:35 +10:00
										 |  |  | void immUniformColor3ubvAlpha(const uchar rgb[3], uchar alpha) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immUniformColor4ub(rgb[0], rgb[1], rgb[2], alpha); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 12:18:35 +10:00
										 |  |  | void immUniformColor4ubv(const uchar rgba[4]) | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   immUniformColor4ub(rgba[0], rgba[1], rgba[2], rgba[3]); | 
					
						
							| 
									
										
										
										
											2018-07-17 21:11:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-11 14:52:57 +11:00
										 |  |  | #ifndef GPU_STANDALONE
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-16 17:04:17 -04:00
										 |  |  | void immUniformThemeColor(int color_id) | 
					
						
							| 
									
										
										
										
											2016-10-12 23:01:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float color[4]; | 
					
						
							|  |  |  |   UI_GetThemeColor4fv(color_id, color); | 
					
						
							|  |  |  |   immUniformColor4fv(color); | 
					
						
							| 
									
										
										
										
											2016-10-12 23:01:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-05 10:59:46 +02:00
										 |  |  | void immUniformThemeColor3(int color_id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float color[3]; | 
					
						
							|  |  |  |   UI_GetThemeColor3fv(color_id, color); | 
					
						
							|  |  |  |   immUniformColor3fv(color); | 
					
						
							| 
									
										
										
										
											2017-04-05 10:59:46 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-16 17:04:17 -04:00
										 |  |  | void immUniformThemeColorShade(int color_id, int offset) | 
					
						
							| 
									
										
										
										
											2016-10-12 23:01:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float color[4]; | 
					
						
							|  |  |  |   UI_GetThemeColorShade4fv(color_id, offset, color); | 
					
						
							|  |  |  |   immUniformColor4fv(color); | 
					
						
							| 
									
										
										
										
											2016-10-13 20:06:44 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-16 17:04:17 -04:00
										 |  |  | void immUniformThemeColorShadeAlpha(int color_id, int color_offset, int alpha_offset) | 
					
						
							| 
									
										
										
										
											2016-10-13 20:06:44 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float color[4]; | 
					
						
							|  |  |  |   UI_GetThemeColorShadeAlpha4fv(color_id, color_offset, alpha_offset, color); | 
					
						
							|  |  |  |   immUniformColor4fv(color); | 
					
						
							| 
									
										
										
										
											2016-10-16 17:04:17 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void immUniformThemeColorBlendShade(int color_id1, int color_id2, float fac, int offset) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float color[4]; | 
					
						
							|  |  |  |   UI_GetThemeColorBlendShade4fv(color_id1, color_id2, fac, offset, color); | 
					
						
							|  |  |  |   immUniformColor4fv(color); | 
					
						
							| 
									
										
										
										
											2016-10-13 20:06:44 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-12-13 16:45:59 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | void immUniformThemeColorBlend(int color_id1, int color_id2, float fac) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   uint8_t color[3]; | 
					
						
							|  |  |  |   UI_GetThemeColorBlend3ubv(color_id1, color_id2, fac, color); | 
					
						
							|  |  |  |   immUniformColor3ubv(color); | 
					
						
							| 
									
										
										
										
											2016-12-13 16:45:59 -05:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-01-15 19:26:35 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | void immThemeColorShadeAlpha(int colorid, int coloffset, int alphaoffset) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   uchar col[4]; | 
					
						
							|  |  |  |   UI_GetThemeColorShadeAlpha4ubv(colorid, coloffset, alphaoffset, col); | 
					
						
							|  |  |  |   immUniformColor4ub(col[0], col[1], col[2], col[3]); | 
					
						
							| 
									
										
										
										
											2017-01-15 19:26:35 -05:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-03-11 14:52:57 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif /* GPU_STANDALONE */
 |