138 lines
4.3 KiB
C++
138 lines
4.3 KiB
C++
#include "gl_framebuffer.h"
|
|
#include "main/logging.h"
|
|
#include "main/references.h"
|
|
|
|
namespace render {
|
|
|
|
class DummyTexture : public Texture {
|
|
GLuint glName;
|
|
public:
|
|
DummyTexture(GLuint name) : glName(name) {
|
|
type = TT_2D;
|
|
hasMipMaps = false;
|
|
loaded = true;
|
|
}
|
|
|
|
virtual bool isPixelActive(vec2i px) const { return false; }
|
|
|
|
virtual void loadStart(Image& image, bool mipmap = true, bool cachePixels = false, unsigned lod = 0) {}
|
|
virtual void loadPartial(Image& image, const recti& pixels, bool cachePixels = false, unsigned lod = 0) {}
|
|
virtual void loadFinish(bool mipmap, unsigned lod = 0) {}
|
|
|
|
virtual void load(Image& image, bool mipmap = true, bool cachePixels = false) {}
|
|
virtual void save(Image& image) const {}
|
|
virtual void bind() { glBindTexture(GL_TEXTURE_2D, glName); }
|
|
virtual unsigned getID() const { return glName; }
|
|
|
|
virtual unsigned getTextureBytes() const { return 0; }
|
|
};
|
|
|
|
glFrameBuffer::glFrameBuffer(const vec2i& Size) {
|
|
devices.render->reportErrors();
|
|
|
|
type = TT_2D;
|
|
loaded = true;
|
|
|
|
size = Size;
|
|
hasMipMaps = false;
|
|
glGenFramebuffers(1, &buffer);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, buffer);
|
|
prevRenderState.filterMin = TF_Nearest;
|
|
prevRenderState.filterMag = TF_Nearest;
|
|
|
|
textures = new GLuint[2];
|
|
glGenTextures(2, textures);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, textures[0]);
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Size.width, Size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, textures[1]);
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, Size.width, Size.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
devices.render->reportErrors("setting framebuffer parameters");
|
|
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
|
|
|
|
devices.render->reportErrors("creating framebuffer color attachment");
|
|
|
|
renderBuffers = new GLuint[1];
|
|
//glGenRenderbuffers(1, renderBuffers);
|
|
//glBindRenderbuffer(GL_RENDERBUFFER, renderBuffers[0]);
|
|
//glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, Size.width, Size.height);
|
|
//glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
|
|
|
//glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffers[0]);
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, textures[1], 0);
|
|
|
|
depthTexture = new DummyTexture(textures[1]);
|
|
|
|
devices.render->reportErrors("creating framebuffer depth attachment");
|
|
|
|
auto state = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
|
if(state != GL_FRAMEBUFFER_COMPLETE)
|
|
error("Incomplete framebuffer: %d", state);
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
}
|
|
|
|
glFrameBuffer::~glFrameBuffer() {
|
|
glDeleteFramebuffers(1, &buffer);
|
|
glDeleteTextures(2, textures); delete[] textures;
|
|
//glDeleteRenderbuffers(1, renderBuffers);
|
|
delete[] renderBuffers;
|
|
delete depthTexture;
|
|
}
|
|
|
|
void glFrameBuffer::bind() {
|
|
glBindTexture(GL_TEXTURE_2D, textures[0]);
|
|
}
|
|
|
|
unsigned glFrameBuffer::getID() const {
|
|
return textures[0];
|
|
}
|
|
|
|
void glFrameBuffer::setAsTarget() {
|
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer);
|
|
glViewport(0,0,size.width, size.height);
|
|
}
|
|
|
|
void glFrameBuffer::save(Image& image) const {
|
|
image.resize(size.width, size.height, FMT_RGB);
|
|
glBindTexture(GL_TEXTURE_2D, textures[0]);
|
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, image.rgb);
|
|
}
|
|
|
|
void glFrameBuffer::load(Image& img, bool mipmap, bool cachePixels) {
|
|
throw "Cannot load framebuffer from image.";
|
|
}
|
|
|
|
void glFrameBuffer::loadStart(Image& image, bool mipmap, bool cachePixels, unsigned lod) {
|
|
throw "Cannot load framebuffer from image.";
|
|
}
|
|
|
|
void glFrameBuffer::loadPartial(Image& image, const recti& pixels, bool cachePixels, unsigned lod) {
|
|
throw "Cannot load framebuffer from image.";
|
|
}
|
|
|
|
void glFrameBuffer::loadFinish(bool mipmap, unsigned lod) {
|
|
throw "Cannot load framebuffer from image.";
|
|
}
|
|
|
|
bool glFrameBuffer::isPixelActive(vec2i px) const {
|
|
throw "Cannot get framebuffer pixels.";
|
|
}
|
|
|
|
unsigned glFrameBuffer::getTextureBytes() const {
|
|
//4 bytes for RGBA, 3 bytes for 24 bit z buffer
|
|
return size.width * size.height * 7;
|
|
}
|
|
|
|
};
|