got framebuffer objects functional with texture and renderbuffer attachments

This commit is contained in:
rexy712 2020-09-27 16:50:17 -07:00
parent fe31a9568f
commit b3c909a93a
6 changed files with 116 additions and 28 deletions

View File

@ -48,6 +48,7 @@ namespace gfx{
bool attach(const texture& tex, GLenum point);
bool attach(const rbo& r, GLenum point);
bool bind()const;
bool bind(gl_frame_buffer& b)const;
bool bind_lock(gl_frame_buffer& b)const;
void bind_unlock(gl_frame_buffer& b)const;

View File

@ -58,6 +58,7 @@ namespace gfx{
public:
//create the texture with no image data
texture();
texture(GLenum format, GLsizei w, GLsizei h, GLenum type);
//create the texture with image data from 'i'
texture(const image& i);
//TODO image data from raw unsigned char array
@ -72,6 +73,7 @@ namespace gfx{
//overwrite the current image data with 'i'
bool set_image(const image& i);
void resize(GLenum format, GLsizei w, GLsizei h, GLenum type);
//set the size of the texture, will wrap the image according to the chosen wrap mode
void set_width(int w);

View File

@ -49,16 +49,21 @@ namespace gfx{
bool fbo::attach(const texture& tex, GLenum point){
if(!bind(framebuffer::draw))
return false;
tex.bind();
glFramebufferTexture2D(m_draw.get_bound_id(), point, GL_TEXTURE_2D, tex.raw(), 0);
return true;
}
bool fbo::attach(const rbo& r, GLenum point){
if(!bind(framebuffer::draw))
return false;
r.bind();
glFramebufferRenderbuffer(m_draw.get_bound_id(), point, GL_RENDERBUFFER, r.raw());
return true;
}
bool fbo::bind()const{
return (bind(framebuffer::draw) && bind(framebuffer::read));
}
bool fbo::bind(gl_frame_buffer& b)const{
if(GL_DRAW_FRAMEBUFFER == b.get_buffer_id()){
if(!m_draw.bind(b))

View File

@ -503,6 +503,7 @@ namespace gfx{
set_uniform(get_uniform_loc(name), t, tex_unit);
}
void shader_program::set_uniform(GLuint loc, const texture& t, GLuint tex_unit){
use();
t.use(tex_unit, loc);
}

View File

@ -25,6 +25,12 @@ namespace gfx{
texture::texture(){
glGenTextures(1, &m_tex_id);
}
texture::texture(GLenum format, GLsizei w, GLsizei h, GLenum type):
m_width(w), m_height(h)
{
glGenTextures(1, &m_tex_id);
resize(format, w, h, type);
}
texture::texture(const image& i):
texture()
{
@ -72,6 +78,11 @@ namespace gfx{
glGenerateMipmap(GL_TEXTURE_2D);
return true;
}
void texture::resize(GLenum format, GLsizei w, GLsizei h, GLenum type){
bind();
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, type, NULL);
glGenerateMipmap(GL_TEXTURE_2D);
}
void texture::set_width(int w){
m_width = w;

View File

@ -20,6 +20,7 @@
#include "graphics/vbo.hpp"
#include "graphics/shader.hpp"
#include "graphics/shader_program.hpp"
#include "graphics/fbo.hpp"
#include "engine/camera.hpp"
@ -136,14 +137,6 @@ std::string select_audio_file(){
return {};
}
void gay_thread(sfx::mixer& m, std::atomic_bool& should_gay_thread_stop){
while(!should_gay_thread_stop){
sfx::mixchunk ch = read_audio_file(select_audio_file().c_str());
m.get_channel(0).play(ch);
std::this_thread::sleep_for(std::chrono::seconds(3));
}
}
gfx::shader_program create_example_shader(){
static constexpr const char vertex_source[] = "#version 330 core\n"
"layout (location = 0) in vec3 position;"
@ -199,6 +192,48 @@ gfx::shader_program create_example_shader(){
}
return prog;
}
gfx::shader_program create_screen_shader(){
static constexpr const char vertex_source[] = "#version 330 core\n"
"layout (location = 0) in vec2 position;"
"layout (location = 1) in vec2 tex_coords;"
"out vec2 frag_tex_coords;"
"void main(){"
"gl_Position = vec4(position, -1.0, 1.0);"
"frag_tex_coords = tex_coords;"
"}";
static constexpr const char fragment_source[] = "#version 330 core\n"
"out vec4 FragColor;"
"in vec2 frag_tex_coords;"
"uniform sampler2D fbtexture;"
"void main(){"
"FragColor = mix(vec4(1,0,0,1),texture(fbtexture, frag_tex_coords), 0.8);"
"}";
gfx::shader_program prog;
gfx::shader vert(vertex_source, gfx::shader::type::VERTEX);
gfx::shader frag(fragment_source, gfx::shader::type::FRAGMENT);
bool error = false;
if(vert.has_compile_error()){
debug_print_error("%s\n", vert.get_error().c_str());
error = true;
}
if(frag.has_compile_error()){
debug_print_error("%s\n", frag.get_error().c_str());
error = true;
}
if(error)
return prog;
prog.attach_shaders(vert, frag);
prog.link();
if(prog.has_link_error()){
debug_print_error("%s\n", prog.get_error().c_str());
}
return prog;
}
class grid
{
@ -233,7 +268,7 @@ public:
int main(){
const grid g;
egn::ortho_camera cam(10, 10, 1, 100);
egn::ortho_camera cam(5, 5, 1, 100);
srand(time(NULL));
game_state gs = {};
@ -243,46 +278,79 @@ int main(){
manager.handle_window_close_event(handle_window_close);
manager.handle_keypress_event(handle_input_events);
//audio testing thread setup
sfx::mixer mix(sfx::mixer::mode::STEREO, 1, 44100);
std::atomic_bool should_gay_thread_stop = false;
std::thread t(gay_thread, std::ref(mix), std::ref(should_gay_thread_stop));
//fbo setup
gfx::fbo fbo;
gfx::rbo rbo(640, 480, GL_DEPTH24_STENCIL8);
gfx::texture tex(GL_RGB, 640, 480, GL_UNSIGNED_BYTE);
fbo.attach(rbo, GL_DEPTH_STENCIL_ATTACHMENT);
fbo.attach(tex, GL_COLOR_ATTACHMENT0);
glClearColor(0, 0, 0, 1);
fbo.unbind();
//create our gl objects
gfx::vbo vbo(sizeof(GLfloat) * sizeof(27), gfx::vbo::usage::STATIC_DRAW);
gfx::shader_program prog = create_example_shader();
gfx::vao vao;
//create our gl objects for rendering to the fbo
gfx::vbo normal_vbo(sizeof(GLfloat) * 27, gfx::vbo::usage::STATIC_DRAW);
gfx::shader_program normal_shader = create_example_shader();
gfx::vao normal_vao;
//add our view-projection matrix in the glsl uniform variable
prog.set_uniform("vp_mat", cam.get_projection_matrix()*cam.get_view_matrix());
auto mat = prog.get_uniform_mat4("vp_mat");
math::dump_matrix(mat);
normal_shader.set_uniform("vp_mat", cam.get_projection_matrix()*cam.get_view_matrix());
//put the grid square positions
for(size_t i = 0;i < 3;++i){
for(size_t j = 0;j < 3;++j){
vbo.buffer(g[i][j], sizeof(GLfloat) * 3);
normal_vbo.buffer(g[i][j], sizeof(GLfloat) * 3);
}
}
//tell gl how to interpret the data in the vbo
vao.bind();
vbo.bind(gfx::buffer::array);
auto attrib = vao.get_attribute(0);
normal_vao.bind();
normal_vbo.bind(gfx::buffer::array);
auto attrib = normal_vao.get_attribute(0);
attrib.set_float_pointer(3, 3, 0);
attrib.enable_array_mode();
constexpr GLfloat square_coords[] = {
-1, 1, 0, 1,
-1, -1, 0, 0,
1, -1, 1, 0,
1, -1, 1, 0,
1, 1, 1, 1,
-1, 1, 0, 1
};
gfx::vbo screen_vbo(sizeof(square_coords), gfx::vbo::usage::STATIC_DRAW);
gfx::shader_program screen_shader = create_screen_shader();
gfx::vao screen_vao;
screen_vbo.buffer(square_coords, sizeof(square_coords));
screen_vao.bind();
screen_vbo.bind(gfx::buffer::array);
attrib = screen_vao.get_attribute(0);
attrib.set_float_pointer(2, 4, 0);
attrib.enable_array_mode();
attrib = screen_vao.get_attribute(1);
attrib.set_float_pointer(2, 4, 2);
attrib.enable_array_mode();
while(!manager.should_close()){
//render using program 'prog' with data from 'vao'
prog.use();
vao.bind();
fbo.bind();
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
normal_shader.use();
normal_vao.bind();
glDrawArrays(GL_POINTS, 0, 9);
fbo.unbind();
glDisable(GL_DEPTH_TEST);
screen_shader.use();
screen_shader.set_uniform("fbtexture", tex, 0);
screen_vao.bind();
glDrawArrays(GL_TRIANGLES, 0, 6);
manager.update();
}
should_gay_thread_stop = true;
while(exists_empty_tile(gs) && gs.turn != -1){
game_turn(gs, get_player_input());
}
t.join();
}