1 /*
2  * This software is licensed under the terms of the MIT License.
3  * See COPYING for further information.
4  * ---
5  * Copyright (c) 2011-2019, Lukas Weber <laochailan@web.de>.
6  * Copyright (c) 2012-2019, Andrei Alexeyev <akari@taisei-project.org>.
7  */
8 
9 #include "taisei.h"
10 
11 #include "../api.h"
12 #include "resource/shader_object.h"
13 #include "../common/backend.h"
14 
15 static char placeholder;
16 static Color dummycolor;
17 
null_create_window(const char * title,int x,int y,int w,int h,uint32_t flags)18 static SDL_Window* null_create_window(const char *title, int x, int y, int w, int h, uint32_t flags) {
19 	return SDL_CreateWindow(title, x, y, w, h, flags);
20 }
21 
null_init(void)22 static void null_init(void) { }
null_post_init(void)23 static void null_post_init(void) { }
null_shutdown(void)24 static void null_shutdown(void) { }
25 
null_features(void)26 static r_feature_bits_t null_features(void) { return ~0; }
27 
null_capabilities(r_capability_bits_t capbits)28 static void null_capabilities(r_capability_bits_t capbits) { }
null_capabilities_current(void)29 static r_capability_bits_t null_capabilities_current(void) { return (r_capability_bits_t)-1; }
30 
null_color4(float r,float g,float b,float a)31 static void null_color4(float r, float g, float b, float a) { }
null_color_current(void)32 static const Color* null_color_current(void) { return &dummycolor; }
33 
null_blend(BlendMode mode)34 static void null_blend(BlendMode mode) { }
null_blend_current(void)35 static BlendMode null_blend_current(void) { return BLEND_NONE; }
36 
null_cull(CullFaceMode mode)37 static void null_cull(CullFaceMode mode) { }
null_cull_current(void)38 static CullFaceMode null_cull_current(void) { return CULL_BACK; }
39 
null_depth_func(DepthTestFunc func)40 static void null_depth_func(DepthTestFunc func) { }
null_depth_func_current(void)41 static DepthTestFunc null_depth_func_current(void) { return DEPTH_LESS; }
42 
null_shader_language_supported(const ShaderLangInfo * lang,ShaderLangInfo * out_alternative)43 static bool null_shader_language_supported(const ShaderLangInfo *lang, ShaderLangInfo *out_alternative) { return true; }
44 
null_shader_object_compile(ShaderSource * source)45 static ShaderObject* null_shader_object_compile(ShaderSource *source) { return (void*)&placeholder; }
null_shader_object_destroy(ShaderObject * shobj)46 static void null_shader_object_destroy(ShaderObject *shobj) { }
null_shader_object_set_debug_label(ShaderObject * shobj,const char * label)47 static void null_shader_object_set_debug_label(ShaderObject *shobj, const char *label) { }
null_shader_object_get_debug_label(ShaderObject * shobj)48 static const char* null_shader_object_get_debug_label(ShaderObject *shobj) { return "Null shader object"; }
49 
null_shader_program_link(uint num_objects,ShaderObject * shobjs[num_objects])50 static ShaderProgram* null_shader_program_link(uint num_objects, ShaderObject *shobjs[num_objects]) { return (void*)&placeholder; }
null_shader_program_destroy(ShaderProgram * prog)51 static void null_shader_program_destroy(ShaderProgram *prog) { }
null_shader_program_set_debug_label(ShaderProgram * prog,const char * label)52 static void null_shader_program_set_debug_label(ShaderProgram *prog, const char *label) { }
null_shader_program_get_debug_label(ShaderProgram * prog)53 static const char* null_shader_program_get_debug_label(ShaderProgram *prog) { return "Null shader program"; }
54 
null_shader(ShaderProgram * prog)55 static void null_shader(ShaderProgram *prog) { }
null_shader_current(void)56 static ShaderProgram* null_shader_current(void) { return (void*)&placeholder; }
57 
null_shader_uniform(ShaderProgram * prog,const char * uniform_name,hash_t uniform_name_hash)58 static Uniform* null_shader_uniform(ShaderProgram *prog, const char *uniform_name, hash_t uniform_name_hash) {
59 	return NULL;
60 }
61 
null_uniform(Uniform * uniform,uint offset,uint count,const void * data)62 static void null_uniform(Uniform *uniform, uint offset, uint count, const void *data) { }
63 
null_uniform_type(Uniform * uniform)64 static UniformType null_uniform_type(Uniform *uniform) { return UNIFORM_FLOAT; }
65 
null_draw(VertexArray * varr,Primitive prim,uint first,uint count,uint instances,uint base_instance)66 static void null_draw(VertexArray *varr, Primitive prim, uint first, uint count, uint instances, uint base_instance) { }
67 
null_texture_create(const TextureParams * params)68 static Texture* null_texture_create(const TextureParams *params) {
69 	return (void*)&placeholder;
70 }
71 
null_texture_get_size(Texture * tex,uint mipmap,uint * width,uint * height)72 static void null_texture_get_size(Texture *tex, uint mipmap, uint *width, uint *height) {
73 	if(width) *width = 1;
74 	if(height) *height = 1;
75 }
76 
null_texture_get_params(Texture * tex,TextureParams * params)77 static void null_texture_get_params(Texture *tex, TextureParams *params) {
78 	memset(params, 0, sizeof(*params));
79 	params->width = 1;
80 	params->height = 1;
81 	params->type = TEX_TYPE_RGBA;
82 }
83 
null_texture_set_debug_label(Texture * tex,const char * label)84 static void null_texture_set_debug_label(Texture *tex, const char *label) { }
null_texture_get_debug_label(Texture * tex)85 static const char* null_texture_get_debug_label(Texture *tex) { return "null texture"; }
null_texture_set_filter(Texture * tex,TextureFilterMode fmin,TextureFilterMode fmag)86 static void null_texture_set_filter(Texture *tex, TextureFilterMode fmin, TextureFilterMode fmag) { }
null_texture_set_wrap(Texture * tex,TextureWrapMode fmin,TextureWrapMode fmag)87 static void null_texture_set_wrap(Texture *tex, TextureWrapMode fmin, TextureWrapMode fmag) { }
null_texture_fill(Texture * tex,uint mipmap,const Pixmap * image_data)88 static void null_texture_fill(Texture *tex, uint mipmap, const Pixmap *image_data) { }
null_texture_fill_region(Texture * tex,uint mipmap,uint x,uint y,const Pixmap * image_data)89 static void null_texture_fill_region(Texture *tex, uint mipmap, uint x, uint y, const Pixmap *image_data) { }
null_texture_invalidate(Texture * tex)90 static void null_texture_invalidate(Texture *tex) { }
null_texture_destroy(Texture * tex)91 static void null_texture_destroy(Texture *tex) { }
null_texture_clear(Texture * tex,const Color * color)92 static void null_texture_clear(Texture *tex, const Color *color) { }
93 
94 static FloatRect default_fb_viewport;
95 
null_framebuffer_create(void)96 static Framebuffer* null_framebuffer_create(void) { return (void*)&placeholder; }
null_framebuffer_set_debug_label(Framebuffer * fb,const char * label)97 static void null_framebuffer_set_debug_label(Framebuffer *fb, const char *label) { }
null_framebuffer_get_debug_label(Framebuffer * fb)98 static const char* null_framebuffer_get_debug_label(Framebuffer *fb) { return "null framebuffer"; }
null_framebuffer_attach(Framebuffer * framebuffer,Texture * tex,uint mipmap,FramebufferAttachment attachment)99 static void null_framebuffer_attach(Framebuffer *framebuffer, Texture *tex, uint mipmap, FramebufferAttachment attachment) { }
null_framebuffer_attachment(Framebuffer * framebuffer,FramebufferAttachment attachment)100 static Texture* null_framebuffer_attachment(Framebuffer *framebuffer, FramebufferAttachment attachment) { return (void*)&placeholder; }
null_framebuffer_attachment_mipmap(Framebuffer * framebuffer,FramebufferAttachment attachment)101 static uint null_framebuffer_attachment_mipmap(Framebuffer *framebuffer, FramebufferAttachment attachment) { return 0; }
null_framebuffer_destroy(Framebuffer * framebuffer)102 static void null_framebuffer_destroy(Framebuffer *framebuffer) { }
null_framebuffer_viewport(Framebuffer * framebuffer,FloatRect vp)103 static void null_framebuffer_viewport(Framebuffer *framebuffer, FloatRect vp) { }
null_framebuffer_viewport_current(Framebuffer * framebuffer,FloatRect * vp)104 static void null_framebuffer_viewport_current(Framebuffer *framebuffer, FloatRect *vp) { *vp = default_fb_viewport; }
null_framebuffer(Framebuffer * framebuffer)105 static void null_framebuffer(Framebuffer *framebuffer) { }
null_framebuffer_current(void)106 static Framebuffer* null_framebuffer_current(void) { return (void*)&placeholder; }
null_framebuffer_clear(Framebuffer * framebuffer,ClearBufferFlags flags,const Color * colorval,float depthval)107 static void null_framebuffer_clear(Framebuffer *framebuffer, ClearBufferFlags flags, const Color *colorval, float depthval) { }
null_framebuffer_get_size(Framebuffer * framebuffer)108 static IntExtent null_framebuffer_get_size(Framebuffer *framebuffer) { return (IntExtent) { 64, 64 }; }
109 
null_vertex_buffer_stream_seek(SDL_RWops * rw,int64_t offset,int whence)110 static int64_t null_vertex_buffer_stream_seek(SDL_RWops *rw, int64_t offset, int whence) { return 0; }
null_vertex_buffer_stream_size(SDL_RWops * rw)111 static int64_t null_vertex_buffer_stream_size(SDL_RWops *rw) { return (1 << 16); }
null_vertex_buffer_stream_write(SDL_RWops * rw,const void * data,size_t size,size_t num)112 static size_t null_vertex_buffer_stream_write(SDL_RWops *rw, const void *data, size_t size, size_t num) { return num; }
null_vertex_buffer_stream_close(SDL_RWops * rw)113 static int null_vertex_buffer_stream_close(SDL_RWops *rw) { return 0; }
114 
null_vertex_buffer_stream_read(SDL_RWops * rw,void * data,size_t size,size_t num)115 static size_t null_vertex_buffer_stream_read(SDL_RWops *rw, void *data, size_t size, size_t num) {
116 	SDL_SetError("Stream is write-only");
117 	return 0;
118 }
119 
120 static SDL_RWops dummy_stream = {
121 	.seek = null_vertex_buffer_stream_seek,
122 	.size = null_vertex_buffer_stream_size,
123 	.write = null_vertex_buffer_stream_write,
124 	.read = null_vertex_buffer_stream_read,
125 	.close = null_vertex_buffer_stream_close,
126 };
127 
null_vertex_buffer_get_stream(VertexBuffer * vbuf)128 static SDL_RWops* null_vertex_buffer_get_stream(VertexBuffer *vbuf) {
129 	return &dummy_stream;
130 }
131 
null_vertex_buffer_create(size_t capacity,void * data)132 static VertexBuffer* null_vertex_buffer_create(size_t capacity, void *data) { return (void*)&placeholder; }
null_vertex_buffer_set_debug_label(VertexBuffer * vbuf,const char * label)133 static void null_vertex_buffer_set_debug_label(VertexBuffer *vbuf, const char *label) { }
null_vertex_buffer_get_debug_label(VertexBuffer * vbuf)134 static const char* null_vertex_buffer_get_debug_label(VertexBuffer *vbuf) { return "null vertex buffer"; }
null_vertex_buffer_destroy(VertexBuffer * vbuf)135 static void null_vertex_buffer_destroy(VertexBuffer *vbuf) { }
null_vertex_buffer_invalidate(VertexBuffer * vbuf)136 static void null_vertex_buffer_invalidate(VertexBuffer *vbuf) { }
137 
null_index_buffer_create(size_t max_elements)138 static IndexBuffer* null_index_buffer_create(size_t max_elements) { return (void*)&placeholder; }
null_index_buffer_get_capacity(IndexBuffer * ibuf)139 static size_t null_index_buffer_get_capacity(IndexBuffer *ibuf) { return UINT32_MAX; }
null_index_buffer_get_debug_label(IndexBuffer * ibuf)140 static const char* null_index_buffer_get_debug_label(IndexBuffer *ibuf) { return "null index buffer"; }
null_index_buffer_set_debug_label(IndexBuffer * ibuf,const char * label)141 static void null_index_buffer_set_debug_label(IndexBuffer *ibuf, const char *label) { }
null_index_buffer_set_offset(IndexBuffer * ibuf,size_t offset)142 static void null_index_buffer_set_offset(IndexBuffer *ibuf, size_t offset) { }
null_index_buffer_get_offset(IndexBuffer * ibuf)143 static size_t null_index_buffer_get_offset(IndexBuffer *ibuf) { return 0; }
null_index_buffer_add_indices(IndexBuffer * ibuf,uint index_ofs,size_t num_elements,uint indices[num_elements])144 static void null_index_buffer_add_indices(IndexBuffer *ibuf, uint index_ofs, size_t num_elements, uint indices[num_elements]) { }
null_index_buffer_destroy(IndexBuffer * ibuf)145 static void null_index_buffer_destroy(IndexBuffer *ibuf) { }
146 
null_vertex_array_create(void)147 static VertexArray* null_vertex_array_create(void) { return (void*)&placeholder; }
null_vertex_array_set_debug_label(VertexArray * varr,const char * label)148 static void null_vertex_array_set_debug_label(VertexArray *varr, const char *label) { }
null_vertex_array_get_debug_label(VertexArray * varr)149 static const char* null_vertex_array_get_debug_label(VertexArray *varr) { return "null vertex array"; }
null_vertex_array_destroy(VertexArray * varr)150 static void null_vertex_array_destroy(VertexArray *varr) { }
null_vertex_array_attach_vertex_buffer(VertexArray * varr,VertexBuffer * vbuf,uint attachment)151 static void null_vertex_array_attach_vertex_buffer(VertexArray *varr, VertexBuffer *vbuf, uint attachment) { }
null_vertex_array_attach_index_buffer(VertexArray * varr,IndexBuffer * vbuf)152 static void null_vertex_array_attach_index_buffer(VertexArray *varr, IndexBuffer *vbuf) { }
null_vertex_array_get_vertex_attachment(VertexArray * varr,uint attachment)153 static VertexBuffer* null_vertex_array_get_vertex_attachment(VertexArray *varr, uint attachment) { return (void*)&placeholder; }
null_vertex_array_get_index_attachment(VertexArray * varr)154 static IndexBuffer* null_vertex_array_get_index_attachment(VertexArray *varr) { return (void*)&placeholder; }
null_vertex_array_layout(VertexArray * varr,uint nattribs,VertexAttribFormat attribs[nattribs])155 static void null_vertex_array_layout(VertexArray *varr, uint nattribs, VertexAttribFormat attribs[nattribs]) { }
156 
null_vsync(VsyncMode mode)157 static void null_vsync(VsyncMode mode) { }
null_vsync_current(void)158 static VsyncMode null_vsync_current(void) { return VSYNC_NONE; }
159 
null_swap(SDL_Window * window)160 static void null_swap(SDL_Window *window) { }
161 
null_screenshot(Pixmap * dest)162 static bool null_screenshot(Pixmap *dest) { return false; }
163 
164 RendererBackend _r_backend_null = {
165 	.name = "null",
166 	.funcs = {
167 		.init = null_init,
168 		.post_init = null_post_init,
169 		.shutdown = null_shutdown,
170 		.create_window = null_create_window,
171 		.features = null_features,
172 		.capabilities = null_capabilities,
173 		.capabilities_current = null_capabilities_current,
174 		.draw = null_draw,
175 		.draw_indexed = null_draw,
176 		.color4 = null_color4,
177 		.color_current = null_color_current,
178 		.blend = null_blend,
179 		.blend_current = null_blend_current,
180 		.cull = null_cull,
181 		.cull_current = null_cull_current,
182 		.depth_func = null_depth_func,
183 		.depth_func_current = null_depth_func_current,
184 		.shader_language_supported = null_shader_language_supported,
185 		.shader_object_compile = null_shader_object_compile,
186 		.shader_object_destroy = null_shader_object_destroy,
187 		.shader_object_set_debug_label = null_shader_object_set_debug_label,
188 		.shader_object_get_debug_label = null_shader_object_get_debug_label,
189 		.shader_program_link = null_shader_program_link,
190 		.shader_program_destroy = null_shader_program_destroy,
191 		.shader_program_set_debug_label = null_shader_program_set_debug_label,
192 		.shader_program_get_debug_label = null_shader_program_get_debug_label,
193 		.shader = null_shader,
194 		.shader_current = null_shader_current,
195 		.shader_uniform = null_shader_uniform,
196 		.uniform = null_uniform,
197 		.uniform_type = null_uniform_type,
198 		.texture_create = null_texture_create,
199 		.texture_get_params = null_texture_get_params,
200 		.texture_get_size = null_texture_get_size,
201 		.texture_get_debug_label = null_texture_get_debug_label,
202 		.texture_set_debug_label = null_texture_set_debug_label,
203 		.texture_set_filter = null_texture_set_filter,
204 		.texture_set_wrap = null_texture_set_wrap,
205 		.texture_destroy = null_texture_destroy,
206 		.texture_invalidate = null_texture_invalidate,
207 		.texture_fill = null_texture_fill,
208 		.texture_fill_region = null_texture_fill_region,
209 		.texture_clear = null_texture_clear,
210 		.framebuffer_create = null_framebuffer_create,
211 		.framebuffer_get_debug_label = null_framebuffer_get_debug_label,
212 		.framebuffer_set_debug_label = null_framebuffer_set_debug_label,
213 		.framebuffer_destroy = null_framebuffer_destroy,
214 		.framebuffer_attach = null_framebuffer_attach,
215 		.framebuffer_get_attachment = null_framebuffer_attachment,
216 		.framebuffer_get_attachment_mipmap = null_framebuffer_attachment_mipmap,
217 		.framebuffer_viewport = null_framebuffer_viewport,
218 		.framebuffer_viewport_current = null_framebuffer_viewport_current,
219 		.framebuffer = null_framebuffer,
220 		.framebuffer_current = null_framebuffer_current,
221 		.framebuffer_clear = null_framebuffer_clear,
222 		.framebuffer_get_size = null_framebuffer_get_size,
223 		.vertex_buffer_create = null_vertex_buffer_create,
224 		.vertex_buffer_get_debug_label = null_vertex_buffer_get_debug_label,
225 		.vertex_buffer_set_debug_label = null_vertex_buffer_set_debug_label,
226 		.vertex_buffer_destroy = null_vertex_buffer_destroy,
227 		.vertex_buffer_invalidate = null_vertex_buffer_invalidate,
228 		.vertex_buffer_get_stream = null_vertex_buffer_get_stream,
229 		.index_buffer_create = null_index_buffer_create,
230 		.index_buffer_get_capacity = null_index_buffer_get_capacity,
231 		.index_buffer_get_debug_label = null_index_buffer_get_debug_label,
232 		.index_buffer_set_debug_label = null_index_buffer_set_debug_label,
233 		.index_buffer_set_offset = null_index_buffer_set_offset,
234 		.index_buffer_get_offset = null_index_buffer_get_offset,
235 		.index_buffer_add_indices = null_index_buffer_add_indices,
236 		.index_buffer_destroy = null_index_buffer_destroy,
237 		.vertex_array_create = null_vertex_array_create,
238 		.vertex_array_get_debug_label = null_vertex_array_get_debug_label,
239 		.vertex_array_set_debug_label = null_vertex_array_set_debug_label,
240 		.vertex_array_destroy = null_vertex_array_destroy,
241 		.vertex_array_layout = null_vertex_array_layout,
242 		.vertex_array_attach_vertex_buffer = null_vertex_array_attach_vertex_buffer,
243 		.vertex_array_get_vertex_attachment = null_vertex_array_get_vertex_attachment,
244 		.vertex_array_attach_index_buffer = null_vertex_array_attach_index_buffer,
245 		.vertex_array_get_index_attachment = null_vertex_array_get_index_attachment,
246 		.vsync = null_vsync,
247 		.vsync_current = null_vsync_current,
248 		.swap = null_swap,
249 		.screenshot = null_screenshot,
250 	},
251 };
252