1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-06 01:28:57 +00:00

Still stepping slowly towards a working composite mode, switched the RGB sampling function to returning a vec4, which may be of benefit to any machine with a brightness part of an RGB signal, and started edging towards at least having the correct GLSL programs ready for converting composite output.

This commit is contained in:
Thomas Harte 2016-03-07 19:08:26 -05:00
parent 3b6c9c15a1
commit cd9c62acca
3 changed files with 56 additions and 34 deletions

View File

@ -35,10 +35,10 @@ Machine::Machine() :
_crt(std::unique_ptr<Outputs::CRT>(new Outputs::CRT(crt_cycles_per_line, 8, Outputs::CRT::DisplayType::PAL50, 1, 1)))
{
_crt->set_rgb_sampling_function(
"vec3 rgb_sample(vec2 coordinate)"
"vec4 rgb_sample(vec2 coordinate)"
"{"
"float texValue = texture(texID, coordinate).r;"
"return vec3(step(4.0/256.0, mod(texValue, 8.0/256.0)), step(2.0/256.0, mod(texValue, 4.0/256.0)), step(1.0/256.0, mod(texValue, 2.0/256.0)));"
"return vec4(step(4.0/256.0, mod(texValue, 8.0/256.0)), step(2.0/256.0, mod(texValue, 4.0/256.0)), step(1.0/256.0, mod(texValue, 2.0/256.0)), 1.0);"
"}");
_crt->set_output_device(Outputs::CRT::Monitor);
// _crt->set_visible_area(Outputs::Rect(0.23108f, 0.0f, 0.8125f, 0.98f)); //1875

View File

@ -195,7 +195,7 @@ class CRT {
format will be applied.
@param shader A GLSL fragent including a function with the signature
`vec3 rgb_sample(vec2 coordinate)` that evaluates to an RGB colour as a function of
`vec4 rgb_sample(vec2 coordinate)` that evaluates to an RGBA colour as a function of
the source buffer sampling location.
The shader may assume a uniform array of sampler2Ds named `buffers` provides access to all input data.
*/
@ -372,12 +372,19 @@ class CRT {
void destruct_openGL();
// Methods used by the OpenGL code
void prepare_shader();
void prepare_rgb_output_shader();
void prepare_vertex_array();
void push_size_uniforms(unsigned int output_width, unsigned int output_height);
char *get_vertex_shader();
char *get_fragment_shader();
char *get_output_vertex_shader();
char *get_output_fragment_shader(const char *sampling_function);
char *get_rgb_output_fragment_shader();
char *get_composite_output_fragment_shader();
char *get_input_vertex_shader();
char *get_input_fragment_shader();
char *get_compound_shader(const char *base, const char *insert);
};

View File

@ -90,7 +90,7 @@ void CRT::draw_frame(unsigned int output_width, unsigned int output_height, bool
glGenBuffers(1, &_openGL_state->arrayBuffer);
_openGL_state->verticesPerSlice = 0;
prepare_shader();
prepare_rgb_output_shader();
glBindBuffer(GL_ARRAY_BUFFER, _openGL_state->arrayBuffer);
glBindVertexArray(_openGL_state->vertexArray);
@ -245,7 +245,7 @@ void CRT::set_rgb_sampling_function(const char *shader)
_rgb_shader = strdup(shader);
}
char *CRT::get_vertex_shader()
char *CRT::get_output_vertex_shader()
{
// the main job of the vertex shader is just to map from an input area of [0,1]x[0,1], with the origin in the
// top left to OpenGL's [-1,1]x[-1,1] with the origin in the lower left, and to convert input data coordinates
@ -305,8 +305,44 @@ char *CRT::get_vertex_shader()
"}");
}
char *CRT::get_fragment_shader()
char *CRT::get_rgb_output_fragment_shader()
{
return get_output_fragment_shader(_rgb_shader);
}
char *CRT::get_composite_output_fragment_shader()
{
return get_output_fragment_shader(
"vec4 rgb_sample(vec2 coordinate)"
"{"
"return texture(texID, coordinate);"
"}");
}
char *CRT::get_output_fragment_shader(const char *sampling_function)
{
return get_compound_shader(
"#version 150\n"
"in float lateralVarying;"
"in float alpha;"
"in vec2 shadowMaskCoordinates;"
"in vec2 srcCoordinatesVarying;"
"out vec4 fragColour;"
"uniform sampler2D texID;"
"uniform sampler2D shadowMaskTexID;"
"\n%s\n"
"void main(void)"
"{"
"fragColour = rgb_sample(srcCoordinatesVarying) * vec4(1.0, 1.0, 1.0, alpha * sin(lateralVarying));" //
"}"
, sampling_function);
}
// assumes y = [0, 1], i and q = [-0.5, 0.5]; therefore i components are multiplied by 1.1914 versus standard matrices, q by 1.0452
// const char *const yiqToRGB = "const mat3 yiqToRGB = mat3(1.0, 1.0, 1.0, 1.1389784, -0.3240608, -1.3176884, 0.6490692, -0.6762444, 1.7799756);";
@ -338,28 +374,7 @@ char *CRT::get_fragment_shader()
// "fragColour = 5.0 * texture(shadowMaskTexID, shadowMaskCoordinates) * vec4(yiqToRGB * vec3(y, i, q), 1.0);//sin(lateralVarying));\n";
// dot(vec3(1.0/6.0, 2.0/3.0, 1.0/6.0), vec3(sample(srcCoordinatesVarying[0]), sample(srcCoordinatesVarying[0]), sample(srcCoordinatesVarying[0])));//sin(lateralVarying));\n";
return get_compound_shader(
"#version 150\n"
"in float lateralVarying;"
"in float alpha;"
"in vec2 shadowMaskCoordinates;"
"in vec2 srcCoordinatesVarying;"
"out vec4 fragColour;"
"uniform sampler2D texID;"
"uniform sampler2D shadowMaskTexID;"
"\n%s\n"
"void main(void)"
"{"
"fragColour = vec4(rgb_sample(srcCoordinatesVarying).rgb, alpha * sin(lateralVarying));" //
"}"
, _rgb_shader);
}
//}
char *CRT::get_compound_shader(const char *base, const char *insert)
{
@ -369,10 +384,10 @@ char *CRT::get_compound_shader(const char *base, const char *insert)
return text;
}
void CRT::prepare_shader()
void CRT::prepare_rgb_output_shader()
{
char *vertex_shader = get_vertex_shader();
char *fragment_shader = get_fragment_shader();
char *vertex_shader = get_output_vertex_shader();
char *fragment_shader = get_rgb_output_fragment_shader();
_openGL_state->shaderProgram = std::unique_ptr<OpenGL::Shader>(new OpenGL::Shader(vertex_shader, fragment_shader));
_openGL_state->shaderProgram->bind();