Client Upload Part 2

RD Core / Commit #5

Commit Client Upload Part 2

Alex Alex committed 19/10/2026 00:06 main Patch
1,244 files +271,215 -0
A RD_Client/src/framework/graphics/graphics.h +74-0 View file
@@ -0,0 +1,74 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef GRAPHICS_H
24+#define GRAPHICS_H
25+
26+#include "declarations.h"
27+#include "painter.h"
28+
29+class Painter;
30+
31+// @bindsingleton g_graphics
32+class Graphics
33+{
34+public:
35+ Graphics();
36+
37+ // @dontbind
38+ void init();
39+ // @dontbind
40+ void terminate();
41+
42+ void resize(const Size& size);
43+ void checkDepthSupport();
44+
45+ int getMaxTextureSize() { return m_maxTextureSize; }
46+ const Size& getViewportSize() { return m_viewportSize; }
47+
48+ std::string getVendor() { return m_vendor; }
49+ std::string getRenderer() { return m_renderer; }
50+ std::string getVersion() { return m_version; }
51+ std::string getExtensions() { return m_extensions; }
52+
53+ bool ok() { return m_ok; }
54+ void checkForError(const std::string& function, const std::string& file, int line);
55+
56+private:
57+#ifdef WITH_DEPTH_BUFFER
58+ void checkDepthSupport();
59+#endif
60+
61+ Size m_viewportSize;
62+ std::string m_vendor;
63+ std::string m_renderer;
64+ std::string m_version;
65+ std::string m_extensions;
66+
67+ int m_maxTextureSize;
68+ int m_alphaBits;
69+ stdext::boolean<false> m_ok;
70+};
71+
72+extern Graphics g_graphics;
73+
74+#endif
A RD_Client/src/framework/graphics/hardwarebuffer.cpp +47-0 View file
@@ -0,0 +1,47 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#include "hardwarebuffer.h"
24+#include "graphics.h"
25+
26+#include <framework/core/application.h>
27+#include <framework/core/eventdispatcher.h>
28+#include <framework/core/logger.h>
29+
30+HardwareBuffer::HardwareBuffer(Type type)
31+{
32+ m_type = type;
33+ m_id = 0;
34+ glGenBuffers(1, &m_id);
35+ if(!m_id)
36+ g_logger.fatal("Unable to create hardware buffer.");
37+ g_graphics.checkForError(__FUNCTION__, __FILE__, __LINE__);
38+}
39+
40+HardwareBuffer::~HardwareBuffer()
41+{
42+ VALIDATE(!g_app.isTerminated());
43+ uint id = m_id;
44+ g_graphicsDispatcher.addEvent([id] {
45+ glDeleteBuffers(1, &id);
46+ });
47+}
A RD_Client/src/framework/graphics/hardwarebuffer.h +55-0 View file
@@ -0,0 +1,55 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+
24+#ifndef HARDWAREBUFFER_H
25+#define HARDWAREBUFFER_H
26+
27+#include "declarations.h"
28+
29+class HardwareBuffer
30+{
31+public:
32+ enum Type {
33+ VertexBuffer = GL_ARRAY_BUFFER,
34+ IndexBuffer = GL_ELEMENT_ARRAY_BUFFER
35+ };
36+
37+ enum UsagePattern {
38+ StreamDraw = GL_STREAM_DRAW,
39+ StaticDraw = GL_STATIC_DRAW,
40+ DynamicDraw = GL_DYNAMIC_DRAW
41+ };
42+
43+ HardwareBuffer(Type type);
44+ ~HardwareBuffer();
45+
46+ void bind() { glBindBuffer(m_type, m_id); }
47+ static void unbind(Type type) { glBindBuffer(type, 0); }
48+ void write(void *data, int count, UsagePattern usage) { glBufferData(m_type, count, data, usage); }
49+
50+private:
51+ Type m_type;
52+ uint m_id;
53+};
54+
55+#endif
A RD_Client/src/framework/graphics/image.cpp +306-0 View file
@@ -0,0 +1,306 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+
24+#include "image.h"
25+
26+#include <framework/core/resourcemanager.h>
27+#include <framework/core/filestream.h>
28+#include <framework/graphics/apngloader.h>
29+#include <framework/util/qrcodegen.h>
30+
31+Image::Image(const Size& size, int bpp, uint8 *pixels)
32+{
33+ m_size = size;
34+ m_bpp = bpp;
35+ m_pixels.resize(size.area() * bpp, 0);
36+ if(pixels)
37+ memcpy(&m_pixels[0], pixels, m_pixels.size());
38+}
39+
40+ImagePtr Image::load(std::string file)
41+{
42+ ImagePtr image;
43+ try {
44+ file = g_resources.guessFilePath(file, "png");
45+
46+ // load image file data
47+ image = loadPNG(file);
48+ } catch(stdext::exception& e) {
49+ g_logger.error(stdext::format("unable to load image '%s': %s", file, e.what()));
50+ }
51+ return image;
52+}
53+
54+ImagePtr Image::loadPNG(const std::string& file)
55+{
56+ std::stringstream fin;
57+ g_resources.readFileStream(file, fin);
58+ ImagePtr image;
59+ apng_data apng;
60+ if(load_apng(fin, &apng) == 0) {
61+ image = ImagePtr(new Image(Size(apng.width, apng.height), apng.bpp, apng.pdata));
62+ free_apng(&apng);
63+ }
64+ return image;
65+}
66+
67+ImagePtr Image::loadPNG(const void* data, uint32_t size)
68+{
69+ std::string temp((char*)data, size);
70+ std::stringstream fin(temp);
71+ ImagePtr image;
72+ apng_data apng;
73+ if (load_apng(fin, &apng) == 0) {
74+ image = ImagePtr(new Image(Size(apng.width, apng.height), apng.bpp, apng.pdata));
75+ free_apng(&apng);
76+ }
77+ return image;
78+}
79+
80+void Image::savePNG(const std::string& fileName)
81+{
82+ FileStreamPtr fin = g_resources.createFile(fileName);
83+ if(!fin)
84+ stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName));
85+
86+ std::stringstream data;
87+ save_png(data, m_size.width(), m_size.height(), 4, (unsigned char*)getPixelData());
88+ fin->write(data.str().c_str(), data.str().length());
89+ fin->flush();
90+ fin->close();
91+}
92+
93+void Image::blit(const Point& dest, const ImagePtr& other)
94+{
95+ VALIDATE(m_bpp == 4);
96+
97+ if (!other)
98+ return;
99+
100+ int width = other->getWidth(), height = other->getHeight();
101+ uint8* otherPixels = other->getPixelData();
102+ for (int y = 0, p = 0; y < height; ++y) {
103+ int pos = ((dest.y + y) * m_size.width() + dest.x) * 4;
104+ for (int x = 0; x < width; ++x) {
105+ if (otherPixels[p + 3] != 0) {
106+ *(uint32_t*)&m_pixels[pos] = *(uint32_t*)&otherPixels[p];
107+ }
108+ pos += 4;
109+ p += 4;
110+ }
111+ }
112+}
113+
114+void Image::paste(const ImagePtr& other)
115+{
116+ VALIDATE(m_bpp == 4);
117+
118+ if (!other)
119+ return;
120+
121+ uint8* otherPixels = other->getPixelData();
122+ for (int p = 0; p < other->getPixelCount(); ++p) {
123+ int x = p % other->getWidth();
124+ int y = p / other->getWidth();
125+ int pos = (y * m_size.width() + x) * 4;
126+
127+ m_pixels[pos + 0] = otherPixels[p * 4 + 0];
128+ m_pixels[pos + 1] = otherPixels[p * 4 + 1];
129+ m_pixels[pos + 2] = otherPixels[p * 4 + 2];
130+ m_pixels[pos + 3] = otherPixels[p * 4 + 3];
131+ }
132+}
133+
134+ImagePtr Image::upscale()
135+{
136+ VALIDATE(m_bpp == 4);
137+
138+ ImagePtr newImage(new Image(m_size * 2));
139+
140+ uint8* otherPixels = newImage->getPixelData();
141+
142+ for (int p = 0; p < getPixelCount(); ++p) {
143+ int x = p % getWidth();
144+ int y = p / getWidth();
145+ int srcPos = (y * getWidth() + x) * 4;
146+ for (int xx = 0; xx < 2; ++xx) {
147+ for (int yy = 0; yy < 2; ++yy) {
148+ int dstPos = ((y * 2 + yy) * getWidth() * 2 + x * 2 + xx) * 4;
149+ for (int i = 0; i < 4; ++i) {
150+ otherPixels[dstPos + i] = m_pixels[srcPos + i];
151+ }
152+ }
153+ }
154+ }
155+
156+ return newImage;
157+}
158+
159+bool Image::nextMipmap()
160+{
161+ VALIDATE(m_bpp == 4);
162+ VALIDATE(stdext::is_power_of_two(m_size.width()) && stdext::is_power_of_two(m_size.height()));
163+
164+ int iw = m_size.width();
165+ int ih = m_size.height();
166+ if(iw == 1 && ih == 1)
167+ return false;
168+
169+ int ow = iw > 1 ? iw/2 : 1;
170+ int oh = ih > 1 ? ih/2 : 1;
171+
172+ std::vector<uint8> pixels(ow*oh*4, 0xFF);
173+
174+ //FIXME: calculate mipmaps for 8x1, 4x1, 2x1 ...
175+ if(iw != 1 && ih != 1) {
176+ for(int x=0;x<ow;++x) {
177+ for(int y=0;y<oh;++y) {
178+ uint8 *inPixel[4];
179+ inPixel[0] = &m_pixels[((y*2)*iw + (x*2))*4];
180+ inPixel[1] = &m_pixels[((y*2)*iw + (x*2)+1)*4];
181+ inPixel[2] = &m_pixels[((y*2+1)*iw + (x*2))*4];
182+ inPixel[3] = &m_pixels[((y*2+1)*iw + (x*2)+1)*4];
183+ uint8 *outPixel = &pixels[(y*ow + x)*4];
184+
185+ int pixelsSum[4];
186+ for(int i=0;i<4;++i)
187+ pixelsSum[i] = 0;
188+
189+ int usedPixels = 0;
190+ for(int j=0;j<4;++j) {
191+ // ignore colors of complete alpha pixels
192+ if(inPixel[j][3] < 16)
193+ continue;
194+
195+ for(int i=0;i<4;++i)
196+ pixelsSum[i] += inPixel[j][i];
197+
198+ usedPixels++;
199+ }
200+
201+ // try to guess the alpha pixel more accurately
202+ for(int i=0;i<4;++i) {
203+ if(usedPixels > 0)
204+ outPixel[i] = pixelsSum[i] / usedPixels;
205+ else
206+ outPixel[i] = 0;
207+ }
208+ outPixel[3] = pixelsSum[3]/4;
209+ }
210+ }
211+ }
212+
213+ m_pixels = pixels;
214+ m_size = Size(ow, oh);
215+ return true;
216+}
217+
218+/*
219+ *
220+
221+void Texture::generateSoftwareMipmaps(std::vector<uint8> inPixels)
222+{
223+ bind();
224+
225+ VALIDATE(stdext::is_power_of_two(m_glSize.width()) && stdext::is_power_of_two(m_glSize.height()));
226+
227+ Size inSize = m_glSize;
228+ Size outSize = inSize / 2;
229+ std::vector<uint8> outPixels;
230+
231+ int mipmap = 1;
232+ while(true) {
233+ outPixels.resize(outSize.area()*4, 0);
234+
235+ // this is a simple bilinear filtering algorithm, it combines every 4 pixels in one pixel
236+ for(int x=0;x<outSize.width();++x) {
237+ for(int y=0;y<outSize.height();++y) {
238+ uint8 *inPixel[4];
239+ inPixel[0] = &inPixels[((y*2)*inSize.width() + (x*2))*4];
240+ inPixel[1] = &inPixels[((y*2)*inSize.width() + (x*2)+1)*4];
241+ inPixel[2] = &inPixels[((y*2+1)*inSize.width() + (x*2))*4];
242+ inPixel[3] = &inPixels[((y*2+1)*inSize.width() + (x*2)+1)*4];
243+ uint8 *outPixel = &outPixels[(y*outSize.width() + x)*4];
244+
245+ int pixelsSum[4];
246+ for(int i=0;i<4;++i)
247+ pixelsSum[i] = 0;
248+
249+ int usedPixels = 0;
250+ for(int j=0;j<4;++j) {
251+ // ignore colors of complete alpha pixels
252+ if(inPixel[j][3] < 16)
253+ continue;
254+
255+ for(int i=0;i<4;++i)
256+ pixelsSum[i] += inPixel[j][i];
257+
258+ usedPixels++;
259+ }
260+
261+ // try to guess the alpha pixel more accurately
262+ for(int i=0;i<4;++i) {
263+ if(usedPixels > 0)
264+ outPixel[i] = pixelsSum[i] / usedPixels;
265+ else
266+ outPixel[i] = 0;
267+ }
268+ outPixel[3] = pixelsSum[3]/4;
269+ }
270+ }
271+
272+ glTexImage2D(GL_TEXTURE_2D, mipmap++, GL_RGBA, outSize.width(), outSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, &outPixels[0]);
273+
274+ if(inSize.width() == 1 || inSize.height() == 1)
275+ break;
276+
277+ inPixels = std::move(outPixels);
278+ inSize /= 2;
279+ outSize /= 2;
280+ }
281+
282+ if(!m_hasMipmaps) {
283+ m_hasMipmaps = true;
284+ setupFilters();
285+ }
286+}
287+*/
288+
289+ImagePtr Image::fromQRCode(const std::string& code, int border)
290+{
291+ enum qrcodegen_Ecc errCorLvl = qrcodegen_Ecc_HIGH; // Error correction level
292+
293+ uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
294+ uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
295+ bool ok = qrcodegen_encodeText(code.c_str(), tempBuffer, qrcode, errCorLvl, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
296+ if (!ok)
297+ return nullptr;
298+ int size = qrcodegen_getSize(qrcode);
299+ ImagePtr image(new Image(Size(size + border * 2, size + border * 2)));
300+ for (int x = 0; x < size + border * 2; ++x) {
301+ for (int y = 0; y < size + border * 2; ++y) {
302+ image->setPixel(x, y, qrcodegen_getModule(qrcode, x - border, y - border) ? Color::black : Color::white);
303+ }
304+ }
305+ return image;
306+}
A RD_Client/src/framework/graphics/image.h +72-0 View file
@@ -0,0 +1,72 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef IMAGE_H
24+#define IMAGE_H
25+
26+#include "declarations.h"
27+#include <framework/util/databuffer.h>
28+
29+class Image : public stdext::shared_object
30+{
31+public:
32+ Image(const Size& size, int bpp = 4, uint8 *pixels = nullptr);
33+
34+ static ImagePtr load(std::string file);
35+ static ImagePtr loadPNG(const std::string& file);
36+ static ImagePtr loadPNG(const void* data, uint32_t size);
37+
38+ void savePNG(const std::string& fileName);
39+
40+ void blit(const Point& dest, const ImagePtr& other);
41+ void paste(const ImagePtr& other);
42+ ImagePtr upscale();
43+ void resize(const Size& size) { m_size = size; m_pixels.resize(size.area() * m_bpp, 0); }
44+ bool nextMipmap();
45+
46+ void setPixel(int x, int y, uint8 *pixel) { memcpy(&m_pixels[(y * m_size.width() + x) * m_bpp], pixel, m_bpp);}
47+ void setPixel(int x, int y, uint32_t argb) { setPixel(x, y, (uint8*)&argb); }
48+ void setPixel(int x, int y, const Color& color) {
49+ m_pixels[(y * m_size.width() + x) * m_bpp] = color.r();
50+ m_pixels[(y * m_size.width() + x) * m_bpp + 1] = color.g();
51+ m_pixels[(y * m_size.width() + x) * m_bpp + 2] = color.b();
52+ m_pixels[(y * m_size.width() + x) * m_bpp + 3] = color.a();
53+ }
54+
55+ std::vector<uint8>& getPixels() { return m_pixels; }
56+ uint8* getPixelData() { return &m_pixels[0]; }
57+ int getPixelCount() { return m_size.area(); }
58+ const Size& getSize() { return m_size; }
59+ int getWidth() { return m_size.width(); }
60+ int getHeight() { return m_size.height(); }
61+ int getBpp() { return m_bpp; }
62+ uint8* getPixel(int x, int y) { return &m_pixels[(y * m_size.width() + x) * m_bpp]; }
63+
64+ static ImagePtr fromQRCode(const std::string& code, int border);
65+
66+private:
67+ std::vector<uint8> m_pixels;
68+ Size m_size;
69+ int m_bpp;
70+};
71+
72+#endif
A RD_Client/src/framework/graphics/painter.h +259-0 View file
@@ -0,0 +1,259 @@
1+/*
2+* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+*
4+* Permission is hereby granted, free of charge, to any person obtaining a copy
5+* of this software and associated documentation files (the "Software"), to deal
6+* in the Software without restriction, including without limitation the rights
7+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+* copies of the Software, and to permit persons to whom the Software is
9+* furnished to do so, subject to the following conditions:
10+*
11+* The above copyright notice and this permission notice shall be included in
12+* all copies or substantial portions of the Software.
13+*
14+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+* THE SOFTWARE.
21+*/
22+
23+#ifndef PAINTER_H
24+#define PAINTER_H
25+
26+#include <framework/graphics/declarations.h>
27+#include <framework/graphics/coordsbuffer.h>
28+#include <framework/graphics/paintershaderprogram.h>
29+#include <framework/graphics/texture.h>
30+#include <framework/graphics/colorarray.h>
31+#include <framework/graphics/drawqueue.h>
32+
33+class Painter {
34+public:
35+ enum BlendEquation {
36+ BlendEquation_Add,
37+ BlendEquation_Max,
38+ BlendEquation_Subtract
39+ };
40+ enum CompositionMode {
41+ CompositionMode_Normal,
42+ CompositionMode_Multiply,
43+ CompositionMode_Add,
44+ CompositionMode_Replace,
45+ CompositionMode_DestBlending,
46+ CompositionMode_Light,
47+ CompositionMode_AlphaZeroing,
48+ CompositionMode_AlphaRestoring,
49+ CompositionMode_ZeroAlphaOverrite
50+
51+ };
52+ enum DepthFunc {
53+ DepthFunc_None,
54+ DepthFunc_LESS,
55+ DepthFunc_LESS_READ,
56+ DepthFunc_LEQUAL,
57+ DepthFunc_LEQUAL_READ,
58+ DepthFunc_EQUAL,
59+ DepthFunc_ALWAYS,
60+ DepthFunc_ALWAYS_READ
61+ };
62+ enum DrawMode {
63+ Triangles = GL_TRIANGLES,
64+ TriangleStrip = GL_TRIANGLE_STRIP
65+ };
66+
67+ struct PainterState {
68+ Size resolution;
69+ Matrix3 transformMatrix;
70+ Matrix3 projectionMatrix;
71+ Matrix3 textureMatrix;
72+ Color color;
73+ Painter::CompositionMode compositionMode;
74+ Painter::BlendEquation blendEquation;
75+ Rect clipRect;
76+ TexturePtr texture;
77+ PainterShaderProgram* shaderProgram;
78+ bool alphaWriting;
79+#ifdef WITH_DEPTH_BUFFER
80+ Painter::DepthFunc depthFunc;
81+ float depth;
82+#endif
83+ };
84+
85+ Painter();
86+ ~Painter() {}
87+
88+ void bind();
89+ void unbind();
90+
91+ void resetState();
92+ void refreshState();
93+ void saveState();
94+ void saveAndResetState();
95+ void restoreSavedState();
96+
97+ void clear(const Color& color);
98+ void clearRect(const Color& color, const Rect& rect);
99+
100+ void setTransformMatrix(const Matrix3& transformMatrix) { m_transformMatrix = transformMatrix; }
101+ void setProjectionMatrix(const Matrix3& projectionMatrix) { m_projectionMatrix = projectionMatrix; }
102+ void setTextureMatrix(const Matrix3& textureMatrix) { m_textureMatrix = textureMatrix; }
103+ void setCompositionMode(CompositionMode compositionMode);
104+ void setBlendEquation(BlendEquation blendEquation);
105+#ifdef WITH_DEPTH_BUFFER
106+ void setDepthFunc(DepthFunc func);
107+#endif
108+ void setClipRect(const Rect& clipRect);
109+ void setShaderProgram(PainterShaderProgram* shaderProgram) { m_shaderProgram = shaderProgram; }
110+ void setTexture(const TexturePtr& texture);
111+ void setAlphaWriting(bool enable);
112+
113+ void setResolution(const Size& resolution);
114+
115+ void scale(float x, float y);
116+ void translate(float x, float y);
117+ void rotate(float angle);
118+ void rotate(float x, float y, float angle);
119+
120+ void pushTransformMatrix();
121+ void popTransformMatrix();
122+
123+ Matrix3 getTransformMatrix() { return m_transformMatrix; }
124+ Matrix3 getProjectionMatrix() { return m_projectionMatrix; }
125+ Matrix3 getTextureMatrix() { return m_textureMatrix; }
126+ BlendEquation getBlendEquation() { return m_blendEquation; }
127+ PainterShaderProgram* getShaderProgram() { return m_shaderProgram; }
128+ bool getAlphaWriting() { return m_alphaWriting; }
129+
130+ void resetBlendEquation() { setBlendEquation(BlendEquation_Add); }
131+ void resetTexture() { setTexture(nullptr); }
132+ void resetAlphaWriting() { setAlphaWriting(true); }
133+ void resetTransformMatrix() { setTransformMatrix(Matrix3()); }
134+
135+ /* org */
136+ void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles, ColorArray* colorBuffer = nullptr, const std::vector<std::pair<int, Color>>* colors = nullptr);
137+ void drawFillCoords(CoordsBuffer& coordsBuffer);
138+ void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture, const std::vector<std::pair<int, Color>>* colors = nullptr);
139+ void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
140+ inline void drawTexturedRect(const Rect& dest, const TexturePtr& texture) { drawTexturedRect(dest, texture, Rect(Point(0, 0), texture->getSize())); }
141+ void drawColorOnTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
142+ void drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
143+ void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
144+ void drawFilledRect(const Rect& dest);
145+
146+ void setDrawProgram(PainterShaderProgram* drawProgram) { m_drawProgram = drawProgram; }
147+ bool hasShaders() { return true; }
148+
149+ void drawText(const Point& pos, CoordsBuffer& coordsBuffer, const Color& color, const TexturePtr& texture);
150+ void drawText(const Point& pos, CoordsBuffer& coordsBuffer, const std::vector<std::pair<int, Color>>& colors, const TexturePtr& texture);
151+
152+ void drawLine(const std::vector<float>& vertex, int size, int width = 1);
153+
154+ void setSecondTexture(const TexturePtr& texture);
155+ void setOffset(const Point& offset);
156+
157+ void setAtlasTextures(const TexturePtr& atlas);
158+ void drawCache(const std::vector<float>& vertex, const std::vector<float>& texture, const std::vector<float>& color, int size);
159+
160+ void setColor(const Color& color) { m_color = color; }
161+ void setShaderProgram(const PainterShaderProgramPtr& shaderProgram) { setShaderProgram(shaderProgram.get()); }
162+
163+ void scale(float factor) { scale(factor, factor); }
164+ void translate(const Point& p) { translate(p.x, p.y); }
165+ void rotate(const Point& p, float angle) { rotate(p.x, p.y, angle); }
166+
167+#ifdef WITH_DEPTH_BUFFER
168+ void setDepth(float depth) { m_depth = depth; }
169+ float getDepth() { return m_depth; }
170+ DepthFunc getDepthFunc() { return m_depthFunc; }
171+ void resetDepth() { return setDepth(0.0f); }
172+ void resetDepthFunc() { setDepthFunc(DepthFunc_None); }
173+#endif
174+
175+ Size getResolution() { return m_resolution; }
176+ Color getColor() { return m_color; }
177+ Rect getClipRect() { return m_clipRect; }
178+ CompositionMode getCompositionMode() { return m_compositionMode; }
179+
180+ void resetClipRect() { setClipRect(Rect()); }
181+ void resetCompositionMode() { setCompositionMode(CompositionMode_Normal); }
182+ void resetColor() { setColor(Color::white); }
183+ void resetShaderProgram() { setShaderProgram(nullptr); }
184+
185+ int draws() { return m_draws; }
186+ int calls() { return m_calls; }
187+ void resetDraws() { m_draws = m_calls = 0; }
188+
189+ void setDrawColorOnTextureShaderProgram()
190+ {
191+ setShaderProgram(m_drawSolidColorOnTextureProgram);
192+ }
193+
194+ void setMatrixColor(const Matrix4& mat4)
195+ {
196+ m_matrixColor = mat4;
197+ }
198+ void setDrawOutfitLayersProgram()
199+ {
200+ setShaderProgram(m_drawOutfitLayersProgram);
201+ }
202+
203+protected:
204+ void updateGlTexture();
205+ void updateGlCompositionMode();
206+ void updateGlBlendEquation();
207+ void updateGlClipRect();
208+ void updateGlAlphaWriting();
209+ void updateGlViewport();
210+#ifdef WITH_DEPTH_BUFFER
211+ void updateDepthFunc();
212+#endif
213+
214+ CoordsBuffer m_coordsBuffer;
215+
216+ std::vector<Matrix3> m_transformMatrixStack;
217+ Matrix3 m_transformMatrix;
218+ Matrix3 m_projectionMatrix;
219+ Matrix3 m_textureMatrix;
220+ Matrix3 m_atlasTextureMatrix;
221+
222+ BlendEquation m_blendEquation;
223+ TexturePtr m_texture;
224+ bool m_alphaWriting;
225+
226+ PainterState m_olderStates[10];
227+ int m_oldStateIndex;
228+
229+ uint m_glTextureId;
230+
231+ PainterShaderProgram* m_shaderProgram;
232+ CompositionMode m_compositionMode;
233+ Color m_color;
234+ Matrix4 m_matrixColor;
235+ Size m_resolution;
236+ Rect m_clipRect;
237+#ifdef WITH_DEPTH_BUFFER
238+ DepthFunc m_depthFunc;
239+ float m_depth;
240+#endif
241+ int m_draws = 0;
242+ int m_calls = 0;
243+
244+private:
245+ PainterShaderProgram* m_drawProgram;
246+ PainterShaderProgramPtr m_drawTexturedProgram;
247+ PainterShaderProgramPtr m_drawSolidColorProgram;
248+ PainterShaderProgramPtr m_drawSolidColorOnTextureProgram;
249+ PainterShaderProgramPtr m_drawOutfitLayersProgram;
250+
251+ PainterShaderProgramPtr m_drawNewProgram;
252+
253+ PainterShaderProgramPtr m_drawTextProgram;
254+ PainterShaderProgramPtr m_drawLineProgram;
255+};
256+
257+extern Painter* g_painter;
258+
259+#endif
A RD_Client/src/framework/graphics/paintershaderprogram.cpp +226-0 View file
@@ -0,0 +1,226 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#include "paintershaderprogram.h"
24+#include "graphics.h"
25+#include "painter.h"
26+#include "texture.h"
27+#include "texturemanager.h"
28+#include <framework/core/clock.h>
29+#include <framework/platform/platformwindow.h>
30+
31+PainterShaderProgram::PainterShaderProgram(const std::string &name)
32+ : ShaderProgram(name) {
33+ m_startTime = g_clock.seconds();
34+ m_depth = 0;
35+ m_color = Color::white;
36+ m_time = 0;
37+}
38+
39+void PainterShaderProgram::setupUniforms() {
40+ bindUniformLocation(TRANSFORM_MATRIX_UNIFORM, "u_TransformMatrix");
41+ bindUniformLocation(PROJECTION_MATRIX_UNIFORM, "u_ProjectionMatrix");
42+ bindUniformLocation(TEXTURE_MATRIX_UNIFORM, "u_TextureMatrix");
43+
44+ bindUniformLocation(COLOR_UNIFORM, "u_Color");
45+ bindUniformLocation(DEPTH_UNIFORM, "u_Depth");
46+ bindUniformLocation(TIME_UNIFORM, "u_Time");
47+
48+ bindUniformLocation(TEX0_UNIFORM, "u_Tex0");
49+ bindUniformLocation(TEX1_UNIFORM, "u_Tex1");
50+ bindUniformLocation(TEX2_UNIFORM, "u_Tex2");
51+ bindUniformLocation(TEX3_UNIFORM, "u_Tex3");
52+
53+ bindUniformLocation(ATLAS_TEX0_UNIFORM, "u_Atlas");
54+ bindUniformLocation(ATLAS_TEX1_UNIFORM, "u_Fonts");
55+
56+ bindUniformLocation(RESOLUTION_UNIFORM, "u_Resolution");
57+ bindUniformLocation(OFFSET_UNIFORM, "u_Offset");
58+ bindUniformLocation(CENTER_UNIFORM, "u_Center");
59+
60+ // VALUES
61+ setUniformValue(TRANSFORM_MATRIX_UNIFORM, m_transformMatrix);
62+ setUniformValue(PROJECTION_MATRIX_UNIFORM, m_projectionMatrix);
63+ setUniformValue(TEXTURE_MATRIX_UNIFORM, m_textureMatrix);
64+
65+ if (!m_useColorMatrix) {
66+ setUniformValue(COLOR_UNIFORM, m_color);
67+ }
68+ setUniformValue(TIME_UNIFORM, m_time);
69+ setUniformValue(DEPTH_UNIFORM, m_depth);
70+
71+ setUniformValue(TEX0_UNIFORM, 0);
72+ setUniformValue(TEX1_UNIFORM, 1);
73+ setUniformValue(TEX2_UNIFORM, 2);
74+ setUniformValue(TEX3_UNIFORM, 3);
75+
76+ setUniformValue(ATLAS_TEX0_UNIFORM, 6);
77+ setUniformValue(ATLAS_TEX1_UNIFORM, 7);
78+
79+ setUniformValue(RESOLUTION_UNIFORM, (float)m_resolution.width(),
80+ (float)m_resolution.height());
81+ setUniformValue(OFFSET_UNIFORM, (float)m_offset.x, (float)m_offset.y);
82+ setUniformValue(CENTER_UNIFORM, (float)m_center.x, (float)m_center.y);
83+}
84+
85+bool PainterShaderProgram::link() {
86+ m_startTime = g_clock.seconds();
87+ bindAttributeLocation(VERTEX_ATTR, "a_Vertex");
88+ bindAttributeLocation(TEXCOORD_ATTR, "a_TexCoord");
89+ bindAttributeLocation(DEPTH_ATTR, "a_Depth");
90+ bindAttributeLocation(COLOR_ATTR, "a_Color");
91+ bindAttributeLocation(DEPTH_TEXCOORD_ATTR, "a_DepthTexCoord");
92+ if (!ShaderProgram::link())
93+ return false;
94+ bind();
95+ setupUniforms();
96+ release();
97+ g_graphics.checkForError(stdext::format("%s (%s)", __FUNCTION__, getName()),
98+ __FILE__, __LINE__);
99+ return true;
100+}
101+
102+void PainterShaderProgram::setTransformMatrix(const Matrix3 &transformMatrix) {
103+ if (transformMatrix == m_transformMatrix)
104+ return;
105+
106+ bind();
107+ setUniformValue(TRANSFORM_MATRIX_UNIFORM, transformMatrix);
108+ m_transformMatrix = transformMatrix;
109+}
110+
111+void PainterShaderProgram::setProjectionMatrix(
112+ const Matrix3 &projectionMatrix) {
113+ if (projectionMatrix == m_projectionMatrix)
114+ return;
115+
116+ bind();
117+ setUniformValue(PROJECTION_MATRIX_UNIFORM, projectionMatrix);
118+ m_projectionMatrix = projectionMatrix;
119+}
120+
121+void PainterShaderProgram::setTextureMatrix(const Matrix3 &textureMatrix) {
122+ if (textureMatrix == m_textureMatrix)
123+ return;
124+
125+ bind();
126+ setUniformValue(TEXTURE_MATRIX_UNIFORM, textureMatrix);
127+ m_textureMatrix = textureMatrix;
128+}
129+
130+void PainterShaderProgram::setColor(const Color &color) {
131+ if (color == m_color || m_useColorMatrix)
132+ return;
133+
134+ bind();
135+ setUniformValue(COLOR_UNIFORM, color);
136+ m_color = color;
137+}
138+
139+void PainterShaderProgram::setMatrixColor(const Matrix4 &colors) {
140+ bind();
141+ setUniformValue(COLOR_UNIFORM, colors);
142+}
143+
144+#ifdef WITH_DEPTH_BUFFER
145+void PainterShaderProgram::setDepth(float depth) {
146+ if (depth < 0.)
147+ depth = 0.;
148+
149+ if (m_depth == depth)
150+ return;
151+
152+ bind();
153+ setUniformValue(DEPTH_UNIFORM, depth);
154+ m_depth = depth;
155+}
156+#endif
157+
158+void PainterShaderProgram::setResolution(const Size &resolution) {
159+ if (m_resolution == resolution)
160+ return;
161+
162+ bind();
163+ setUniformValue(RESOLUTION_UNIFORM, (float)resolution.width(),
164+ (float)resolution.height());
165+ m_resolution = resolution;
166+}
167+
168+void PainterShaderProgram::setOffset(const Point &offset) {
169+ if (m_offset == offset)
170+ return;
171+
172+ bind();
173+ m_offset = offset;
174+ setUniformValue(OFFSET_UNIFORM, (float)m_offset.x, (float)m_offset.y);
175+}
176+
177+void PainterShaderProgram::setCenter(const Point &center) {
178+ if (m_center == center)
179+ return;
180+
181+ bind();
182+ m_center = center;
183+ setUniformValue(CENTER_UNIFORM, (float)m_center.x, (float)m_center.y);
184+}
185+
186+void PainterShaderProgram::updateTime() {
187+ float time = g_clock.seconds() - m_startTime;
188+ if (m_time == time)
189+ return;
190+
191+ bind();
192+ setUniformValue(TIME_UNIFORM, time);
193+ m_time = time;
194+}
195+
196+void PainterShaderProgram::addMultiTexture(const std::string &file) {
197+ if (m_multiTextures.size() > 3)
198+ g_logger.error(stdext::format(
199+ "cannot add more multi textures to shader, the max is 3 - %s",
200+ getName()));
201+
202+ TexturePtr texture = g_textures.getTexture(file);
203+ if (!texture)
204+ return;
205+
206+ texture->setSmooth(true);
207+ texture->setRepeat(true);
208+
209+ m_multiTextures.push_back(texture);
210+}
211+
212+void PainterShaderProgram::bindMultiTextures() {
213+ if (m_multiTextures.size() == 0)
214+ return;
215+
216+ int i = 1;
217+ for (const TexturePtr &tex : m_multiTextures) {
218+ tex->update();
219+ glActiveTexture(GL_TEXTURE0 + i++);
220+ glBindTexture(GL_TEXTURE_2D, tex->getId());
221+ }
222+
223+ glActiveTexture(GL_TEXTURE0);
224+}
225+
226+void PainterShaderProgram::clearMultiTextures() { m_multiTextures.clear(); }
A RD_Client/src/framework/graphics/paintershaderprogram.h +101-0 View file
@@ -0,0 +1,101 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef PAINTERSHADERPROGRAM_H
24+#define PAINTERSHADERPROGRAM_H
25+
26+#include "coordsbuffer.h"
27+#include "shaderprogram.h"
28+#include <framework/core/timer.h>
29+
30+class PainterShaderProgram : public ShaderProgram {
31+protected:
32+ enum {
33+ VERTEX_ATTR = 0,
34+ TEXCOORD_ATTR = 1,
35+ DEPTH_ATTR = 2,
36+ COLOR_ATTR = 3,
37+ DEPTH_TEXCOORD_ATTR = 4,
38+
39+ PROJECTION_MATRIX_UNIFORM = 0,
40+ TEXTURE_MATRIX_UNIFORM = 1,
41+ TRANSFORM_MATRIX_UNIFORM = 2,
42+
43+ COLOR_UNIFORM = 3,
44+ TIME_UNIFORM = 5,
45+ DEPTH_UNIFORM = 6,
46+
47+ TEX0_UNIFORM = 7,
48+ TEX1_UNIFORM = 8,
49+ TEX2_UNIFORM = 9,
50+ TEX3_UNIFORM = 10,
51+ ATLAS_TEX0_UNIFORM = 11,
52+ ATLAS_TEX1_UNIFORM = 12,
53+
54+ RESOLUTION_UNIFORM = 13,
55+ OFFSET_UNIFORM = 14,
56+ CENTER_UNIFORM = 15
57+ };
58+
59+ friend class Painter;
60+
61+ virtual void setupUniforms();
62+
63+public:
64+ PainterShaderProgram(const std::string &name);
65+
66+ bool link();
67+
68+ void setTransformMatrix(const Matrix3 &transformMatrix);
69+ void setProjectionMatrix(const Matrix3 &projectionMatrix);
70+ void setTextureMatrix(const Matrix3 &textureMatrix);
71+ void setColor(const Color &color);
72+ void setMatrixColor(const Matrix4 &colors);
73+ void setDepth(float depth);
74+ void setResolution(const Size &resolution);
75+ void setOffset(const Point &offset);
76+ void setCenter(const Point &center);
77+ void updateTime();
78+
79+ void addMultiTexture(const std::string &file);
80+ void bindMultiTextures();
81+ void clearMultiTextures();
82+
83+ void enableColorMatrix() { m_useColorMatrix = true; }
84+
85+private:
86+ float m_startTime;
87+
88+ Color m_color;
89+ float m_depth;
90+ Matrix3 m_transformMatrix;
91+ Matrix3 m_projectionMatrix;
92+ Matrix3 m_textureMatrix;
93+ Size m_resolution;
94+ Point m_offset;
95+ Point m_center;
96+ float m_time;
97+ std::vector<TexturePtr> m_multiTextures;
98+ bool m_useColorMatrix = false;
99+};
100+
101+#endif
A RD_Client/src/framework/graphics/particleeffect.cpp +0-0 View file
Empty file.
A RD_Client/src/framework/graphics/particleeffect.h +0-0 View file
Empty file.
A RD_Client/src/framework/graphics/shader.cpp +93-0 View file
@@ -0,0 +1,93 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#include "shader.h"
24+#include "graphics.h"
25+
26+#include <framework/core/application.h>
27+#include <framework/core/resourcemanager.h>
28+
29+Shader::Shader(Shader::ShaderType shaderType)
30+{
31+ m_shaderType = shaderType;
32+ switch(shaderType) {
33+ case Vertex:
34+ m_shaderId = glCreateShader(GL_VERTEX_SHADER);
35+ break;
36+ case Fragment:
37+ m_shaderId = glCreateShader(GL_FRAGMENT_SHADER);
38+ break;
39+ }
40+
41+ if(!m_shaderId)
42+ g_logger.fatal("Unable to create GL shader");
43+}
44+
45+Shader::~Shader()
46+{
47+ VALIDATE(!g_app.isTerminated());
48+ if(g_graphics.ok())
49+ glDeleteShader(m_shaderId);
50+}
51+
52+bool Shader::compileSourceCode(const std::string& sourceCode)
53+{
54+#ifdef OPENGL_ES
55+ static const char *qualifierDefines =
56+ "precision highp float;\n";
57+ std::string code = qualifierDefines;
58+ code.append(sourceCode);
59+ const char* c_source = code.c_str();
60+#else
61+ const char* c_source = sourceCode.c_str();
62+#endif
63+ glShaderSource(m_shaderId, 1, &c_source, NULL);
64+ glCompileShader(m_shaderId);
65+
66+ int res = GL_FALSE;
67+ glGetShaderiv(m_shaderId, GL_COMPILE_STATUS, &res);
68+ return (res == GL_TRUE);
69+}
70+
71+bool Shader::compileSourceFile(const std::string& sourceFile)
72+{
73+ try {
74+ std::string sourceCode = g_resources.readFileContents(sourceFile);
75+ return compileSourceCode(sourceCode);
76+ } catch(stdext::exception& e) {
77+ g_logger.error(stdext::format("unable to load shader source form file '%s': %s", sourceFile, e.what()));
78+ }
79+ return false;
80+}
81+
82+std::string Shader::log()
83+{
84+ std::string infoLog;
85+ int infoLogLength = 0;
86+ glGetShaderiv(m_shaderId, GL_INFO_LOG_LENGTH, &infoLogLength);
87+ if(infoLogLength > 1) {
88+ std::vector<char> buf(infoLogLength);
89+ glGetShaderInfoLog(m_shaderId, infoLogLength-1, NULL, &buf[0]);
90+ infoLog = &buf[0];
91+ }
92+ return infoLog;
93+}
A RD_Client/src/framework/graphics/shader.h +51-0 View file
@@ -0,0 +1,51 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef SHADER_H
24+#define SHADER_H
25+
26+#include "declarations.h"
27+
28+class Shader : public stdext::shared_object
29+{
30+public:
31+ enum ShaderType {
32+ Vertex,
33+ Fragment
34+ };
35+
36+ Shader(ShaderType shaderType);
37+ ~Shader();
38+
39+ bool compileSourceCode(const std::string& sourceCode);
40+ bool compileSourceFile(const std::string& sourceFile);
41+ std::string log();
42+
43+ uint getShaderId() { return m_shaderId; }
44+ ShaderType getShaderType() { return m_shaderType; }
45+
46+private:
47+ uint m_shaderId;
48+ ShaderType m_shaderType;
49+};
50+
51+#endif
A RD_Client/src/framework/graphics/shadermanager.cpp +76-0 View file
@@ -0,0 +1,76 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#include "shadermanager.h"
24+#include <framework/graphics/paintershaderprogram.h>
25+#include <framework/graphics/graphics.h>
26+#include <framework/core/resourcemanager.h>
27+#include <framework/core/eventdispatcher.h>
28+
29+ShaderManager g_shaders;
30+
31+void ShaderManager::init()
32+{
33+ PainterShaderProgram::release();
34+}
35+
36+void ShaderManager::terminate()
37+{
38+ m_shaders.clear();
39+}
40+
41+void ShaderManager::createShader(const std::string& name, std::string vertex, std::string fragment, bool colorMatrix)
42+{
43+ if (vertex.find("\n") == std::string::npos) { // file
44+ vertex = g_resources.guessFilePath(vertex, "frag");
45+ vertex = g_resources.readFileContents(vertex);
46+ }
47+ if (fragment.find("\n") == std::string::npos) { // file
48+ fragment = g_resources.guessFilePath(fragment, "frag");
49+ fragment = g_resources.readFileContents(fragment);
50+ }
51+
52+ g_graphicsDispatcher.addEventEx("createShader", [&, name, vertex, fragment, colorMatrix] {
53+ auto program = PainterShaderProgram::create(name, vertex, fragment, colorMatrix);
54+ if (program)
55+ m_shaders[name] = program;
56+ });
57+}
58+
59+void ShaderManager::addTexture(const std::string& name, const std::string& file)
60+{
61+ g_graphicsDispatcher.addEventEx("addTexture", [&, name, file] {
62+ auto program = getShader(name);
63+ if (program)
64+ program->addMultiTexture(file);
65+ });
66+}
67+
68+PainterShaderProgramPtr ShaderManager::getShader(const std::string& name)
69+{
70+ VALIDATE_GRAPHICS_THREAD();
71+ auto it = m_shaders.find(name);
72+ if(it != m_shaders.end())
73+ return it->second;
74+ return nullptr;
75+}
76+
A RD_Client/src/framework/graphics/shadermanager.h +52-0 View file
@@ -0,0 +1,52 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef SHADERMANAGER_H
24+#define SHADERMANAGER_H
25+
26+#include "declarations.h"
27+#include <framework/graphics/paintershaderprogram.h>
28+
29+//@bindsingleton g_shaders
30+class ShaderManager
31+{
32+public:
33+ void init();
34+ void terminate();
35+
36+ void createShader(const std::string& name, std::string vertex, std::string fragment, bool colorMatrix = false);
37+ void createOutfitShader(const std::string& name, std::string vertex, std::string fragment)
38+ {
39+ return createShader(name, vertex, fragment, true);
40+ }
41+ void addTexture(const std::string& name, const std::string& file);
42+ PainterShaderProgramPtr getShader(const std::string& name);
43+
44+private:
45+ std::unordered_map<std::string, PainterShaderProgramPtr> m_shaders;
46+};
47+
48+
49+extern ShaderManager g_shaders;
50+
51+#endif
52+
A RD_Client/src/framework/graphics/shaderprogram.cpp +184-0 View file
@@ -0,0 +1,184 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#include "shaderprogram.h"
24+#include "graphics.h"
25+
26+#include <framework/core/application.h>
27+
28+uint ShaderProgram::m_currentProgram = 0;
29+
30+ShaderProgram::ShaderProgram(const std::string& name) : m_name(name)
31+{
32+ m_linked = false;
33+ m_programId = glCreateProgram();
34+ m_uniformLocations.fill(-1);
35+ if(!m_programId)
36+ g_logger.fatal("Unable to create GL shader program");
37+}
38+
39+ShaderProgram::~ShaderProgram()
40+{
41+ VALIDATE(!g_app.isTerminated());
42+ if(g_graphics.ok())
43+ glDeleteProgram(m_programId);
44+}
45+
46+PainterShaderProgramPtr ShaderProgram::create(const std::string& name, const std::string& vertexShader, const std::string& fragmentShader, bool colorMatrix)
47+{
48+ PainterShaderProgramPtr program(new PainterShaderProgram(name));
49+ if (!program) {
50+ g_logger.error(stdext::format("Cant creatre shader: %s", program->getName()));
51+ return nullptr;
52+ }
53+ if (!program->addShaderFromSourceCode(Shader::Vertex, vertexShader))
54+ return nullptr;
55+ if(!program->addShaderFromSourceCode(Shader::Fragment, fragmentShader))
56+ return nullptr;
57+
58+ if (colorMatrix) {
59+ program->enableColorMatrix();
60+ }
61+ if (!program->link()) {
62+ g_graphics.checkForError(stdext::format("%s (%s)", __FUNCTION__, program->getName()), vertexShader + "\n" + fragmentShader, __LINE__);
63+ return nullptr;
64+ }
65+ g_graphics.checkForError(stdext::format("%s (%s)", __FUNCTION__, program->getName()), vertexShader + "\n" + fragmentShader, __LINE__);
66+ return program;
67+}
68+
69+
70+bool ShaderProgram::addShader(const ShaderPtr& shader) {
71+ glAttachShader(m_programId, shader->getShaderId());
72+ m_linked = false;
73+ m_shaders.push_back(shader);
74+ return true;
75+}
76+
77+bool ShaderProgram::addShaderFromSourceCode(Shader::ShaderType shaderType, const std::string& sourceCode) {
78+ ShaderPtr shader(new Shader(shaderType));
79+ if(!shader->compileSourceCode(sourceCode)) {
80+ g_logger.error(stdext::format("failed to compile shader: %s\n%s", getName(), shader->log()));
81+ return false;
82+ }
83+ return addShader(shader);
84+}
85+
86+bool ShaderProgram::addShaderFromSourceFile(Shader::ShaderType shaderType, const std::string& sourceFile) {
87+ ShaderPtr shader(new Shader(shaderType));
88+ if(!shader->compileSourceFile(sourceFile)) {
89+ g_logger.error(stdext::format("failed to compile shader %s (%s): %s", getName(), sourceFile, shader->log()));
90+ return false;
91+ }
92+ return addShader(shader);
93+}
94+
95+void ShaderProgram::removeShader(const ShaderPtr& shader)
96+{
97+ auto it = std::find(m_shaders.begin(), m_shaders.end(), shader);
98+ if(it == m_shaders.end())
99+ return;
100+
101+ glDetachShader(m_programId, shader->getShaderId());
102+ m_shaders.erase(it);
103+ m_linked = false;
104+}
105+
106+void ShaderProgram::removeAllShaders()
107+{
108+ while(!m_shaders.empty())
109+ removeShader(m_shaders.front());
110+}
111+
112+bool ShaderProgram::link()
113+{
114+ if(m_linked)
115+ return true;
116+
117+ glLinkProgram(m_programId);
118+
119+ int value = GL_FALSE;
120+ glGetProgramiv(m_programId, GL_LINK_STATUS, &value);
121+ m_linked = (value != GL_FALSE);
122+ if (m_linked) {
123+ return true;
124+ }
125+
126+ GLint maxLength = 0;
127+ glGetProgramiv(m_programId, GL_INFO_LOG_LENGTH, &maxLength);
128+ std::vector<GLchar> infoLog(maxLength);
129+ glGetProgramInfoLog(m_programId, maxLength, &maxLength, &infoLog[0]);
130+ g_logger.error(stdext::format("Program %i, %s linking error (%i): %s - %s - %s %s\nExtensions: %s", m_programId, getName(), infoLog.size(),
131+ std::string(infoLog.begin(), infoLog.end()).c_str(), log().c_str(),
132+ g_graphics.getRenderer(), g_graphics.getVersion(), g_graphics.getExtensions()));
133+ return false;
134+}
135+
136+bool ShaderProgram::bind()
137+{
138+ if(m_currentProgram != m_programId) {
139+ if (!m_linked) {
140+ link();
141+ }
142+ glUseProgram(m_programId);
143+ m_currentProgram = m_programId;
144+ }
145+ return true;
146+}
147+
148+void ShaderProgram::release()
149+{
150+ if(m_currentProgram != 0) {
151+ m_currentProgram = 0;
152+ glUseProgram(0);
153+ }
154+}
155+
156+std::string ShaderProgram::log()
157+{
158+ std::string infoLog;
159+ int infoLogLength = 0;
160+ glGetProgramiv(m_programId, GL_INFO_LOG_LENGTH, &infoLogLength);
161+ if(infoLogLength > 1) {
162+ std::vector<char> buf(infoLogLength);
163+ glGetShaderInfoLog(m_programId, infoLogLength-1, NULL, &buf[0]);
164+ infoLog = &buf[0];
165+ }
166+ return infoLog;
167+}
168+
169+int ShaderProgram::getAttributeLocation(const char* name)
170+{
171+ return glGetAttribLocation(m_programId, name);
172+}
173+
174+void ShaderProgram::bindAttributeLocation(int location, const char* name)
175+{
176+ return glBindAttribLocation(m_programId, location, name);
177+}
178+
179+void ShaderProgram::bindUniformLocation(int location, const char* name)
180+{
181+ VALIDATE(m_linked);
182+ VALIDATE(location >= 0 && location < MAX_UNIFORM_LOCATIONS);
183+ m_uniformLocations[location] = glGetUniformLocation(m_programId, name);
184+}
A RD_Client/src/framework/graphics/shaderprogram.h +106-0 View file
@@ -0,0 +1,106 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef SHADERPROGRAM_H
24+#define SHADERPROGRAM_H
25+
26+#include "shader.h"
27+#include <framework/luaengine/luaobject.h>
28+
29+ // @bindclass
30+class ShaderProgram : public LuaObject {
31+ enum {
32+ MAX_UNIFORM_LOCATIONS = 30
33+ };
34+
35+public:
36+ ShaderProgram(const std::string& name);
37+ ~ShaderProgram();
38+
39+ static PainterShaderProgramPtr create(const std::string& name, const std::string& vertexShader, const std::string& fragmentShader, bool colorMatrix = false);
40+
41+ bool addShader(const ShaderPtr& shader);
42+ bool addShaderFromSourceCode(Shader::ShaderType shaderType, const std::string& sourceCode);
43+ bool addShaderFromSourceFile(Shader::ShaderType shaderType, const std::string& sourceFile);
44+ void removeShader(const ShaderPtr& shader);
45+ void removeAllShaders();
46+
47+ virtual bool link();
48+ bool bind();
49+ static void release();
50+ std::string log();
51+
52+ static void disableAttributeArray(int location) { glDisableVertexAttribArray(location); }
53+ static void enableAttributeArray(int location) { glEnableVertexAttribArray(location); }
54+ void disableAttributeArray(const char* name) { glDisableVertexAttribArray(getAttributeLocation(name)); }
55+ void enableAttributeArray(const char* name) { glEnableVertexAttribArray(getAttributeLocation(name)); }
56+
57+ int getAttributeLocation(const char* name);
58+ void bindAttributeLocation(int location, const char* name);
59+ void bindUniformLocation(int location, const char* name);
60+
61+ void setAttributeArray(int location, const float* values, int size, int stride = 0) { glVertexAttribPointer(location, size, GL_FLOAT, GL_FALSE, stride, values); }
62+ void setAttributeValue(int location, float value) { glVertexAttrib1f(location, value); }
63+ void setAttributeValue(int location, float x, float y) { glVertexAttrib2f(location, x, y); }
64+ void setAttributeValue(int location, float x, float y, float z) { glVertexAttrib3f(location, x, y, z); }
65+ void setAttributeArray(const char* name, const float* values, int size, int stride = 0) { glVertexAttribPointer(getAttributeLocation(name), size, GL_FLOAT, GL_FALSE, stride, values); }
66+ void setAttributeValue(const char* name, float value) { glVertexAttrib1f(getAttributeLocation(name), value); }
67+ void setAttributeValue(const char* name, float x, float y) { glVertexAttrib2f(getAttributeLocation(name), x, y); }
68+ void setAttributeValue(const char* name, float x, float y, float z) { glVertexAttrib3f(getAttributeLocation(name), x, y, z); }
69+
70+ void setUniformValue(int location, const Color& color) { glUniform4f(m_uniformLocations[location], color.rF(), color.gF(), color.bF(), color.aF()); }
71+ void setUniformValue(int location, int value) { glUniform1i(m_uniformLocations[location], value); }
72+ void setUniformValue(int location, float value) { glUniform1f(m_uniformLocations[location], value); }
73+ void setUniformValue(int location, float x, float y) { glUniform2f(m_uniformLocations[location], x, y); }
74+ void setUniformValue(int location, float x, float y, float z) { glUniform3f(m_uniformLocations[location], x, y, z); }
75+ void setUniformValue(int location, float x, float y, float z, float w) { glUniform4f(m_uniformLocations[location], x, y, z, w); }
76+ void setUniformValue(int location, const Matrix2& mat) { glUniformMatrix2fv(m_uniformLocations[location], 1, GL_FALSE, mat.data()); }
77+ void setUniformValue(int location, const Matrix3& mat) { glUniformMatrix3fv(m_uniformLocations[location], 1, GL_FALSE, mat.data()); }
78+ void setUniformValue(int location, const Matrix4& mat) { glUniformMatrix4fv(m_uniformLocations[location], 1, GL_FALSE, mat.data()); }
79+ void setUniformValue(int location, int count, const int* value) { glUniform1iv(m_uniformLocations[location], count, value); }
80+ void setUniformValue(const char* name, const Color& color) { glUniform4f(glGetUniformLocation(m_programId, name), color.rF(), color.gF(), color.bF(), color.aF()); }
81+ void setUniformValue(const char* name, int value) { glUniform1i(glGetUniformLocation(m_programId, name), value); }
82+ void setUniformValue(const char* name, float value) { glUniform1f(glGetUniformLocation(m_programId, name), value); }
83+ void setUniformValue(const char* name, float x, float y) { glUniform2f(glGetUniformLocation(m_programId, name), x, y); }
84+ void setUniformValue(const char* name, float x, float y, float z) { glUniform3f(glGetUniformLocation(m_programId, name), x, y, z); }
85+ void setUniformValue(const char* name, float x, float y, float z, float w) { glUniform4f(glGetUniformLocation(m_programId, name), x, y, z, w); }
86+ void setUniformValue(const char* name, const Matrix2& mat) { glUniformMatrix2fv(glGetUniformLocation(m_programId, name), 1, GL_FALSE, mat.data()); }
87+ void setUniformValue(const char* name, const Matrix3& mat) { glUniformMatrix3fv(glGetUniformLocation(m_programId, name), 1, GL_FALSE, mat.data()); }
88+ void setUniformValue(const char* name, const Matrix4& mat) { glUniformMatrix4fv(glGetUniformLocation(m_programId, name), 1, GL_FALSE, mat.data()); }
89+ // TODO: Point, PointF, Color, Size, SizeF ?
90+
91+ bool isLinked() { return m_linked; }
92+ uint getProgramId() { return m_programId; }
93+ ShaderList getShaders() { return m_shaders; }
94+
95+ std::string getName() { return m_name; }
96+
97+private:
98+ std::string m_name;
99+ bool m_linked;
100+ uint m_programId;
101+ static uint m_currentProgram;
102+ ShaderList m_shaders;
103+ std::array<int, MAX_UNIFORM_LOCATIONS> m_uniformLocations;
104+};
105+
106+#endif
A RD_Client/src/framework/graphics/shaders/newshader.h +79-0 View file
@@ -0,0 +1,79 @@
1+#ifndef NEWSHADER_H
2+#define NEWSHADER_H
3+
4+#include <string>
5+// VERTEX
6+static const std::string newVertexShader = "\n\
7+ attribute vec2 a_Vertex;\n\
8+ attribute vec2 a_TexCoord;\n\
9+ attribute vec4 a_Color;\n\
10+ \n\
11+ uniform mat3 u_ProjectionMatrix;\n\
12+ uniform mat3 u_TransformMatrix;\n\
13+ uniform mat3 u_TextureMatrix;\n\
14+ \n\
15+ varying vec2 v_TexCoord;\n\
16+ varying vec4 v_Color;\n\
17+ void main()\n\
18+ {\n\
19+ gl_Position = vec4((u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy, 1.0)).xy, 1.0, 1.0);\n\
20+ v_TexCoord = (u_TextureMatrix * vec3(a_TexCoord,1.0)).xy;\n\
21+ v_Color = a_Color;\n\
22+ }\n";
23+
24+// TEXT
25+static const std::string textVertexShader = "\n\
26+ attribute vec2 a_TexCoord;\n\
27+ uniform mat3 u_TextureMatrix;\n\
28+ varying vec2 v_TexCoord;\n\
29+ attribute vec2 a_Vertex;\n\
30+ uniform mat3 u_TransformMatrix;\n\
31+ uniform mat3 u_ProjectionMatrix;\n\
32+ uniform float u_Depth;\n\
33+ uniform vec2 u_Offset;\n\
34+ void main()\n\
35+ {\n\
36+ gl_Position = vec4((u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy + u_Offset, 1.0)).xy, 1.0, 1.0);\n\
37+ v_TexCoord = (u_TextureMatrix * vec3(a_TexCoord,1.0)).xy;\n\
38+ }\n";
39+
40+// LINE
41+static const std::string lineVertexShader = "\n\
42+ attribute vec2 a_Vertex;\n\
43+ uniform mat3 u_TransformMatrix;\n\
44+ uniform mat3 u_ProjectionMatrix;\n\
45+ void main()\n\
46+ {\n\
47+ gl_Position = vec4((u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy, 1.0)).xy, 1.0, 1.0);\n\
48+ }\n";
49+
50+// FRAGMENT
51+static const std::string newFragmentShader = "\n\
52+ varying vec2 v_TexCoord;\n\
53+ varying vec4 v_Color;\n\
54+ uniform sampler2D u_Atlas;\n\
55+ void main()\n\
56+ {\n\
57+ if(v_TexCoord.x < 0.0) { gl_FragColor = v_Color; return; }\n\
58+ gl_FragColor = texture2D(u_Atlas, v_TexCoord) * v_Color;\n\
59+ }\n";
60+
61+// TEXT
62+static const std::string textFragmentShader = "\n\
63+ varying vec2 v_TexCoord;\n\
64+ uniform vec4 u_Color;\n\
65+ uniform sampler2D u_Tex0;\n\
66+ void main()\n\
67+ {\n\
68+ gl_FragColor = texture2D(u_Tex0, v_TexCoord) * u_Color;\n\
69+ }\n";
70+
71+// LINE
72+static const std::string lineFragmentShader = "\n\
73+ uniform vec4 u_Color;\n\
74+ void main()\n\
75+ {\n\
76+ gl_FragColor = u_Color;\n\
77+ }\n";
78+
79+#endif
A RD_Client/src/framework/graphics/shaders/outfits.h +39-0 View file
@@ -0,0 +1,39 @@
1+#ifndef OUTFITS_H
2+#define OUTFITS_H
3+
4+static const std::string glslAdvancedOutfitVertexShader = "\n\
5+ attribute vec2 a_TexCoord;\n\
6+ attribute vec2 a_Vertex;\n\
7+ uniform mat3 u_TextureMatrix;\n\
8+ varying vec2 v_TexCoord;\n\
9+ varying vec2 v_TexCoord2;\n\
10+ varying vec2 v_TexCoord3;\n\
11+ uniform mat3 u_TransformMatrix;\n\
12+ uniform mat3 u_ProjectionMatrix;\n\
13+ uniform vec2 u_Offset;\n\
14+ uniform vec2 u_Resolution;\n\
15+ uniform float u_Depth;\n\
16+ void main()\n\
17+ {\n\
18+ gl_Position = vec4((u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy, 1.0)).xy, u_Depth / 16384.0, 1.0);\n\
19+ v_TexCoord = (u_TextureMatrix * vec3(a_TexCoord,1.0)).xy;\n\
20+ v_TexCoord2 = (u_TextureMatrix * vec3(a_TexCoord + u_Offset,1.0)).xy;\n\
21+ v_TexCoord3 = (u_TextureMatrix * vec3(u_Resolution,1.0)).xy;\n\
22+ }\n";
23+
24+static const std::string glslAdvancedOutfitFragmentShader = "\n\
25+ uniform float u_Depth;\n\
26+ uniform mat4 u_Color;\n\
27+ varying vec2 v_TexCoord;\n\
28+ varying vec2 v_TexCoord2;\n\
29+ uniform sampler2D u_Tex0;\n\
30+ uniform sampler2D u_Tex1;\n\
31+ void main()\n\
32+ {\n\
33+ gl_FragColor = texture2D(u_Tex0, v_TexCoord);\n\
34+ if(texture2D(u_Tex0, v_TexCoord2).a > 0.01)\n\
35+ gl_FragColor *= vec4(1.0, 1.0, 0.0, 1.0);\n\
36+ if(gl_FragColor.a < 0.01) discard;\n\
37+ }\n";
38+
39+#endif
A RD_Client/src/framework/graphics/shaders/shaders.h +8-0 View file
@@ -0,0 +1,8 @@
1+#ifndef SHADERS_H
2+#define SHADERS_H
3+
4+#include "newshader.h"
5+#include "shadersources.h"
6+#include "outfits.h"
7+
8+#endif
A RD_Client/src/framework/graphics/shaders/shadersources.h +123-0 View file
@@ -0,0 +1,123 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef PAINTEROGL2_SHADERSOURCES_H
24+#define PAINTEROGL2_SHADERSOURCES_H
25+
26+static const std::string glslMainVertexShader = "\n\
27+ vec4 calculatePosition();\n\
28+ void main() {\n\
29+ gl_Position = calculatePosition();\n\
30+ }\n";
31+
32+static const std::string glslMainWithTexCoordsVertexShader = "\n\
33+ attribute vec2 a_TexCoord;\n\
34+ uniform mat3 u_TextureMatrix;\n\
35+ varying vec2 v_TexCoord;\n\
36+ vec4 calculatePosition();\n\
37+ void main()\n\
38+ {\n\
39+ gl_Position = calculatePosition();\n\
40+ v_TexCoord = (u_TextureMatrix * vec3(a_TexCoord,1.0)).xy;\n\
41+ }\n";
42+
43+static std::string glslPositionOnlyVertexShader = "\n\
44+ attribute vec2 a_Vertex;\n\
45+ uniform mat3 u_TransformMatrix;\n\
46+ uniform mat3 u_ProjectionMatrix;\n\
47+ uniform float u_Depth;\n\
48+ vec4 calculatePosition() {\n\
49+ return vec4((u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy, 1.0)).xy, u_Depth / 16384.0, 1.0);\n\
50+ }\n";
51+
52+static const std::string glslMainFragmentShader = "\n\
53+ uniform float u_Depth;\n\
54+ vec4 calculatePixel();\n\
55+ void main()\n\
56+ {\n\
57+ gl_FragColor = calculatePixel();\n\
58+ if(gl_FragColor.a < 0.01 && u_Depth > 0.0)\n\
59+ discard;\n\
60+ }\n";
61+
62+static const std::string glslTextureSrcFragmentShader = "\n\
63+ varying vec2 v_TexCoord;\n\
64+ uniform vec4 u_Color;\n\
65+ uniform sampler2D u_Tex0;\n\
66+ vec4 calculatePixel() {\n\
67+ return texture2D(u_Tex0, v_TexCoord) * u_Color;\n\
68+ }\n";
69+
70+
71+static const std::string glslSolidColorFragmentShader = "\n\
72+ uniform vec4 u_Color;\n\
73+ vec4 calculatePixel() {\n\
74+ return u_Color;\n\
75+ }\n";
76+
77+static const std::string glslSolidColorOnTextureFragmentShader = "\n\
78+ uniform vec4 u_Color;\n\
79+ varying vec2 v_TexCoord;\n\
80+ uniform sampler2D u_Tex0;\n\
81+ vec4 calculatePixel() {\n\
82+ if(texture2D(u_Tex0, v_TexCoord).a > 0.01)\n\
83+ return u_Color;\n\
84+ return vec4(0,0,0,0);\n\
85+ }\n";
86+
87+
88+static const std::string glslOutfitVertexShader = "\n\
89+ attribute vec2 a_TexCoord;\n\
90+ uniform mat3 u_TextureMatrix;\n\
91+ varying vec2 v_TexCoord;\n\
92+ varying vec2 v_TexCoord2;\n\
93+ attribute vec2 a_Vertex;\n\
94+ uniform mat3 u_TransformMatrix;\n\
95+ uniform mat3 u_ProjectionMatrix;\n\
96+ uniform float u_Depth;\n\
97+ uniform vec2 u_Offset;\n\
98+ void main()\n\
99+ {\n\
100+ gl_Position = vec4((u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy, 1.0)).xy, u_Depth / 16384.0, 1.0);\n\
101+ v_TexCoord = (u_TextureMatrix * vec3(a_TexCoord,1.0)).xy;\n\
102+ v_TexCoord2 = (u_TextureMatrix * vec3(a_TexCoord + u_Offset,1.0)).xy;\n\
103+ }\n";
104+
105+static const std::string glslOutfitFragmentShader = "\n\
106+ uniform mat4 u_Color;\n\
107+ varying vec2 v_TexCoord;\n\
108+ varying vec2 v_TexCoord2;\n\
109+ uniform sampler2D u_Tex0;\n\
110+ void main()\n\
111+ {\n\
112+ gl_FragColor = texture2D(u_Tex0, v_TexCoord);\n\
113+ vec4 texcolor = texture2D(u_Tex0, v_TexCoord2);\n\
114+ if(texcolor.r > 0.9)\n\
115+ gl_FragColor *= texcolor.g > 0.9 ? u_Color[0] : u_Color[1];\n\
116+ else if(texcolor.g > 0.9)\n\
117+ gl_FragColor *= u_Color[2];\n\
118+ else if(texcolor.b > 0.9)\n\
119+ gl_FragColor *= u_Color[3];\n\
120+ if(gl_FragColor.a < 0.01) discard;\n\
121+ }\n";
122+
123+#endif
A RD_Client/src/framework/graphics/textrender.cpp +129-0 View file
@@ -0,0 +1,129 @@
1+#include "painter.h"
2+#include "textrender.h"
3+#include <framework/core/logger.h>
4+#include <framework/core/eventdispatcher.h>
5+
6+TextRender g_text;
7+
8+void TextRender::init()
9+{
10+
11+}
12+
13+void TextRender::terminate()
14+{
15+ for (auto& cache : m_cache) {
16+ cache.clear();
17+ }
18+}
19+
20+void TextRender::poll()
21+{
22+ static int iteration = 0;
23+ int index = (iteration++) % INDEXES;
24+ std::lock_guard<std::mutex> lock(m_mutex[index]);
25+ auto& cache = m_cache[index];
26+ if (cache.size() < 100)
27+ return;
28+
29+ ticks_t dropPoint = g_clock.millis();
30+ if (cache.size() > 500)
31+ dropPoint -= 10;
32+ else if (cache.size() > 250)
33+ dropPoint -= 100;
34+ else
35+ dropPoint -= 1000;
36+
37+ for (auto it = cache.begin(); it != cache.end(); ) {
38+ if (it->second->lastUse < dropPoint) {
39+ it = cache.erase(it);
40+ continue;
41+ }
42+ ++it;
43+ }
44+}
45+
46+uint64_t TextRender::addText(BitmapFontPtr font, const std::string& text, const Size& size, Fw::AlignmentFlag align)
47+{
48+ if (!font || text.empty() || !size.isValid())
49+ return 0;
50+ uint64_t hash = 1125899906842597ULL;
51+ for (size_t i = 0; i < text.length(); ++i) {
52+ hash = hash * 31 + text[i];
53+ }
54+ hash = hash * 31 + size.width();
55+ hash = hash * 31 + size.height();
56+ hash = hash * 31 + (uint64_t)align;
57+ hash = hash * 31 + (uint64_t)font->getId();
58+
59+ int index = hash % INDEXES;
60+ m_mutex[index].lock();
61+ auto it = m_cache[index].find(hash);
62+ if (it == m_cache[index].end()) {
63+ m_cache[index][hash] = std::shared_ptr<TextRenderCache>(new TextRenderCache{ font, text, size, align, font->getTexture(), CoordsBuffer(), g_clock.millis() });
64+ }
65+ m_mutex[index].unlock();
66+ return hash;
67+}
68+
69+void TextRender::drawText(const Rect& rect, const std::string& text, BitmapFontPtr font, const Color& color, Fw::AlignmentFlag align, bool shadow)
70+{
71+ VALIDATE_GRAPHICS_THREAD();
72+ uint64_t hash = addText(font, text, rect.size(), align);
73+ drawText(rect.topLeft(), hash, color, shadow);
74+}
75+
76+void TextRender::drawText(const Point& pos, uint64_t hash, const Color& color, bool shadow)
77+{
78+ VALIDATE_GRAPHICS_THREAD();
79+ int index = hash % INDEXES;
80+ m_mutex[index].lock();
81+ auto _it = m_cache[index].find(hash);
82+ if (_it == m_cache[index].end()) {
83+ m_mutex[index].unlock();
84+ return;
85+ }
86+ auto it = _it->second;
87+ it->lastUse = g_clock.millis();
88+ m_mutex[index].unlock();
89+ if (it->font) { // calculate text coords
90+ it->font->calculateDrawTextCoords(it->coords, it->text, Rect(0, 0, it->size), it->align);
91+ it->coords.cache();
92+ it->text.clear();
93+ it->font.reset();
94+ }
95+
96+ if (shadow) {
97+ auto shadowPos = Point(pos);
98+ shadowPos.x += 1;
99+ shadowPos.y += 1;
100+ g_painter->drawText(shadowPos, it->coords, Color::black, it->texture);
101+ }
102+
103+ g_painter->drawText(pos, it->coords, color, it->texture);
104+}
105+
106+void TextRender::drawColoredText(const Point& pos, uint64_t hash, const std::vector<std::pair<int, Color>>& colors, bool shadow)
107+{
108+ VALIDATE_GRAPHICS_THREAD();
109+ if (colors.empty())
110+ return drawText(pos, hash, Color::white);
111+ int index = hash % INDEXES;
112+ m_mutex[index].lock();
113+ auto _it = m_cache[index].find(hash);
114+ if (_it == m_cache[index].end()) {
115+ m_mutex[index].unlock();
116+ return;
117+ }
118+ auto it = _it->second;
119+ it->lastUse = g_clock.millis();
120+ m_mutex[index].unlock();
121+ if (it->font) { // calculate text coords
122+ it->font->calculateDrawTextCoords(it->coords, it->text, Rect(0, 0, it->size), it->align);
123+ it->coords.cache();
124+ it->text.clear();
125+ it->font.reset();
126+ }
127+ g_painter->drawText(pos, it->coords, colors, it->texture);
128+}
129+
A RD_Client/src/framework/graphics/textrender.h +39-0 View file
@@ -0,0 +1,39 @@
1+#ifndef TEXTRENDER_H
2+#define TEXTRENDER_H
3+
4+#include <map>
5+#include <mutex>
6+#include "bitmapfont.h"
7+#include "coordsbuffer.h"
8+#include <framework/core/clock.h>
9+
10+struct TextRenderCache {
11+ BitmapFontPtr font;
12+ std::string text;
13+ Size size;
14+ Fw::AlignmentFlag align;
15+ TexturePtr texture;
16+ CoordsBuffer coords;
17+ ticks_t lastUse;
18+};
19+
20+class TextRender
21+{
22+ static const int INDEXES = 10;
23+public:
24+ void init();
25+ void terminate();
26+ void poll();
27+ uint64_t addText(BitmapFontPtr font, const std::string& text, const Size& size, Fw::AlignmentFlag align = Fw::AlignTopLeft);
28+ void drawText(const Rect& rect, const std::string& text, BitmapFontPtr font, const Color& color = Color::white, Fw::AlignmentFlag align = Fw::AlignTopLeft, bool shadow = false);
29+ void drawText(const Point& pos, uint64_t hash, const Color& color, bool shadow = false);
30+ void drawColoredText(const Point& pos, uint64_t hash, const std::vector<std::pair<int, Color>>& colors, bool shadow = false);
31+
32+private:
33+ std::map<uint64_t, std::shared_ptr<TextRenderCache>> m_cache[INDEXES];
34+ std::mutex m_mutex[INDEXES];
35+};
36+
37+extern TextRender g_text;
38+
39+#endif
Top