1 /**
2 Copyright: Copyright (c) 2013-2018 Andrey Penechko.
3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 
7 module voxelman.graphics.oglrenderer;
8 
9 import voxelman.graphics.gl;
10 import voxelman.graphics.irenderer;
11 import voxelman.graphics.shaderprogram;
12 import voxelman.graphics.texture;
13 import voxelman.math;
14 import voxelman.platform.iwindow;
15 
16 
17 class OglRenderer : IRenderer
18 {
19 private:
20 	ShaderProgram[] shaders;
21 
22 	IWindow	window;
23 
24 public:
25 	this(IWindow window)
26 	{
27 		this.window = window;
28 	}
29 
30 	override void alphaBlending(bool value)
31 	{
32 		if (value) {
33 			checkgl!glEnable(GL_BLEND);
34 			checkgl!glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
35 		}
36 		else
37 			checkgl!glDisable(GL_BLEND);
38 	}
39 
40 	override void rectClipping(bool value)
41 	{
42 		if (value) checkgl!glEnable(GL_SCISSOR_TEST);
43 		else checkgl!glDisable(GL_SCISSOR_TEST);
44 	}
45 
46 	override void depthWrite(bool value) {
47 		checkgl!glDepthMask(value);
48 	}
49 
50 	override void depthTest(bool value) {
51 		if (value)
52 			checkgl!glEnable(GL_DEPTH_TEST);
53 		else
54 			checkgl!glDisable(GL_DEPTH_TEST);
55 	}
56 
57 	override void faceCulling(bool value) {
58 		if (value)
59 			checkgl!glEnable(GL_CULL_FACE);
60 		else
61 			checkgl!glDisable(GL_CULL_FACE);
62 	}
63 
64 	override void faceCullMode(FaceCullMode mode) {
65 		checkgl!glCullFace(mode);
66 	}
67 
68 	override void wireFrameMode(bool value) {
69 		if (value)
70 			checkgl!glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
71 		else
72 			checkgl!glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
73 	}
74 
75 	override void setViewport(ivec2 pos, ivec2 size) {
76 		checkgl!glViewport(pos.x, pos.y, size.x, size.y);
77 	}
78 
79 	override void setClipRect(irect rect) {
80 		checkgl!glScissor(rect.x, window.framebufferSize.y - rect.y - rect.height,  rect.width, rect.height);
81 	}
82 
83 	override void setClearColor(ubyte r, ubyte g, ubyte b, ubyte a = 255)
84 	{
85 		checkgl!glClearColor(cast(float)r/255, cast(float)g/255, cast(float)b/255, cast(float)a/255);
86 	}
87 
88 	override SuperImage loadImage(string filename)
89 	{
90 		import dlib.image.io.io : dlib_loadImage = loadImage;
91 		import dlib.image.image : ImageRGBA8, convert, PixelFormat;
92 		SuperImage image = dlib_loadImage(filename);
93 		if (image.pixelFormat != PixelFormat.RGBA8)
94 			image = convert!ImageRGBA8(image);
95 		return image;
96 	}
97 
98 	override Texture createTexture(SuperImage image)
99 	{
100 		return new Texture(image, TextureTarget.target2d, TextureFormat.rgba);
101 	}
102 
103 	override ShaderProgram createShaderProgram(string vertexSource, string fragmentSource)
104 	{
105 		ShaderProgram newProgram = new ShaderProgram(vertexSource, fragmentSource);
106 		if (!newProgram.compile) throw new Exception(newProgram.errorLog);
107 		shaders ~= newProgram;
108 		return newProgram;
109 	}
110 
111 	override ivec2 framebufferSize() @property
112 	{
113 		return window.framebufferSize();
114 	}
115 
116 	override void flush()
117 	{
118 		window.swapBuffers;
119 	}
120 
121 	override void close()
122 	{
123 		foreach(shader; shaders)
124 		{
125 			shader.close;
126 		}
127 		shaders = null;
128 	}
129 }