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