mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 20:59:19 +02:00
TMP
This commit is contained in:
@@ -86,6 +86,7 @@ set(SOURCES
|
|||||||
"gl/ubo.cpp"
|
"gl/ubo.cpp"
|
||||||
"gl/framebuffer.cpp"
|
"gl/framebuffer.cpp"
|
||||||
"gl/renderbuffer.cpp"
|
"gl/renderbuffer.cpp"
|
||||||
|
"gl/postfx.cpp"
|
||||||
|
|
||||||
"imgui/imgui.cpp"
|
"imgui/imgui.cpp"
|
||||||
"imgui/imgui_demo.cpp"
|
"imgui/imgui_demo.cpp"
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ TextureTest( std::string const &Name ) {
|
|||||||
auto const lookup {
|
auto const lookup {
|
||||||
FileExists(
|
FileExists(
|
||||||
{ Global.asCurrentTexturePath + Name, Name, szTexturePath + Name },
|
{ Global.asCurrentTexturePath + Name, Name, szTexturePath + Name },
|
||||||
{ ".mat", ".dds", ".tga", ".bmp" } ) };
|
{ ".mat", ".dds", ".tga", ".png", ".bmp" } ) };
|
||||||
|
|
||||||
return ( lookup.first + lookup.second );
|
return ( lookup.first + lookup.second );
|
||||||
}
|
}
|
||||||
|
|||||||
130
Texture.cpp
130
Texture.cpp
@@ -277,17 +277,17 @@ opengl_texture::load_DDS() {
|
|||||||
{
|
{
|
||||||
case FOURCC_DXT1:
|
case FOURCC_DXT1:
|
||||||
// DXT1's compression ratio is 8:1
|
// DXT1's compression ratio is 8:1
|
||||||
data_format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
data_format = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FOURCC_DXT3:
|
case FOURCC_DXT3:
|
||||||
// DXT3's compression ratio is 4:1
|
// DXT3's compression ratio is 4:1
|
||||||
data_format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
data_format = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FOURCC_DXT5:
|
case FOURCC_DXT5:
|
||||||
// DXT5's compression ratio is 4:1
|
// DXT5's compression ratio is 4:1
|
||||||
data_format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
data_format = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -299,7 +299,7 @@ opengl_texture::load_DDS() {
|
|||||||
data_height = ddsd.dwHeight;
|
data_height = ddsd.dwHeight;
|
||||||
data_mapcount = ddsd.dwMipMapCount;
|
data_mapcount = ddsd.dwMipMapCount;
|
||||||
|
|
||||||
int blockSize = ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ? 8 : 16 );
|
int blockSize = ( data_format == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ? 8 : 16 );
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
while( ( data_width > Global.iMaxTextureSize ) || ( data_height > Global.iMaxTextureSize ) ) {
|
while( ( data_width > Global.iMaxTextureSize ) || ( data_height > Global.iMaxTextureSize ) ) {
|
||||||
@@ -584,8 +584,9 @@ opengl_texture::bind() {
|
|||||||
bool
|
bool
|
||||||
opengl_texture::create() {
|
opengl_texture::create() {
|
||||||
|
|
||||||
if( data_state != resource_state::good ) {
|
if( data_state != resource_state::good && !is_rendertarget ) {
|
||||||
// don't bother until we have useful texture data
|
// don't bother until we have useful texture data
|
||||||
|
// and it isn't rendertarget texture without loaded data
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,55 +612,64 @@ opengl_texture::create() {
|
|||||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ( wraps == true ? GL_REPEAT : GL_CLAMP_TO_EDGE ) );
|
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ( wraps == true ? GL_REPEAT : GL_CLAMP_TO_EDGE ) );
|
||||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ( wrapt == true ? GL_REPEAT : GL_CLAMP_TO_EDGE ) );
|
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ( wrapt == true ? GL_REPEAT : GL_CLAMP_TO_EDGE ) );
|
||||||
|
|
||||||
set_filtering();
|
|
||||||
|
|
||||||
// upload texture data
|
// upload texture data
|
||||||
int dataoffset = 0,
|
int dataoffset = 0,
|
||||||
datasize = 0,
|
datasize = 0,
|
||||||
datawidth = data_width,
|
datawidth = data_width,
|
||||||
dataheight = data_height;
|
dataheight = data_height;
|
||||||
for( int maplevel = 0; maplevel < data_mapcount; ++maplevel ) {
|
if (is_rendertarget)
|
||||||
|
{
|
||||||
if( ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT )
|
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||||
|| ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT )
|
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||||
|| ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ) ) {
|
glTexImage2D(GL_TEXTURE_2D, 0, data_format, data_width, data_height, 0, data_components, data_type, nullptr);
|
||||||
// compressed dds formats
|
|
||||||
int const datablocksize =
|
|
||||||
( data_format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ?
|
|
||||||
8 :
|
|
||||||
16 );
|
|
||||||
|
|
||||||
datasize = ( ( std::max( datawidth, 4 ) + 3 ) / 4 ) * ( ( std::max( dataheight, 4 ) + 3 ) / 4 ) * datablocksize;
|
|
||||||
|
|
||||||
::glCompressedTexImage2D(
|
|
||||||
GL_TEXTURE_2D, maplevel, data_format,
|
|
||||||
datawidth, dataheight, 0,
|
|
||||||
datasize, (GLubyte *)&data[ dataoffset ] );
|
|
||||||
|
|
||||||
dataoffset += datasize;
|
|
||||||
datawidth = std::max( datawidth / 2, 1 );
|
|
||||||
dataheight = std::max( dataheight / 2, 1 );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// uncompressed texture data. have the gfx card do the compression as it sees fit
|
|
||||||
::glTexImage2D(
|
|
||||||
GL_TEXTURE_2D, 0,
|
|
||||||
Global.compress_tex ? GL_COMPRESSED_RGBA : GL_RGBA,
|
|
||||||
data_width, data_height, 0,
|
|
||||||
data_format, GL_UNSIGNED_BYTE, (GLubyte *)&data[ 0 ] );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_filtering();
|
||||||
|
|
||||||
if( data_mapcount == 1 ) {
|
for( int maplevel = 0; maplevel < data_mapcount; ++maplevel ) {
|
||||||
// fill missing mipmaps if needed
|
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ( true == Global.ResourceMove )
|
if( ( data_format == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT )
|
||||||
|| ( false == Global.ResourceSweep ) ) {
|
|| ( data_format == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT )
|
||||||
// if garbage collection is disabled we don't expect having to upload the texture more than once
|
|| ( data_format == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT ) ) {
|
||||||
data = std::vector<char>();
|
// compressed dds formats
|
||||||
data_state = resource_state::none;
|
int const datablocksize =
|
||||||
|
( data_format == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ?
|
||||||
|
8 :
|
||||||
|
16 );
|
||||||
|
|
||||||
|
datasize = ( ( std::max( datawidth, 4 ) + 3 ) / 4 ) * ( ( std::max( dataheight, 4 ) + 3 ) / 4 ) * datablocksize;
|
||||||
|
|
||||||
|
::glCompressedTexImage2D(
|
||||||
|
GL_TEXTURE_2D, maplevel, data_format,
|
||||||
|
datawidth, dataheight, 0,
|
||||||
|
datasize, (GLubyte *)&data[ dataoffset ] );
|
||||||
|
|
||||||
|
dataoffset += datasize;
|
||||||
|
datawidth = std::max( datawidth / 2, 1 );
|
||||||
|
dataheight = std::max( dataheight / 2, 1 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// uncompressed texture data. have the gfx card do the compression as it sees fit
|
||||||
|
::glTexImage2D(
|
||||||
|
GL_TEXTURE_2D, 0,
|
||||||
|
Global.compress_tex ? GL_COMPRESSED_SRGB_ALPHA : GL_SRGB_ALPHA,
|
||||||
|
data_width, data_height, 0,
|
||||||
|
data_format, data_type, (GLubyte *)&data[ 0 ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( data_mapcount == 1 ) {
|
||||||
|
// fill missing mipmaps if needed
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( true == Global.ResourceMove )
|
||||||
|
|| ( false == Global.ResourceSweep ) ) {
|
||||||
|
// if garbage collection is disabled we don't expect having to upload the texture more than once
|
||||||
|
data = std::vector<char>();
|
||||||
|
data_state = resource_state::none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is_ready = true;
|
is_ready = true;
|
||||||
}
|
}
|
||||||
@@ -673,7 +683,7 @@ opengl_texture::release() {
|
|||||||
|
|
||||||
if( id == -1 ) { return; }
|
if( id == -1 ) { return; }
|
||||||
|
|
||||||
if( true == Global.ResourceMove ) {
|
if( true == Global.ResourceMove && !is_rendertarget ) {
|
||||||
// if resource move is enabled we don't keep a cpu side copy after upload
|
// if resource move is enabled we don't keep a cpu side copy after upload
|
||||||
// so need to re-acquire the data before release
|
// so need to re-acquire the data before release
|
||||||
// TBD, TODO: instead of vram-ram transfer fetch the data 'normally' from the disk using worker thread
|
// TBD, TODO: instead of vram-ram transfer fetch the data 'normally' from the disk using worker thread
|
||||||
@@ -694,6 +704,7 @@ opengl_texture::release() {
|
|||||||
// for whatever reason texture didn't get compressed during upload
|
// for whatever reason texture didn't get compressed during upload
|
||||||
// fallback on plain rgba storage...
|
// fallback on plain rgba storage...
|
||||||
data_format = GL_RGBA;
|
data_format = GL_RGBA;
|
||||||
|
data_type = GL_UNSIGNED_BYTE;
|
||||||
data.resize( data_width * data_height * 4 );
|
data.resize( data_width * data_height * 4 );
|
||||||
// ...fetch the data...
|
// ...fetch the data...
|
||||||
::glGetTexImage( GL_TEXTURE_2D, 0, data_format, GL_UNSIGNED_BYTE, &data[ 0 ] );
|
::glGetTexImage( GL_TEXTURE_2D, 0, data_format, GL_UNSIGNED_BYTE, &data[ 0 ] );
|
||||||
@@ -710,6 +721,18 @@ opengl_texture::release() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void opengl_texture::alloc_rendertarget(GLint format, GLint components, GLint type, int width, int height)
|
||||||
|
{
|
||||||
|
data_width = width;
|
||||||
|
data_height = height;
|
||||||
|
data_format = format;
|
||||||
|
data_components = components;
|
||||||
|
data_type = type;
|
||||||
|
data_mapcount = 1;
|
||||||
|
is_rendertarget = true;
|
||||||
|
create();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_texture::set_filtering() const {
|
opengl_texture::set_filtering() const {
|
||||||
|
|
||||||
@@ -899,9 +922,14 @@ void
|
|||||||
texture_manager::update() {
|
texture_manager::update() {
|
||||||
|
|
||||||
if( m_garbagecollector.sweep() > 0 ) {
|
if( m_garbagecollector.sweep() > 0 ) {
|
||||||
for( auto &unit : m_units ) {
|
reset_unit_cache();
|
||||||
unit = -1;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void texture_manager::reset_unit_cache()
|
||||||
|
{
|
||||||
|
for( auto &unit : m_units ) {
|
||||||
|
unit = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -986,7 +1014,7 @@ texture_manager::find_on_disk( std::string const &Texturename ) const {
|
|||||||
return (
|
return (
|
||||||
FileExists(
|
FileExists(
|
||||||
filenames,
|
filenames,
|
||||||
{ ".dds", ".tga", ".bmp", ".ext" } ) );
|
{ ".dds", ".tga", ".png", ".bmp", ".ext" } ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ struct opengl_texture {
|
|||||||
int
|
int
|
||||||
height() const {
|
height() const {
|
||||||
return data_height; }
|
return data_height; }
|
||||||
|
|
||||||
|
void alloc_rendertarget(GLint format, GLint components, GLint type, int width, int height);
|
||||||
|
|
||||||
// members
|
// members
|
||||||
GLuint id{ (GLuint)-1 }; // associated GL resource
|
GLuint id{ (GLuint)-1 }; // associated GL resource
|
||||||
bool has_alpha{ false }; // indicates the texture has alpha channel
|
bool has_alpha{ false }; // indicates the texture has alpha channel
|
||||||
@@ -60,6 +63,7 @@ private:
|
|||||||
void flip_vertical();
|
void flip_vertical();
|
||||||
|
|
||||||
// members
|
// members
|
||||||
|
bool is_rendertarget; // is used as postfx rendertarget, without loaded data
|
||||||
std::vector<char> data; // texture data (stored GL-style, bottom-left origin)
|
std::vector<char> data; // texture data (stored GL-style, bottom-left origin)
|
||||||
resource_state data_state{ resource_state::none }; // current state of texture data
|
resource_state data_state{ resource_state::none }; // current state of texture data
|
||||||
int data_width{ 0 },
|
int data_width{ 0 },
|
||||||
@@ -67,6 +71,8 @@ private:
|
|||||||
data_mapcount{ 0 };
|
data_mapcount{ 0 };
|
||||||
GLint data_format{ 0 },
|
GLint data_format{ 0 },
|
||||||
data_components{ 0 };
|
data_components{ 0 };
|
||||||
|
|
||||||
|
GLint data_type = GL_UNSIGNED_BYTE;
|
||||||
/*
|
/*
|
||||||
std::atomic<bool> is_loaded{ false }; // indicates the texture data was loaded and can be processed
|
std::atomic<bool> is_loaded{ false }; // indicates the texture data was loaded and can be processed
|
||||||
std::atomic<bool> is_good{ false }; // indicates the texture data was retrieved without errors
|
std::atomic<bool> is_good{ false }; // indicates the texture data was retrieved without errors
|
||||||
@@ -96,6 +102,7 @@ public:
|
|||||||
// performs a resource sweep
|
// performs a resource sweep
|
||||||
void
|
void
|
||||||
update();
|
update();
|
||||||
|
void reset_unit_cache();
|
||||||
// debug performance string
|
// debug performance string
|
||||||
std::string
|
std::string
|
||||||
info() const;
|
info() const;
|
||||||
|
|||||||
@@ -325,15 +325,15 @@ void DecompressDXT(DDS_IMAGE_DATA lImage, const GLubyte *lCompData, GLubyte *Dat
|
|||||||
{
|
{
|
||||||
switch (lImage.format)
|
switch (lImage.format)
|
||||||
{
|
{
|
||||||
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
|
||||||
DecompressDXT1(lImage, lCompData, Data);
|
DecompressDXT1(lImage, lCompData, Data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
|
||||||
DecompressDXT3(lImage, lCompData, Data);
|
DecompressDXT3(lImage, lCompData, Data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
|
||||||
DecompressDXT5(lImage, lCompData, Data);
|
DecompressDXT5(lImage, lCompData, Data);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "framebuffer.h"
|
||||||
|
|
||||||
|
gl::framebuffer::framebuffer()
|
||||||
|
{
|
||||||
|
glGenFramebuffers(1, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
gl::framebuffer::~framebuffer()
|
||||||
|
{
|
||||||
|
glDeleteFramebuffers(1, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gl::framebuffer::bind(GLuint id)
|
||||||
|
{
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gl::framebuffer::attach(const opengl_texture &tex, GLenum location)
|
||||||
|
{
|
||||||
|
bind();
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, location, GL_TEXTURE_2D, tex.id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gl::framebuffer::attach(const renderbuffer &rb, GLenum location)
|
||||||
|
{
|
||||||
|
bind();
|
||||||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, location, GL_RENDERBUFFER, *rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gl::framebuffer::is_complete()
|
||||||
|
{
|
||||||
|
bind();
|
||||||
|
return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gl::framebuffer::clear()
|
||||||
|
{
|
||||||
|
bind();
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "object.h"
|
||||||
|
#include "bindable.h"
|
||||||
|
#include "renderbuffer.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
|
||||||
|
namespace gl
|
||||||
|
{
|
||||||
|
class framebuffer : public object, public bindable<framebuffer>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
framebuffer();
|
||||||
|
~framebuffer();
|
||||||
|
|
||||||
|
void attach(const opengl_texture &tex, GLenum location);
|
||||||
|
void attach(const renderbuffer &rb, GLenum location);
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
bool is_complete();
|
||||||
|
|
||||||
|
using bindable::bind;
|
||||||
|
static void bind(GLuint id);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include "renderbuffer.h"
|
||||||
|
|
||||||
|
gl::renderbuffer::renderbuffer()
|
||||||
|
{
|
||||||
|
glGenRenderbuffers(1, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
gl::renderbuffer::~renderbuffer()
|
||||||
|
{
|
||||||
|
glDeleteRenderbuffers(1, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gl::renderbuffer::bind(GLuint id)
|
||||||
|
{
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gl::renderbuffer::alloc(GLuint format, int width, int height)
|
||||||
|
{
|
||||||
|
bind();
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, format, width, height);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "object.h"
|
||||||
|
#include "bindable.h"
|
||||||
|
|
||||||
|
namespace gl
|
||||||
|
{
|
||||||
|
class renderbuffer : public object, public bindable<renderbuffer>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
renderbuffer();
|
||||||
|
~renderbuffer();
|
||||||
|
|
||||||
|
void alloc(GLuint format, int width, int height);
|
||||||
|
|
||||||
|
static void bind(GLuint id);
|
||||||
|
using bindable::bind;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -55,8 +55,6 @@ gl::shader::shader(const std::string &filename)
|
|||||||
std::string str = read_file(filename);
|
std::string str = read_file(filename);
|
||||||
expand_includes(str);
|
expand_includes(str);
|
||||||
|
|
||||||
std::cout << (str) << std::endl;;
|
|
||||||
|
|
||||||
const GLchar *cstr = str.c_str();
|
const GLchar *cstr = str.c_str();
|
||||||
|
|
||||||
if (!cstr[0])
|
if (!cstr[0])
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ void gl::ubo::bind(GLuint i)
|
|||||||
glBindBuffer(GL_UNIFORM_BUFFER, i);
|
glBindBuffer(GL_UNIFORM_BUFFER, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gl::ubo::update(void *data, int offset, int size)
|
void gl::ubo::update(const uint8_t *data, int offset, int size)
|
||||||
{
|
{
|
||||||
bind();
|
bind();
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, offset, size, data);
|
glBufferSubData(GL_UNIFORM_BUFFER, offset, size, data);
|
||||||
|
|||||||
8
gl/ubo.h
8
gl/ubo.h
@@ -1,3 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "bindable.h"
|
#include "bindable.h"
|
||||||
|
|
||||||
@@ -16,7 +18,11 @@ namespace gl
|
|||||||
using bindable::bind;
|
using bindable::bind;
|
||||||
static void bind(GLuint i);
|
static void bind(GLuint i);
|
||||||
|
|
||||||
void update(void *data, int offset, int size);
|
void update(const uint8_t *data, int offset, int size);
|
||||||
|
template <typename T> void update(const T &data, size_t offset = 0)
|
||||||
|
{
|
||||||
|
update(reinterpret_cast<const uint8_t*>(&data), offset, sizeof(data));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// layout std140
|
// layout std140
|
||||||
|
|||||||
34
material.cpp
34
material.cpp
@@ -54,24 +54,46 @@ opengl_material::deserialize_mapping( cParser &Input, int const Priority, bool c
|
|||||||
key.erase(0, 7);
|
key.erase(0, 7);
|
||||||
size_t num = std::stoi(key) - 1;
|
size_t num = std::stoi(key) - 1;
|
||||||
if (num < textures.size() &&
|
if (num < textures.size() &&
|
||||||
(textures[num] == null_handle || Priority > m_priority[num]))
|
(textures[num] == null_handle || Priority > m_texture_priority[num]))
|
||||||
{
|
{
|
||||||
std::replace(value.begin(), value.end(), '\\', '/');
|
std::replace(value.begin(), value.end(), '\\', '/');
|
||||||
textures[num] = GfxRenderer.Fetch_Texture( value, Loadnow );
|
textures[num] = GfxRenderer.Fetch_Texture( value, Loadnow );
|
||||||
m_priority[num] = Priority;
|
m_texture_priority[num] = Priority;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (key.compare(0, 7, "param") == 0) {
|
||||||
|
key.erase(0, 5);
|
||||||
|
size_t num = std::stoi(key) - 1;
|
||||||
|
if (num < params.size() &&
|
||||||
|
(Priority > m_param_priority[num]))
|
||||||
|
{
|
||||||
|
std::istringstream stream(value);
|
||||||
|
|
||||||
|
stream >> params[num].r;
|
||||||
|
stream >> params[num].g;
|
||||||
|
stream >> params[num].b;
|
||||||
|
stream >> params[num].a;
|
||||||
|
|
||||||
|
m_param_priority[num] = Priority;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (key == "shader:" &&
|
else if (key == "shader:" &&
|
||||||
(!shader || Priority > m_priority[max_textures]))
|
(!shader || Priority > m_shader_priority))
|
||||||
{
|
{
|
||||||
shader = GfxRenderer.Fetch_Shader(value);
|
shader = GfxRenderer.Fetch_Shader(value);
|
||||||
m_priority[max_textures] = Priority;
|
m_shader_priority = Priority;
|
||||||
}
|
}
|
||||||
else if (key == "opacity:" &&
|
else if (key == "opacity:" &&
|
||||||
Priority > m_priority[max_textures + 1])
|
Priority > m_opacity_priority)
|
||||||
{
|
{
|
||||||
opacity = std::stoi(value); //m7t: handle exception
|
opacity = std::stoi(value); //m7t: handle exception
|
||||||
m_priority[max_textures + 1] = Priority;
|
m_opacity_priority = Priority;
|
||||||
|
}
|
||||||
|
else if (key == "selfillum:" &&
|
||||||
|
Priority > m_selfillum_priority)
|
||||||
|
{
|
||||||
|
selfillum = std::stoi(value); //m7t: handle exception
|
||||||
|
m_selfillum_priority = Priority;
|
||||||
}
|
}
|
||||||
else if( value == "{" ) {
|
else if( value == "{" ) {
|
||||||
// unrecognized or ignored token, but comes with attribute block and potential further nesting
|
// unrecognized or ignored token, but comes with attribute block and potential further nesting
|
||||||
|
|||||||
13
material.h
13
material.h
@@ -12,20 +12,23 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Classes.h"
|
#include "Classes.h"
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include "gl/shader.h"
|
#include "gl/shader.h"
|
||||||
|
#include "gl/ubo.h"
|
||||||
|
|
||||||
typedef int material_handle;
|
typedef int material_handle;
|
||||||
|
|
||||||
// a collection of parameters for the rendering setup.
|
// a collection of parameters for the rendering setup.
|
||||||
// for modern opengl this translates to set of attributes for shaders
|
// for modern opengl this translates to set of attributes for shaders
|
||||||
struct opengl_material {
|
struct opengl_material {
|
||||||
static const size_t max_textures = 2;
|
static const size_t MAX_TEXTURES = 4;
|
||||||
|
|
||||||
// primary texture, typically diffuse+apha
|
// primary texture, typically diffuse+apha
|
||||||
// secondary texture, typically normal+reflection
|
// secondary texture, typically normal+reflection
|
||||||
std::array<texture_handle, max_textures> textures = { null_handle };
|
std::array<texture_handle, MAX_TEXTURES> textures = { null_handle };
|
||||||
|
std::array<glm::vec4, gl::MAX_PARAMS> params = { glm::vec4() };
|
||||||
|
|
||||||
std::shared_ptr<gl::program> shader;
|
std::shared_ptr<gl::program> shader;
|
||||||
float opacity = std::numeric_limits<float>::quiet_NaN();
|
float opacity = std::numeric_limits<float>::quiet_NaN();
|
||||||
|
float selfillum = std::numeric_limits<float>::quiet_NaN();
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
@@ -44,7 +47,11 @@ private:
|
|||||||
|
|
||||||
// members
|
// members
|
||||||
// priorities for textures, shader, opacity
|
// priorities for textures, shader, opacity
|
||||||
std::array<int, max_textures + 2> m_priority = { -1 };
|
int m_shader_priority = -1;
|
||||||
|
int m_opacity_priority = -1;
|
||||||
|
int m_selfillum_priority = -1;
|
||||||
|
std::array<int, MAX_TEXTURES> m_texture_priority = { -1 };
|
||||||
|
std::array<int, gl::MAX_PARAMS> m_param_priority = { -1 };
|
||||||
};
|
};
|
||||||
|
|
||||||
class material_manager {
|
class material_manager {
|
||||||
|
|||||||
62
renderer.cpp
62
renderer.cpp
@@ -169,6 +169,20 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
|||||||
|
|
||||||
m_invalid_material = Fetch_Material("invalid");
|
m_invalid_material = Fetch_Material("invalid");
|
||||||
|
|
||||||
|
m_main_fb = std::make_unique<gl::framebuffer>();
|
||||||
|
m_main_tex = std::make_unique<opengl_texture>();
|
||||||
|
m_main_rb = std::make_unique<gl::renderbuffer>();
|
||||||
|
|
||||||
|
m_main_rb->alloc(GL_DEPTH_COMPONENT32, 1280, 720);
|
||||||
|
m_main_tex->alloc_rendertarget(GL_RGB16F, GL_RGB, GL_FLOAT, 1280, 720);
|
||||||
|
|
||||||
|
m_main_fb->attach(*m_main_tex, GL_COLOR_ATTACHMENT0);
|
||||||
|
m_main_fb->attach(*m_main_rb, GL_DEPTH_ATTACHMENT);
|
||||||
|
if (!m_main_fb->is_complete())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_pfx = std::make_unique<gl::postfx>("copy");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,6 +267,9 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
case rendermode::color: {
|
case rendermode::color: {
|
||||||
glDebug("color pass");
|
glDebug("color pass");
|
||||||
|
|
||||||
|
m_main_fb->bind();
|
||||||
|
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||||
|
|
||||||
if( ( true == m_environmentcubetexturesupport )
|
if( ( true == m_environmentcubetexturesupport )
|
||||||
&& ( true == World.InitPerformed() ) ) {
|
&& ( true == World.InitPerformed() ) ) {
|
||||||
// potentially update environmental cube map
|
// potentially update environmental cube map
|
||||||
@@ -282,11 +299,11 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
|
|
||||||
scene_ubs.time = Timer::GetTime();
|
scene_ubs.time = Timer::GetTime();
|
||||||
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
|
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
|
||||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
scene_ubo->update(scene_ubs);
|
||||||
Render( &World.Environment );
|
Render( &World.Environment );
|
||||||
|
|
||||||
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
|
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
|
||||||
scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs));
|
scene_ubo->update(scene_ubs);
|
||||||
// opaque parts...
|
// opaque parts...
|
||||||
setup_drawing( false );
|
setup_drawing( false );
|
||||||
|
|
||||||
@@ -343,9 +360,11 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
glDebug("color pass done");
|
glDebug("color pass done");
|
||||||
}
|
}
|
||||||
|
|
||||||
glDebug("render ui");
|
m_pfx->apply(*m_main_tex, nullptr);
|
||||||
|
m_textures.reset_unit_cache();
|
||||||
|
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||||
|
|
||||||
UILayer.render();
|
UILayer.render();
|
||||||
glDebug("ui render done");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -561,7 +580,7 @@ opengl_renderer::Render( world_environment *Environment ) {
|
|||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
|
|
||||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
model_ubo->update(model_ubs);
|
||||||
|
|
||||||
// skydome
|
// skydome
|
||||||
Environment->m_skydome.Render();
|
Environment->m_skydome.Render();
|
||||||
@@ -657,6 +676,9 @@ opengl_renderer::Bind_Material( material_handle const Material ) {
|
|||||||
if (Material != null_handle)
|
if (Material != null_handle)
|
||||||
{
|
{
|
||||||
auto &material = m_materials.material( Material );
|
auto &material = m_materials.material( Material );
|
||||||
|
for (size_t i = 0; i < gl::MAX_PARAMS; i++)
|
||||||
|
model_ubs.param[i] = material.params[i];
|
||||||
|
model_ubs.opacity = material.opacity;
|
||||||
material.shader->bind();
|
material.shader->bind();
|
||||||
|
|
||||||
size_t unit = 0;
|
size_t unit = 0;
|
||||||
@@ -685,12 +707,12 @@ opengl_renderer::Fetch_Texture( std::string const &Filename, bool const Loadnow
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_renderer::Bind_Texture( texture_handle const Texture ) {
|
opengl_renderer::Bind_Texture(size_t Unit, texture_handle const Texture ) {
|
||||||
|
|
||||||
m_textures.bind( 0, Texture );
|
m_textures.bind( Unit, Texture );
|
||||||
}
|
}
|
||||||
|
|
||||||
opengl_texture const &
|
opengl_texture &
|
||||||
opengl_renderer::Texture( texture_handle const Texture ) const {
|
opengl_renderer::Texture( texture_handle const Texture ) const {
|
||||||
|
|
||||||
return m_textures.texture( Texture );
|
return m_textures.texture( Texture );
|
||||||
@@ -937,7 +959,7 @@ opengl_renderer::Render( scene::shape_node const &Shape, bool const Ignorerange
|
|||||||
}
|
}
|
||||||
// render
|
// render
|
||||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
model_ubo->update(model_ubs);
|
||||||
|
|
||||||
m_geometry.draw( data.geometry );
|
m_geometry.draw( data.geometry );
|
||||||
// debug data
|
// debug data
|
||||||
@@ -1267,7 +1289,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
|
|
||||||
// main draw call
|
// main draw call
|
||||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
model_ubo->update(model_ubs);
|
||||||
|
|
||||||
m_geometry.draw( Submodel->m_geometry );
|
m_geometry.draw( Submodel->m_geometry );
|
||||||
|
|
||||||
@@ -1336,11 +1358,9 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
|
|
||||||
// main draw call
|
// main draw call
|
||||||
model_ubs.param[0] = glm::vec4(glm::vec3(Submodel->f4Diffuse), 0.0f);
|
model_ubs.param[0] = glm::vec4(glm::vec3(Submodel->f4Diffuse), 0.0f);
|
||||||
model_ubs.param[1] = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
|
||||||
model_ubs.emission = lightlevel * anglefactor;
|
model_ubs.emission = lightlevel * anglefactor;
|
||||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
model_ubo->update(model_ubs);
|
||||||
model_ubs.emission = 0.0f;
|
|
||||||
m_freespot_shader->bind();
|
m_freespot_shader->bind();
|
||||||
|
|
||||||
m_geometry.draw( Submodel->m_geometry );
|
m_geometry.draw( Submodel->m_geometry );
|
||||||
@@ -1373,7 +1393,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
|
|
||||||
// main draw call
|
// main draw call
|
||||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
model_ubo->update(model_ubs);
|
||||||
|
|
||||||
//m_geometry.draw( Submodel->m_geometry, gfx::color_streams );
|
//m_geometry.draw( Submodel->m_geometry, gfx::color_streams );
|
||||||
}
|
}
|
||||||
@@ -1415,7 +1435,7 @@ opengl_renderer::Render( TTrack *Track ) {
|
|||||||
++m_debugstats.drawcalls;
|
++m_debugstats.drawcalls;
|
||||||
|
|
||||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
model_ubo->update(model_ubs);
|
||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::color:
|
case rendermode::color:
|
||||||
@@ -1463,7 +1483,7 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
|
|||||||
}
|
}
|
||||||
|
|
||||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
model_ubo->update(model_ubs);
|
||||||
|
|
||||||
// first pass, material 1
|
// first pass, material 1
|
||||||
for( auto first { First }; first != Last; ++first ) {
|
for( auto first { First }; first != Last; ++first ) {
|
||||||
@@ -1737,7 +1757,7 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) {
|
|||||||
|
|
||||||
model_ubs.param[0] = glm::vec4(Traction->wire_color(), linealpha);
|
model_ubs.param[0] = glm::vec4(Traction->wire_color(), linealpha);
|
||||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
model_ubo->update(model_ubs);
|
||||||
m_line_shader->bind();
|
m_line_shader->bind();
|
||||||
|
|
||||||
m_geometry.draw(Traction->m_geometry);
|
m_geometry.draw(Traction->m_geometry);
|
||||||
@@ -1781,7 +1801,7 @@ opengl_renderer::Render_Alpha( scene::lines_node const &Lines ) {
|
|||||||
|
|
||||||
model_ubs.param[0] = glm::vec4(glm::vec3(data.lighting.diffuse * m_sunlight.ambient), linealpha);
|
model_ubs.param[0] = glm::vec4(glm::vec3(data.lighting.diffuse * m_sunlight.ambient), linealpha);
|
||||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
model_ubo->update(model_ubs);
|
||||||
m_line_shader->bind();
|
m_line_shader->bind();
|
||||||
|
|
||||||
m_geometry.draw( data.geometry);
|
m_geometry.draw( data.geometry);
|
||||||
@@ -1961,7 +1981,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
|
|
||||||
// main draw call
|
// main draw call
|
||||||
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
|
||||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
model_ubo->update(model_ubs);
|
||||||
m_geometry.draw( Submodel->m_geometry );
|
m_geometry.draw( Submodel->m_geometry );
|
||||||
|
|
||||||
#ifdef EU07_USE_OPTIMIZED_NORMALIZATION
|
#ifdef EU07_USE_OPTIMIZED_NORMALIZATION
|
||||||
@@ -2028,7 +2048,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
|
|
||||||
// main draw call
|
// main draw call
|
||||||
model_ubs.set(OpenGLMatrices.data(GL_MODELVIEW));
|
model_ubs.set(OpenGLMatrices.data(GL_MODELVIEW));
|
||||||
model_ubo->update(&model_ubs, 0, sizeof(model_ubs));
|
model_ubo->update(model_ubs);
|
||||||
m_geometry.draw( m_billboardgeometry );
|
m_geometry.draw( m_billboardgeometry );
|
||||||
|
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
@@ -2264,7 +2284,7 @@ opengl_renderer::Update_Lights( light_array &Lights ) {
|
|||||||
light_ubs.lights[0].color = m_sunlight.diffuse * m_sunlight.factor;
|
light_ubs.lights[0].color = m_sunlight.diffuse * m_sunlight.factor;
|
||||||
light_ubs.lights_count = light_i;
|
light_ubs.lights_count = light_i;
|
||||||
|
|
||||||
light_ubo->update(&light_ubs, 0, sizeof(light_ubs));
|
light_ubo->update(light_ubs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|||||||
12
renderer.h
12
renderer.h
@@ -21,6 +21,9 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "light.h"
|
#include "light.h"
|
||||||
#include "gl/shader_mvp.h"
|
#include "gl/shader_mvp.h"
|
||||||
#include "gl/ubo.h"
|
#include "gl/ubo.h"
|
||||||
|
#include "gl/framebuffer.h"
|
||||||
|
#include "gl/renderbuffer.h"
|
||||||
|
#include "gl/postfx.h"
|
||||||
|
|
||||||
#define EU07_USE_PICKING_FRAMEBUFFER
|
#define EU07_USE_PICKING_FRAMEBUFFER
|
||||||
//#define EU07_USE_DEBUG_SHADOWMAP
|
//#define EU07_USE_DEBUG_SHADOWMAP
|
||||||
@@ -163,8 +166,8 @@ public:
|
|||||||
texture_handle
|
texture_handle
|
||||||
Fetch_Texture( std::string const &Filename, bool const Loadnow = true );
|
Fetch_Texture( std::string const &Filename, bool const Loadnow = true );
|
||||||
void
|
void
|
||||||
Bind_Texture( texture_handle const Texture );
|
Bind_Texture( size_t Unit, texture_handle const Texture );
|
||||||
opengl_texture const &
|
opengl_texture &
|
||||||
Texture( texture_handle const Texture ) const;
|
Texture( texture_handle const Texture ) const;
|
||||||
// utility methods
|
// utility methods
|
||||||
TSubModel const *
|
TSubModel const *
|
||||||
@@ -389,6 +392,11 @@ private:
|
|||||||
std::unique_ptr<gl::program> m_line_shader;
|
std::unique_ptr<gl::program> m_line_shader;
|
||||||
std::unique_ptr<gl::program> m_freespot_shader;
|
std::unique_ptr<gl::program> m_freespot_shader;
|
||||||
|
|
||||||
|
std::unique_ptr<gl::framebuffer> m_main_fb;
|
||||||
|
std::unique_ptr<opengl_texture> m_main_tex;
|
||||||
|
std::unique_ptr<gl::renderbuffer> m_main_rb;
|
||||||
|
std::unique_ptr<gl::postfx> m_pfx;
|
||||||
|
|
||||||
material_handle m_invalid_material;
|
material_handle m_invalid_material;
|
||||||
|
|
||||||
bool m_widelines_supported;
|
bool m_widelines_supported;
|
||||||
|
|||||||
Reference in New Issue
Block a user