mirror of
https://github.com/TomHarte/CLK.git
synced 2024-07-07 23:29:06 +00:00
Switched to passing around std::string
s rather than char *
s, because they should be easier to capture.
This commit is contained in:
parent
d979a822ac
commit
6cb95b4fc5
@ -243,7 +243,7 @@ class CRT {
|
|||||||
that evaluates to the composite signal level as a function of a source buffer, sampling location, colour
|
that evaluates to the composite signal level as a function of a source buffer, sampling location, colour
|
||||||
carrier phase and amplitude.
|
carrier phase and amplitude.
|
||||||
*/
|
*/
|
||||||
inline void set_composite_sampling_function(const char *shader)
|
inline void set_composite_sampling_function(const std::string &shader)
|
||||||
{
|
{
|
||||||
openGL_output_builder_.set_composite_sampling_function(shader);
|
openGL_output_builder_.set_composite_sampling_function(shader);
|
||||||
}
|
}
|
||||||
@ -261,7 +261,7 @@ class CRT {
|
|||||||
* `vec2 coordinate` representing the source buffer location to sample from in the range [0, 1); and
|
* `vec2 coordinate` representing the source buffer location to sample from in the range [0, 1); and
|
||||||
* `vec2 icoordinate` representing the source buffer location to sample from as a pixel count, for easier multiple-pixels-per-byte unpacking.
|
* `vec2 icoordinate` representing the source buffer location to sample from as a pixel count, for easier multiple-pixels-per-byte unpacking.
|
||||||
*/
|
*/
|
||||||
inline void set_rgb_sampling_function(const char *shader)
|
inline void set_rgb_sampling_function(const std::string &shader)
|
||||||
{
|
{
|
||||||
openGL_output_builder_.set_rgb_sampling_function(shader);
|
openGL_output_builder_.set_rgb_sampling_function(shader);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include "CRT.hpp"
|
#include "CRT.hpp"
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "CRTOpenGL.hpp"
|
#include "CRTOpenGL.hpp"
|
||||||
@ -17,7 +16,8 @@
|
|||||||
|
|
||||||
using namespace Outputs::CRT;
|
using namespace Outputs::CRT;
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
|
{
|
||||||
static const GLenum source_data_texture_unit = GL_TEXTURE0;
|
static const GLenum source_data_texture_unit = GL_TEXTURE0;
|
||||||
static const GLenum pixel_accumulation_texture_unit = GL_TEXTURE1;
|
static const GLenum pixel_accumulation_texture_unit = GL_TEXTURE1;
|
||||||
|
|
||||||
@ -31,8 +31,6 @@ namespace {
|
|||||||
OpenGLOutputBuilder::OpenGLOutputBuilder(size_t bytes_per_pixel) :
|
OpenGLOutputBuilder::OpenGLOutputBuilder(size_t bytes_per_pixel) :
|
||||||
visible_area_(Rect(0, 0, 1, 1)),
|
visible_area_(Rect(0, 0, 1, 1)),
|
||||||
composite_src_output_y_(0),
|
composite_src_output_y_(0),
|
||||||
composite_shader_(nullptr),
|
|
||||||
rgb_shader_(nullptr),
|
|
||||||
last_output_width_(0),
|
last_output_width_(0),
|
||||||
last_output_height_(0),
|
last_output_height_(0),
|
||||||
fence_(nullptr),
|
fence_(nullptr),
|
||||||
@ -78,9 +76,6 @@ OpenGLOutputBuilder::OpenGLOutputBuilder(size_t bytes_per_pixel) :
|
|||||||
OpenGLOutputBuilder::~OpenGLOutputBuilder()
|
OpenGLOutputBuilder::~OpenGLOutputBuilder()
|
||||||
{
|
{
|
||||||
glDeleteVertexArrays(1, &output_vertex_array_);
|
glDeleteVertexArrays(1, &output_vertex_array_);
|
||||||
|
|
||||||
free(composite_shader_);
|
|
||||||
free(rgb_shader_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLOutputBuilder::get_is_television_output()
|
bool OpenGLOutputBuilder::get_is_television_output()
|
||||||
@ -275,17 +270,17 @@ void OpenGLOutputBuilder::set_openGL_context_will_change(bool should_delete_reso
|
|||||||
output_mutex_.unlock();
|
output_mutex_.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLOutputBuilder::set_composite_sampling_function(const char *shader)
|
void OpenGLOutputBuilder::set_composite_sampling_function(const std::string &shader)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock_guard(output_mutex_);
|
std::lock_guard<std::mutex> lock_guard(output_mutex_);
|
||||||
composite_shader_ = strdup(shader);
|
composite_shader_ = shader;
|
||||||
reset_all_OpenGL_state();
|
reset_all_OpenGL_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLOutputBuilder::set_rgb_sampling_function(const char *shader)
|
void OpenGLOutputBuilder::set_rgb_sampling_function(const std::string &shader)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock_guard(output_mutex_);
|
std::lock_guard<std::mutex> lock_guard(output_mutex_);
|
||||||
rgb_shader_ = strdup(shader);
|
rgb_shader_ = shader;
|
||||||
reset_all_OpenGL_state();
|
reset_all_OpenGL_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +316,7 @@ void OpenGLOutputBuilder::prepare_composite_input_shaders()
|
|||||||
|
|
||||||
void OpenGLOutputBuilder::prepare_rgb_input_shaders()
|
void OpenGLOutputBuilder::prepare_rgb_input_shaders()
|
||||||
{
|
{
|
||||||
if(rgb_shader_)
|
if(rgb_shader_.size())
|
||||||
{
|
{
|
||||||
rgb_input_shader_program_ = OpenGL::IntermediateShader::make_rgb_source_shader(rgb_shader_);
|
rgb_input_shader_program_ = OpenGL::IntermediateShader::make_rgb_source_shader(rgb_shader_);
|
||||||
rgb_input_shader_program_->set_source_texture_unit(source_data_texture_unit);
|
rgb_input_shader_program_->set_source_texture_unit(source_data_texture_unit);
|
||||||
|
@ -47,8 +47,8 @@ class OpenGLOutputBuilder {
|
|||||||
Rect visible_area_;
|
Rect visible_area_;
|
||||||
|
|
||||||
// Other things the caller may have provided.
|
// Other things the caller may have provided.
|
||||||
char *composite_shader_;
|
std::string composite_shader_;
|
||||||
char *rgb_shader_;
|
std::string rgb_shader_;
|
||||||
|
|
||||||
// Methods used by the OpenGL code
|
// Methods used by the OpenGL code
|
||||||
void prepare_output_shader();
|
void prepare_output_shader();
|
||||||
@ -148,8 +148,8 @@ class OpenGLOutputBuilder {
|
|||||||
|
|
||||||
void draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty);
|
void draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty);
|
||||||
void set_openGL_context_will_change(bool should_delete_resources);
|
void set_openGL_context_will_change(bool should_delete_resources);
|
||||||
void set_composite_sampling_function(const char *shader);
|
void set_composite_sampling_function(const std::string &shader);
|
||||||
void set_rgb_sampling_function(const char *shader);
|
void set_rgb_sampling_function(const std::string &shader);
|
||||||
void set_output_device(OutputDevice output_device);
|
void set_output_device(OutputDevice output_device);
|
||||||
void set_timing(unsigned int input_frequency, unsigned int cycles_per_line, unsigned int height_of_display, unsigned int horizontal_scan_period, unsigned int vertical_scan_period, unsigned int vertical_period_divider);
|
void set_timing(unsigned int input_frequency, unsigned int cycles_per_line, unsigned int height_of_display, unsigned int horizontal_scan_period, unsigned int vertical_scan_period, unsigned int vertical_period_divider);
|
||||||
};
|
};
|
||||||
|
@ -26,7 +26,7 @@ namespace {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IntermediateShader> IntermediateShader::make_shader(const char *fragment_shader, bool use_usampler, bool input_is_inputPosition)
|
std::unique_ptr<IntermediateShader> IntermediateShader::make_shader(const std::string &fragment_shader, bool use_usampler, bool input_is_inputPosition)
|
||||||
{
|
{
|
||||||
const char *sampler_type = use_usampler ? "usampler2D" : "sampler2D";
|
const char *sampler_type = use_usampler ? "usampler2D" : "sampler2D";
|
||||||
const char *input_variable = input_is_inputPosition ? "inputPosition" : "outputPosition";
|
const char *input_variable = input_is_inputPosition ? "inputPosition" : "outputPosition";
|
||||||
@ -111,12 +111,13 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_shader(const char *
|
|||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IntermediateShader> IntermediateShader::make_source_conversion_shader(const char *composite_shader, const char *rgb_shader)
|
std::unique_ptr<IntermediateShader> IntermediateShader::make_source_conversion_shader(const std::string &composite_shader, const std::string &rgb_shader)
|
||||||
{
|
{
|
||||||
char *composite_sample = (char *)composite_shader;
|
char *derived_composite_sample = nullptr;
|
||||||
if(!composite_sample)
|
const char *composite_sample = composite_shader.c_str();
|
||||||
|
if(!composite_shader.size())
|
||||||
{
|
{
|
||||||
asprintf(&composite_sample,
|
asprintf(&derived_composite_sample,
|
||||||
"%s\n"
|
"%s\n"
|
||||||
"uniform mat3 rgbToLumaChroma;"
|
"uniform mat3 rgbToLumaChroma;"
|
||||||
"float composite_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)"
|
"float composite_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)"
|
||||||
@ -126,7 +127,8 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_source_conversion_s
|
|||||||
"vec2 quadrature = vec2(cos(phase), -sin(phase)) * amplitude;"
|
"vec2 quadrature = vec2(cos(phase), -sin(phase)) * amplitude;"
|
||||||
"return dot(lumaChromaColour, vec3(1.0 - amplitude, quadrature));"
|
"return dot(lumaChromaColour, vec3(1.0 - amplitude, quadrature));"
|
||||||
"}",
|
"}",
|
||||||
rgb_shader);
|
rgb_shader.c_str());
|
||||||
|
composite_sample = derived_composite_sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *fragment_shader;
|
char *fragment_shader;
|
||||||
@ -148,7 +150,7 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_source_conversion_s
|
|||||||
"fragColour = vec4(composite_sample(texID, inputPositionsVarying[5], iInputPositionVarying, phaseAndAmplitudeVarying.x, phaseAndAmplitudeVarying.y));"
|
"fragColour = vec4(composite_sample(texID, inputPositionsVarying[5], iInputPositionVarying, phaseAndAmplitudeVarying.x, phaseAndAmplitudeVarying.y));"
|
||||||
"}"
|
"}"
|
||||||
, composite_sample);
|
, composite_sample);
|
||||||
if(!composite_shader) free(composite_sample);
|
free(derived_composite_sample);
|
||||||
|
|
||||||
std::unique_ptr<IntermediateShader> shader = make_shader(fragment_shader, true, true);
|
std::unique_ptr<IntermediateShader> shader = make_shader(fragment_shader, true, true);
|
||||||
free(fragment_shader);
|
free(fragment_shader);
|
||||||
@ -156,7 +158,7 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_source_conversion_s
|
|||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IntermediateShader> IntermediateShader::make_rgb_source_shader(const char *rgb_shader)
|
std::unique_ptr<IntermediateShader> IntermediateShader::make_rgb_source_shader(const std::string &rgb_shader)
|
||||||
{
|
{
|
||||||
char *fragment_shader;
|
char *fragment_shader;
|
||||||
asprintf(&fragment_shader,
|
asprintf(&fragment_shader,
|
||||||
@ -176,7 +178,7 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_rgb_source_shader(c
|
|||||||
"{"
|
"{"
|
||||||
"fragColour = rgb_sample(texID, inputPositionsVarying[5], iInputPositionVarying);"
|
"fragColour = rgb_sample(texID, inputPositionsVarying[5], iInputPositionVarying);"
|
||||||
"}"
|
"}"
|
||||||
, rgb_shader);
|
, rgb_shader.c_str());
|
||||||
|
|
||||||
std::unique_ptr<IntermediateShader> shader = make_shader(fragment_shader, true, true);
|
std::unique_ptr<IntermediateShader> shader = make_shader(fragment_shader, true, true);
|
||||||
free(fragment_shader);
|
free(fragment_shader);
|
||||||
|
@ -25,13 +25,13 @@ public:
|
|||||||
converting them to single-channel composite values using @c composite_shader if supplied
|
converting them to single-channel composite values using @c composite_shader if supplied
|
||||||
or @c rgb_shader and a reference composite conversion if @c composite_shader is @c nullptr.
|
or @c rgb_shader and a reference composite conversion if @c composite_shader is @c nullptr.
|
||||||
*/
|
*/
|
||||||
static std::unique_ptr<IntermediateShader> make_source_conversion_shader(const char *composite_shader, const char *rgb_shader);
|
static std::unique_ptr<IntermediateShader> make_source_conversion_shader(const std::string &composite_shader, const std::string &rgb_shader);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Constructs and returns an intermediate shader that will take runs from the inputPositions,
|
Constructs and returns an intermediate shader that will take runs from the inputPositions,
|
||||||
converting them to RGB values using @c rgb_shader.
|
converting them to RGB values using @c rgb_shader.
|
||||||
*/
|
*/
|
||||||
static std::unique_ptr<IntermediateShader> make_rgb_source_shader(const char *rgb_shader);
|
static std::unique_ptr<IntermediateShader> make_rgb_source_shader(const std::string &rgb_shader);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Constructs and returns an intermediate shader that will read composite samples from the R channel,
|
Constructs and returns an intermediate shader that will read composite samples from the R channel,
|
||||||
@ -95,7 +95,7 @@ public:
|
|||||||
void set_is_double_height(bool is_double_height, float input_offset = 0.0f, float output_offset = 0.0f);
|
void set_is_double_height(bool is_double_height, float input_offset = 0.0f, float output_offset = 0.0f);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::unique_ptr<IntermediateShader> make_shader(const char *fragment_shader, bool use_usampler, bool input_is_inputPosition);
|
static std::unique_ptr<IntermediateShader> make_shader(const std::string &fragment_shader, bool use_usampler, bool input_is_inputPosition);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,22 +8,23 @@
|
|||||||
|
|
||||||
#include "Shader.hpp"
|
#include "Shader.hpp"
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
using namespace OpenGL;
|
using namespace OpenGL;
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
|
{
|
||||||
Shader *bound_shader = nullptr;
|
Shader *bound_shader = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint Shader::compile_shader(const char *source, GLenum type)
|
GLuint Shader::compile_shader(const std::string &source, GLenum type)
|
||||||
{
|
{
|
||||||
GLuint shader = glCreateShader(type);
|
GLuint shader = glCreateShader(type);
|
||||||
glShaderSource(shader, 1, &source, NULL);
|
const char *c_str = source.c_str();
|
||||||
|
glShaderSource(shader, 1, &c_str, NULL);
|
||||||
glCompileShader(shader);
|
glCompileShader(shader);
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#ifdef DEBUG
|
||||||
GLint isCompiled = 0;
|
GLint isCompiled = 0;
|
||||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
|
||||||
if(isCompiled == GL_FALSE)
|
if(isCompiled == GL_FALSE)
|
||||||
@ -31,10 +32,10 @@ GLuint Shader::compile_shader(const char *source, GLenum type)
|
|||||||
GLint logLength;
|
GLint logLength;
|
||||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
|
||||||
if(logLength > 0) {
|
if(logLength > 0) {
|
||||||
GLchar *log = (GLchar *)malloc((size_t)logLength);
|
GLchar *log = new GLchar[logLength];
|
||||||
glGetShaderInfoLog(shader, logLength, &logLength, log);
|
glGetShaderInfoLog(shader, logLength, &logLength, log);
|
||||||
printf("Compile log:\n%s\n", log);
|
printf("Compile log:\n%s\n", log);
|
||||||
free(log);
|
delete[] log;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw (type == GL_VERTEX_SHADER) ? VertexShaderCompilationError : FragmentShaderCompilationError;
|
throw (type == GL_VERTEX_SHADER) ? VertexShaderCompilationError : FragmentShaderCompilationError;
|
||||||
@ -44,7 +45,7 @@ GLuint Shader::compile_shader(const char *source, GLenum type)
|
|||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader::Shader(const char *vertex_shader, const char *fragment_shader, const AttributeBinding *attribute_bindings)
|
Shader::Shader(const std::string &vertex_shader, const std::string &fragment_shader, const AttributeBinding *attribute_bindings)
|
||||||
{
|
{
|
||||||
shader_program_ = glCreateProgram();
|
shader_program_ = glCreateProgram();
|
||||||
GLuint vertex = compile_shader(vertex_shader, GL_VERTEX_SHADER);
|
GLuint vertex = compile_shader(vertex_shader, GL_VERTEX_SHADER);
|
||||||
@ -64,7 +65,7 @@ Shader::Shader(const char *vertex_shader, const char *fragment_shader, const Att
|
|||||||
|
|
||||||
glLinkProgram(shader_program_);
|
glLinkProgram(shader_program_);
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#ifdef DEBUG
|
||||||
GLint didLink = 0;
|
GLint didLink = 0;
|
||||||
glGetProgramiv(shader_program_, GL_LINK_STATUS, &didLink);
|
glGetProgramiv(shader_program_, GL_LINK_STATUS, &didLink);
|
||||||
if(didLink == GL_FALSE)
|
if(didLink == GL_FALSE)
|
||||||
@ -72,10 +73,10 @@ Shader::Shader(const char *vertex_shader, const char *fragment_shader, const Att
|
|||||||
GLint logLength;
|
GLint logLength;
|
||||||
glGetProgramiv(shader_program_, GL_INFO_LOG_LENGTH, &logLength);
|
glGetProgramiv(shader_program_, GL_INFO_LOG_LENGTH, &logLength);
|
||||||
if(logLength > 0) {
|
if(logLength > 0) {
|
||||||
GLchar *log = (GLchar *)malloc((size_t)logLength);
|
GLchar *log = new GLchar[logLength];
|
||||||
glGetProgramInfoLog(shader_program_, logLength, &logLength, log);
|
glGetProgramInfoLog(shader_program_, logLength, &logLength, log);
|
||||||
printf("Link log:\n%s\n", log);
|
printf("Link log:\n%s\n", log);
|
||||||
free(log);
|
delete[] log;
|
||||||
}
|
}
|
||||||
throw ProgramLinkageError;
|
throw ProgramLinkageError;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ public:
|
|||||||
@param fragment_shader The fragment shader source code.
|
@param fragment_shader The fragment shader source code.
|
||||||
@param attribute_bindings Either @c nullptr or an array terminated by an entry with a @c nullptr-name of attribute bindings.
|
@param attribute_bindings Either @c nullptr or an array terminated by an entry with a @c nullptr-name of attribute bindings.
|
||||||
*/
|
*/
|
||||||
Shader(const char *vertex_shader, const char *fragment_shader, const AttributeBinding *attribute_bindings);
|
Shader(const std::string &vertex_shader, const std::string &fragment_shader, const AttributeBinding *attribute_bindings);
|
||||||
~Shader();
|
~Shader();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -106,7 +106,7 @@ public:
|
|||||||
void set_uniform_matrix(const std::string &name, GLint size, GLsizei count, bool transpose, const GLfloat *values);
|
void set_uniform_matrix(const std::string &name, GLint size, GLsizei count, bool transpose, const GLfloat *values);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLuint compile_shader(const char *source, GLenum type);
|
GLuint compile_shader(const std::string &source, GLenum type);
|
||||||
GLuint shader_program_;
|
GLuint shader_program_;
|
||||||
|
|
||||||
void flush_functions();
|
void flush_functions();
|
||||||
|
Loading…
Reference in New Issue
Block a user