mirror of https://github.com/bsnes-emu/bsnes.git
88 lines
3.1 KiB
C++
88 lines
3.1 KiB
C++
void OpenGLProgram::bind(OpenGL* instance, const Markup::Node& node, const string& pathname) {
|
|
filter = glrFilter(node["filter"].text());
|
|
wrap = glrWrap(node["wrap"].text());
|
|
modulo = glrModulo(node["modulo"].integer());
|
|
|
|
string w = node["width"].text(), h = node["height"].text();
|
|
if(w.endswith("%")) relativeWidth = real(w.rtrim<1>("%")) / 100.0;
|
|
else absoluteWidth = decimal(w);
|
|
if(h.endswith("%")) relativeHeight = real(h.rtrim<1>("%")) / 100.0;
|
|
else absoluteHeight = decimal(h);
|
|
|
|
if(node.name != "program") return;
|
|
format = glrFormat(node["format"].text());
|
|
|
|
program = glCreateProgram();
|
|
glGenFramebuffers(1, &framebuffer);
|
|
|
|
if(file::exists({pathname, node["vertex"].text()})) {
|
|
string source = file::read({pathname, node["vertex"].text()});
|
|
vertex = glrCreateShader(program, GL_VERTEX_SHADER, source);
|
|
} else {
|
|
vertex = glrCreateShader(program, GL_VERTEX_SHADER, OpenGLVertexShader);
|
|
}
|
|
|
|
if(file::exists({pathname, node["geometry"].text()})) {
|
|
string source = file::read({pathname, node["geometry"].text()});
|
|
geometry = glrCreateShader(program, GL_GEOMETRY_SHADER, source);
|
|
} else {
|
|
//geometry shaders, when attached, must pass all vertex output through to the fragment shaders
|
|
//geometry = glrCreateShader(program, GL_GEOMETRY_SHADER, OpenGLGeometryShader);
|
|
}
|
|
|
|
if(file::exists({pathname, node["fragment"].text()})) {
|
|
string source = file::read({pathname, node["fragment"].text()});
|
|
fragment = glrCreateShader(program, GL_FRAGMENT_SHADER, source);
|
|
} else {
|
|
fragment = glrCreateShader(program, GL_FRAGMENT_SHADER, OpenGLFragmentShader);
|
|
}
|
|
|
|
for(auto& leaf : node.find("pixmap")) {
|
|
nall::image image({pathname, leaf.text()});
|
|
image.transform(0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0);
|
|
if(image.empty()) continue;
|
|
|
|
GLuint texture;
|
|
glGenTextures(1, &texture);
|
|
|
|
unsigned n = pixmaps.size();
|
|
pixmaps(n).texture = texture;
|
|
pixmaps(n).width = image.width;
|
|
pixmaps(n).height = image.height;
|
|
pixmaps(n).format = format;
|
|
pixmaps(n).filter = filter;
|
|
pixmaps(n).wrap = wrap;
|
|
if(leaf["format"].exists()) pixmaps(n).format = glrFormat(leaf["format"].text());
|
|
if(leaf["filter"].exists()) pixmaps(n).filter = glrFilter(leaf["filter"].text());
|
|
if(leaf["wrap"].exists()) pixmaps(n).wrap = glrWrap(leaf["wrap"].text());
|
|
|
|
unsigned w = glrSize(image.width), h = glrSize(image.height);
|
|
uint32_t* buffer = new uint32_t[w * h]();
|
|
glBindTexture(GL_TEXTURE_2D, texture);
|
|
glTexImage2D(GL_TEXTURE_2D, 0, pixmaps(n).format, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image.width, image.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image.data);
|
|
delete[] buffer;
|
|
}
|
|
|
|
OpenGLSurface::allocate();
|
|
glrLinkProgram(program);
|
|
}
|
|
|
|
void OpenGLProgram::release() {
|
|
OpenGLSurface::release();
|
|
for(auto& pixmap : pixmaps) glDeleteTextures(1, &pixmap.texture);
|
|
pixmaps.reset();
|
|
|
|
width = 0;
|
|
height = 0;
|
|
format = GL_RGBA8;
|
|
filter = GL_LINEAR;
|
|
wrap = GL_CLAMP_TO_BORDER;
|
|
phase = 0;
|
|
modulo = 0;
|
|
absoluteWidth = 0;
|
|
absoluteHeight = 0;
|
|
relativeWidth = 0;
|
|
relativeHeight = 0;
|
|
}
|