Skip to content

Commit c12cc9a

Browse files
committed
render: opengl: support filter in opengl mode
1 parent eb09206 commit c12cc9a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+14787
-17
lines changed

CMakeLists.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ add_subdirectory(ext/png)
166166
add_subdirectory(ext/expat)
167167
add_subdirectory(ext/mujs)
168168
add_subdirectory(ext/lame)
169+
add_subdirectory(ext/gpupixel)
169170

170171
file(GLOB PLATFORM_FILES ${PROJECT_SOURCE_DIR}/src/platform/*.cpp)
171172
file(GLOB CONFIG_FILES ${PROJECT_SOURCE_DIR}/src/config/*.cpp)
@@ -472,6 +473,7 @@ include_directories(${EXTPNG_INCLUDE_DIR})
472473
include_directories(${EXTMUJS_INCLUDE_DIR})
473474
include_directories(${CMRC_INCLUDE_DIR})
474475
include_directories(${EXTLAME_INCLUDE_DIR})
476+
include_directories(${GPUPIXEL_INCLUDE_DIR})
475477

476478
include_directories(ext)
477479
include_directories(src)
@@ -491,7 +493,7 @@ endif()
491493
target_link_libraries (${GAME}
492494
${SDL2_LIBRARY} ${SDL2_MIXER_LIBRARY} ${EXTMUJS_LIBRARY}
493495
${EXTEXPAT_LIBRARY} ${EXTPNG_LIBRARY} ${CPPTRACE_LIBRARY}
494-
${EXTLAME_LIBRARY} akhenaten::rc)
496+
${EXTLAME_LIBRARY} ${GPUPIXEL_LIBRARY} akhenaten::rc)
495497

496498
if(MSVC)
497499
target_link_libraries(${GAME} "winmm" "imagehlp" "shlwapi")

ext/gpupixel/CMakeLists.txt

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
cmake_minimum_required(VERSION 3.0)
2+
project(gpupixel CXX)
3+
4+
file(GLOB CORE_FILES ${PROJECT_SOURCE_DIR}/core/*.cc)
5+
file(GLOB FILTER_FILES ${PROJECT_SOURCE_DIR}/filter/*.cc)
6+
file(GLOB SOURCE_FILES ${PROJECT_SOURCE_DIR}/source/*.cc)
7+
file(GLOB TARGET_FILES ${PROJECT_SOURCE_DIR}/target/*.cc)
8+
file(GLOB UTILS_FILES ${PROJECT_SOURCE_DIR}/utils/*.cc)
9+
10+
set(SOURCES_LIST
11+
${CORE_FILES}
12+
${FILTER_FILES}
13+
${SOURCE_FILES}
14+
${TARGET_FILES}
15+
${UTILS_FILES}
16+
)
17+
18+
if (MSVC)
19+
20+
elseif()
21+
add_compile_definitions("-Wno-absolute-value")
22+
endif()
23+
24+
add_library(${PROJECT_NAME} ${SOURCES_LIST})
25+
26+
set(GPUPIXEL_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/core
27+
CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE)
28+
29+
set(GPUPIXEL_LIBRARY ${PROJECT_NAME}
30+
CACHE INTERNAL "${PROJECT_NAME}: Library Name" FORCE)

ext/gpupixel/core/framebuffer.cc

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* GPUPixel
3+
*
4+
* Created by PixPark on 2021/6/24.
5+
* Copyright © 2021 PixPark. All rights reserved.
6+
*/
7+
8+
#include <assert.h>
9+
#include <algorithm>
10+
11+
#include "framebuffer.h"
12+
#include "gpupixel_context.h"
13+
#include "../utils/util.h"
14+
15+
NS_GPUPIXEL_BEGIN
16+
17+
TextureAttributes Framebuffer::defaultTextureAttribures = {
18+
GL_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE,
19+
GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE
20+
};
21+
22+
Framebuffer::Framebuffer(int width, int height, bool onlyGenerateTexture /* = false*/, const TextureAttributes textureAttributes /* = defaultTextureAttribures*/) : _texture(-1), _framebuffer(-1) {
23+
_width = width;
24+
_height = height;
25+
_textureAttributes = textureAttributes;
26+
_hasFB = !onlyGenerateTexture;
27+
28+
if (_hasFB) {
29+
_generateFramebuffer();
30+
} else {
31+
_generateTexture();
32+
}
33+
}
34+
35+
Framebuffer::~Framebuffer() {
36+
gpupixel::GPUPixelContext::getInstance()->runSync([&] {
37+
bool bDeleteTex = (_texture != -1);
38+
bool bDeleteFB = (_framebuffer != -1);
39+
40+
if (bDeleteTex) {
41+
CHECK_GL(glDeleteTextures(1, &_texture));
42+
_texture = -1;
43+
}
44+
45+
if (bDeleteFB) {
46+
CHECK_GL(glDeleteFramebuffers(1, &_framebuffer));
47+
_framebuffer = -1;
48+
}
49+
});
50+
}
51+
52+
void Framebuffer::active() {
53+
CHECK_GL(glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer));
54+
CHECK_GL(glViewport(0, 0, _width, _height));
55+
}
56+
57+
void Framebuffer::inactive() {
58+
CHECK_GL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
59+
}
60+
61+
void Framebuffer::_generateTexture() {
62+
CHECK_GL(glGenTextures(1, &_texture));
63+
CHECK_GL(glBindTexture(GL_TEXTURE_2D, _texture));
64+
CHECK_GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _textureAttributes.minFilter));
65+
CHECK_GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _textureAttributes.magFilter));
66+
CHECK_GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _textureAttributes.wrapS));
67+
CHECK_GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _textureAttributes.wrapT));
68+
69+
// TODO: Handle mipmaps
70+
CHECK_GL(glBindTexture(GL_TEXTURE_2D, 0));
71+
}
72+
73+
void Framebuffer::_generateFramebuffer() {
74+
CHECK_GL(glGenFramebuffers(1, &_framebuffer));
75+
CHECK_GL(glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer));
76+
77+
_generateTexture();
78+
79+
CHECK_GL(glBindTexture(GL_TEXTURE_2D, _texture));
80+
CHECK_GL(glTexImage2D(GL_TEXTURE_2D, 0, _textureAttributes.internalFormat, _width, _height, 0, _textureAttributes.format, _textureAttributes.type, 0));
81+
CHECK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0));
82+
CHECK_GL(glBindTexture(GL_TEXTURE_2D, 0));
83+
CHECK_GL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
84+
}
85+
86+
NS_GPUPIXEL_END

ext/gpupixel/core/framebuffer.h

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#pragma once
2+
3+
#include "gpupixel_macros.h"
4+
5+
NS_GPUPIXEL_BEGIN
6+
7+
typedef struct {
8+
GLenum minFilter;
9+
GLenum magFilter;
10+
GLenum wrapS;
11+
GLenum wrapT;
12+
GLenum internalFormat;
13+
GLenum format;
14+
GLenum type;
15+
} TextureAttributes;
16+
17+
class Framebuffer;
18+
using FramebufferPtr = std::shared_ptr<Framebuffer>;
19+
20+
class Framebuffer {
21+
public:
22+
Framebuffer(int width, int height, bool onlyGenerateTexture = false, const TextureAttributes textureAttributes = defaultTextureAttribures);
23+
~Framebuffer();
24+
25+
GLuint getTexture() const { return _texture; }
26+
GLuint getFramebuffer() const { return _framebuffer; }
27+
28+
int getWidth() const { return _width; }
29+
int getHeight() const { return _height; }
30+
const TextureAttributes &getTextureAttributes() const { return _textureAttributes; };
31+
bool hasFramebuffer() { return _hasFB; };
32+
33+
void active();
34+
void inactive();
35+
36+
static TextureAttributes defaultTextureAttribures;
37+
38+
private:
39+
int _width, _height;
40+
TextureAttributes _textureAttributes;
41+
bool _hasFB;
42+
GLuint _texture;
43+
GLuint _framebuffer;
44+
45+
void _generateTexture();
46+
void _generateFramebuffer();
47+
};
48+
49+
NS_GPUPIXEL_END
+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* GPUPixel
3+
*
4+
* Created by PixPark on 2021/6/24.
5+
* Copyright © 2021 PixPark. All rights reserved.
6+
*/
7+
8+
#include "framebuffer_cache.h"
9+
#include "../utils/util.h"
10+
11+
NS_GPUPIXEL_BEGIN
12+
13+
FramebufferCache::FramebufferCache() {}
14+
15+
FramebufferCache::~FramebufferCache() {
16+
purge();
17+
}
18+
19+
std::shared_ptr<Framebuffer> FramebufferCache::fetchFramebuffer(int width, int height, bool onlyTexture /* = false*/, const TextureAttributes textureAttributes /* = defaultTextureAttribure*/) {
20+
std::shared_ptr<Framebuffer> framebufferFromCache;
21+
std::string lookupHash = _getHash(width, height, onlyTexture, textureAttributes);
22+
int numberOfMatchingFramebuffers = 0;
23+
24+
if (_framebufferTypeCounts.find(lookupHash) != _framebufferTypeCounts.end()) {
25+
numberOfMatchingFramebuffers = _framebufferTypeCounts[lookupHash];
26+
}
27+
if (numberOfMatchingFramebuffers < 1) {
28+
framebufferFromCache = std::shared_ptr<Framebuffer>(new Framebuffer(width, height, onlyTexture, textureAttributes));
29+
} else {
30+
int curFramebufferId = numberOfMatchingFramebuffers - 1;
31+
while (!framebufferFromCache && curFramebufferId >= 0) {
32+
std::string framebufferHash = Util::str_format("%s-%ld", lookupHash.c_str(), curFramebufferId);
33+
if (_framebuffers.find(framebufferHash) != _framebuffers.end()) {
34+
framebufferFromCache = _framebuffers[framebufferHash];
35+
_framebuffers.erase(framebufferHash);
36+
} else {
37+
framebufferFromCache = 0;
38+
}
39+
curFramebufferId--;
40+
}
41+
42+
curFramebufferId++;
43+
_framebufferTypeCounts[lookupHash] = curFramebufferId;
44+
45+
if (!framebufferFromCache) {
46+
framebufferFromCache = std::shared_ptr<Framebuffer>(new Framebuffer(width, height, onlyTexture, textureAttributes));
47+
}
48+
}
49+
50+
return framebufferFromCache;
51+
}
52+
53+
void FramebufferCache::returnFramebuffer(std::shared_ptr<Framebuffer> framebuffer) {
54+
if (framebuffer == 0) {
55+
return;
56+
}
57+
58+
int width = framebuffer->getWidth();
59+
int height = framebuffer->getHeight();
60+
const TextureAttributes &textureAttributes = framebuffer->getTextureAttributes();
61+
std::string lookupHash = _getHash(width, height, !framebuffer->hasFramebuffer(), textureAttributes);
62+
int numberOfMatchingFramebuffers = 0;
63+
if (_framebufferTypeCounts.find(lookupHash) != _framebufferTypeCounts.end()) {
64+
numberOfMatchingFramebuffers = _framebufferTypeCounts[lookupHash];
65+
}
66+
std::string framebufferHash = Util::str_format("%s-%ld", lookupHash.c_str(),
67+
numberOfMatchingFramebuffers);
68+
_framebuffers[framebufferHash] = framebuffer;
69+
_framebufferTypeCounts[lookupHash] = numberOfMatchingFramebuffers + 1;
70+
}
71+
72+
std::string FramebufferCache::_getHash(int width, int height, bool onlyTexture, const TextureAttributes textureAttributes) const {
73+
if (onlyTexture) {
74+
return Util::str_format("%.1dx%.1d-%d:%d:%d:%d:%d:%d:%d-NOFB", width,
75+
height, textureAttributes.minFilter,
76+
textureAttributes.magFilter,
77+
textureAttributes.wrapS, textureAttributes.wrapT,
78+
textureAttributes.internalFormat,
79+
textureAttributes.format, textureAttributes.type);
80+
} else {
81+
return Util::str_format("%.1dx%.1d-%d:%d:%d:%d:%d:%d:%d", width, height,
82+
textureAttributes.minFilter,
83+
textureAttributes.magFilter,
84+
textureAttributes.wrapS, textureAttributes.wrapT,
85+
textureAttributes.internalFormat,
86+
textureAttributes.format, textureAttributes.type);
87+
}
88+
}
89+
90+
std::shared_ptr<Framebuffer> FramebufferCache::_getFramebufferByHash(
91+
const std::string &hash) {
92+
return _framebuffers[hash];
93+
}
94+
95+
void FramebufferCache::purge() {
96+
_framebuffers.clear();
97+
_framebufferTypeCounts.clear();
98+
}
99+
100+
NS_GPUPIXEL_END

ext/gpupixel/core/framebuffer_cache.h

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* GPUPixel
3+
*
4+
* Created by PixPark on 2021/6/24.
5+
* Copyright © 2021 PixPark. All rights reserved.
6+
*/
7+
8+
#pragma once
9+
10+
#include <map>
11+
#include <string>
12+
#include "framebuffer.h"
13+
#include "gpupixel_macros.h"
14+
15+
NS_GPUPIXEL_BEGIN
16+
17+
class FramebufferCache {
18+
public:
19+
FramebufferCache();
20+
~FramebufferCache();
21+
std::shared_ptr<Framebuffer> fetchFramebuffer(int width, int height, bool onlyTexture = false, const TextureAttributes textureAttributes = Framebuffer::defaultTextureAttribures);
22+
void returnFramebuffer(std::shared_ptr<Framebuffer> framebuffer);
23+
void purge();
24+
25+
private:
26+
std::string _getHash(int width, int height, bool onlyTexture, const TextureAttributes textureAttributes) const;
27+
std::shared_ptr<Framebuffer> _getFramebufferByHash(const std::string& hash);
28+
29+
std::map<std::string, std::shared_ptr<Framebuffer>> _framebuffers;
30+
std::map<std::string, int> _framebufferTypeCounts;
31+
};
32+
33+
NS_GPUPIXEL_END

0 commit comments

Comments
 (0)