mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-27 01:31:42 +00:00
The attribute locations don't really need to be stored. They can be transient.
This commit is contained in:
parent
6dfe877c43
commit
bb09a5f58c
@ -374,7 +374,7 @@ class CRT {
|
|||||||
// Methods used by the OpenGL code
|
// Methods used by the OpenGL code
|
||||||
void prepare_rgb_output_shader();
|
void prepare_rgb_output_shader();
|
||||||
void prepare_composite_input_shader();
|
void prepare_composite_input_shader();
|
||||||
void prepare_vertex_array();
|
void prepare_output_vertex_array();
|
||||||
void push_size_uniforms(unsigned int output_width, unsigned int output_height);
|
void push_size_uniforms(unsigned int output_width, unsigned int output_height);
|
||||||
|
|
||||||
char *get_output_vertex_shader();
|
char *get_output_vertex_shader();
|
||||||
|
@ -19,13 +19,9 @@ using namespace Outputs;
|
|||||||
struct CRT::OpenGLState {
|
struct CRT::OpenGLState {
|
||||||
std::unique_ptr<OpenGL::Shader> rgb_shader_program;
|
std::unique_ptr<OpenGL::Shader> rgb_shader_program;
|
||||||
std::unique_ptr<OpenGL::Shader> composite_input_shader_program, composite_output_shader_program;
|
std::unique_ptr<OpenGL::Shader> composite_input_shader_program, composite_output_shader_program;
|
||||||
GLuint arrayBuffer, vertexArray;
|
|
||||||
size_t verticesPerSlice;
|
|
||||||
|
|
||||||
GLint positionAttribute;
|
GLuint output_array_buffer, output_vertex_array;
|
||||||
GLint textureCoordinatesAttribute;
|
size_t output_vertices_per_slice;
|
||||||
GLint lateralAttribute;
|
|
||||||
GLint timestampAttribute;
|
|
||||||
|
|
||||||
GLint windowSizeUniform, timestampBaseUniform;
|
GLint windowSizeUniform, timestampBaseUniform;
|
||||||
GLint boundsOriginUniform, boundsSizeUniform;
|
GLint boundsOriginUniform, boundsSizeUniform;
|
||||||
@ -91,16 +87,16 @@ void CRT::draw_frame(unsigned int output_width, unsigned int output_height, bool
|
|||||||
glTexImage2D(GL_TEXTURE_2D, 0, (GLint)format, CRTInputBufferBuilderWidth, CRTInputBufferBuilderHeight, 0, format, GL_UNSIGNED_BYTE, _buffer_builder->buffers[buffer].data);
|
glTexImage2D(GL_TEXTURE_2D, 0, (GLint)format, CRTInputBufferBuilderWidth, CRTInputBufferBuilderHeight, 0, format, GL_UNSIGNED_BYTE, _buffer_builder->buffers[buffer].data);
|
||||||
}
|
}
|
||||||
|
|
||||||
glGenVertexArrays(1, &_openGL_state->vertexArray);
|
glGenVertexArrays(1, &_openGL_state->output_vertex_array);
|
||||||
glGenBuffers(1, &_openGL_state->arrayBuffer);
|
glGenBuffers(1, &_openGL_state->output_array_buffer);
|
||||||
_openGL_state->verticesPerSlice = 0;
|
_openGL_state->output_vertices_per_slice = 0;
|
||||||
|
|
||||||
prepare_composite_input_shader();
|
prepare_composite_input_shader();
|
||||||
prepare_rgb_output_shader();
|
prepare_rgb_output_shader();
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _openGL_state->arrayBuffer);
|
glBindBuffer(GL_ARRAY_BUFFER, _openGL_state->output_array_buffer);
|
||||||
glBindVertexArray(_openGL_state->vertexArray);
|
glBindVertexArray(_openGL_state->output_vertex_array);
|
||||||
prepare_vertex_array();
|
prepare_output_vertex_array();
|
||||||
|
|
||||||
// This should return either an actual framebuffer number, if this is a target with a framebuffer intended for output,
|
// This should return either an actual framebuffer number, if this is a target with a framebuffer intended for output,
|
||||||
// or 0 if no framebuffer is bound, in which case 0 is also what we want to supply to bind the implied framebuffer. So
|
// or 0 if no framebuffer is bound, in which case 0 is also what we want to supply to bind the implied framebuffer. So
|
||||||
@ -165,20 +161,21 @@ void CRT::draw_frame(unsigned int output_width, unsigned int output_height, bool
|
|||||||
// glGetIntegerv(GL_VIEWPORT, results);
|
// glGetIntegerv(GL_VIEWPORT, results);
|
||||||
|
|
||||||
// ensure array buffer is up to date
|
// ensure array buffer is up to date
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _openGL_state->output_array_buffer);
|
||||||
size_t max_number_of_vertices = 0;
|
size_t max_number_of_vertices = 0;
|
||||||
for(int c = 0; c < kCRTNumberOfFields; c++)
|
for(int c = 0; c < kCRTNumberOfFields; c++)
|
||||||
{
|
{
|
||||||
max_number_of_vertices = std::max(max_number_of_vertices, _run_builders[c]->number_of_vertices);
|
max_number_of_vertices = std::max(max_number_of_vertices, _run_builders[c]->number_of_vertices);
|
||||||
}
|
}
|
||||||
if(_openGL_state->verticesPerSlice < max_number_of_vertices)
|
if(_openGL_state->output_vertices_per_slice < max_number_of_vertices)
|
||||||
{
|
{
|
||||||
_openGL_state->verticesPerSlice = max_number_of_vertices;
|
_openGL_state->output_vertices_per_slice = max_number_of_vertices;
|
||||||
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(max_number_of_vertices * kCRTOutputVertexSize * kCRTOutputVertexSize), NULL, GL_STREAM_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(max_number_of_vertices * kCRTOutputVertexSize * kCRTOutputVertexSize), NULL, GL_STREAM_DRAW);
|
||||||
|
|
||||||
for(unsigned int c = 0; c < kCRTNumberOfFields; c++)
|
for(unsigned int c = 0; c < kCRTNumberOfFields; c++)
|
||||||
{
|
{
|
||||||
uint8_t *data = &_run_builders[c]->_runs[0];
|
uint8_t *data = &_run_builders[c]->_runs[0];
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, (GLsizeiptr)(c * _openGL_state->verticesPerSlice * kCRTOutputVertexSize), (GLsizeiptr)(_run_builders[c]->number_of_vertices * kCRTOutputVertexSize), data);
|
glBufferSubData(GL_ARRAY_BUFFER, (GLsizeiptr)(c * _openGL_state->output_vertices_per_slice * kCRTOutputVertexSize), (GLsizeiptr)(_run_builders[c]->number_of_vertices * kCRTOutputVertexSize), data);
|
||||||
_run_builders[c]->uploaded_vertices = _run_builders[c]->number_of_vertices;
|
_run_builders[c]->uploaded_vertices = _run_builders[c]->number_of_vertices;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,13 +211,13 @@ void CRT::draw_frame(unsigned int output_width, unsigned int output_height, bool
|
|||||||
{
|
{
|
||||||
uint8_t *data = &_run_builders[run]->_runs[_run_builders[run]->uploaded_vertices * kCRTOutputVertexSize];
|
uint8_t *data = &_run_builders[run]->_runs[_run_builders[run]->uploaded_vertices * kCRTOutputVertexSize];
|
||||||
glBufferSubData(GL_ARRAY_BUFFER,
|
glBufferSubData(GL_ARRAY_BUFFER,
|
||||||
(GLsizeiptr)(((run * _openGL_state->verticesPerSlice) + _run_builders[run]->uploaded_vertices) * kCRTOutputVertexSize),
|
(GLsizeiptr)(((run * _openGL_state->output_vertices_per_slice) + _run_builders[run]->uploaded_vertices) * kCRTOutputVertexSize),
|
||||||
(GLsizeiptr)((_run_builders[run]->number_of_vertices - _run_builders[run]->uploaded_vertices) * kCRTOutputVertexSize), data);
|
(GLsizeiptr)((_run_builders[run]->number_of_vertices - _run_builders[run]->uploaded_vertices) * kCRTOutputVertexSize), data);
|
||||||
_run_builders[run]->uploaded_vertices = _run_builders[run]->number_of_vertices;
|
_run_builders[run]->uploaded_vertices = _run_builders[run]->number_of_vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw this frame
|
// draw this frame
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, (GLint)(run * _openGL_state->verticesPerSlice), (GLsizei)_run_builders[run]->number_of_vertices);
|
glDrawArrays(GL_TRIANGLE_STRIP, (GLint)(run * _openGL_state->output_vertices_per_slice), (GLsizei)_run_builders[run]->number_of_vertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
// advance back in time
|
// advance back in time
|
||||||
@ -448,6 +445,45 @@ void CRT::prepare_composite_input_shader()
|
|||||||
free(fragment_shader);
|
free(fragment_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*void CRT::prepare_output_shader(char *fragment_shader)
|
||||||
|
{
|
||||||
|
char *vertex_shader = get_output_vertex_shader();
|
||||||
|
if(vertex_shader && fragment_shader)
|
||||||
|
{
|
||||||
|
_openGL_state->rgb_shader_program = std::unique_ptr<OpenGL::Shader>(new OpenGL::Shader(vertex_shader, fragment_shader));
|
||||||
|
|
||||||
|
_openGL_state->rgb_shader_program->bind();
|
||||||
|
|
||||||
|
_openGL_state->windowSizeUniform = _openGL_state->rgb_shader_program->get_uniform_location("windowSize");
|
||||||
|
_openGL_state->boundsSizeUniform = _openGL_state->rgb_shader_program->get_uniform_location("boundsSize");
|
||||||
|
_openGL_state->boundsOriginUniform = _openGL_state->rgb_shader_program->get_uniform_location("boundsOrigin");
|
||||||
|
_openGL_state->timestampBaseUniform = _openGL_state->rgb_shader_program->get_uniform_location("timestampBase");
|
||||||
|
|
||||||
|
GLint texIDUniform = _openGL_state->rgb_shader_program->get_uniform_location("texID");
|
||||||
|
GLint shadowMaskTexIDUniform = _openGL_state->rgb_shader_program->get_uniform_location("shadowMaskTexID");
|
||||||
|
GLint textureSizeUniform = _openGL_state->rgb_shader_program->get_uniform_location("textureSize");
|
||||||
|
GLint ticksPerFrameUniform = _openGL_state->rgb_shader_program->get_uniform_location("ticksPerFrame");
|
||||||
|
GLint scanNormalUniform = _openGL_state->rgb_shader_program->get_uniform_location("scanNormal");
|
||||||
|
GLint positionConversionUniform = _openGL_state->rgb_shader_program->get_uniform_location("positionConversion");
|
||||||
|
|
||||||
|
glUniform1i(texIDUniform, first_supplied_buffer_texture_unit);
|
||||||
|
glUniform1i(shadowMaskTexIDUniform, 1);
|
||||||
|
glUniform2f(textureSizeUniform, CRTInputBufferBuilderWidth, CRTInputBufferBuilderHeight);
|
||||||
|
glUniform1f(ticksPerFrameUniform, (GLfloat)(_cycles_per_line * _height_of_display));
|
||||||
|
glUniform2f(positionConversionUniform, _horizontal_flywheel->get_scan_period(), _vertical_flywheel->get_scan_period() / (unsigned int)_vertical_flywheel_output_divider);
|
||||||
|
|
||||||
|
float scan_angle = atan2f(1.0f / (float)_height_of_display, 1.0f);
|
||||||
|
float scan_normal[] = { -sinf(scan_angle), cosf(scan_angle)};
|
||||||
|
float multiplier = (float)_horizontal_flywheel->get_standard_period() / ((float)_height_of_display * (float)_horizontal_flywheel->get_scan_period());
|
||||||
|
scan_normal[0] *= multiplier;
|
||||||
|
scan_normal[1] *= multiplier;
|
||||||
|
glUniform2f(scanNormalUniform, scan_normal[0], scan_normal[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(vertex_shader);
|
||||||
|
free(fragment_shader);
|
||||||
|
}*/
|
||||||
|
|
||||||
void CRT::prepare_rgb_output_shader()
|
void CRT::prepare_rgb_output_shader()
|
||||||
{
|
{
|
||||||
char *vertex_shader = get_output_vertex_shader();
|
char *vertex_shader = get_output_vertex_shader();
|
||||||
@ -459,11 +495,6 @@ void CRT::prepare_rgb_output_shader()
|
|||||||
|
|
||||||
_openGL_state->rgb_shader_program->bind();
|
_openGL_state->rgb_shader_program->bind();
|
||||||
|
|
||||||
_openGL_state->positionAttribute = _openGL_state->rgb_shader_program->get_attrib_location("position");
|
|
||||||
_openGL_state->textureCoordinatesAttribute = _openGL_state->rgb_shader_program->get_attrib_location("srcCoordinates");
|
|
||||||
_openGL_state->lateralAttribute = _openGL_state->rgb_shader_program->get_attrib_location("lateral");
|
|
||||||
_openGL_state->timestampAttribute = _openGL_state->rgb_shader_program->get_attrib_location("timestamp");
|
|
||||||
|
|
||||||
_openGL_state->windowSizeUniform = _openGL_state->rgb_shader_program->get_uniform_location("windowSize");
|
_openGL_state->windowSizeUniform = _openGL_state->rgb_shader_program->get_uniform_location("windowSize");
|
||||||
_openGL_state->boundsSizeUniform = _openGL_state->rgb_shader_program->get_uniform_location("boundsSize");
|
_openGL_state->boundsSizeUniform = _openGL_state->rgb_shader_program->get_uniform_location("boundsSize");
|
||||||
_openGL_state->boundsOriginUniform = _openGL_state->rgb_shader_program->get_uniform_location("boundsOrigin");
|
_openGL_state->boundsOriginUniform = _openGL_state->rgb_shader_program->get_uniform_location("boundsOrigin");
|
||||||
@ -494,18 +525,26 @@ void CRT::prepare_rgb_output_shader()
|
|||||||
free(fragment_shader);
|
free(fragment_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRT::prepare_vertex_array()
|
void CRT::prepare_output_vertex_array()
|
||||||
{
|
{
|
||||||
glEnableVertexAttribArray((GLuint)_openGL_state->positionAttribute);
|
if(_openGL_state->rgb_shader_program)
|
||||||
glEnableVertexAttribArray((GLuint)_openGL_state->textureCoordinatesAttribute);
|
{
|
||||||
glEnableVertexAttribArray((GLuint)_openGL_state->lateralAttribute);
|
GLint positionAttribute = _openGL_state->rgb_shader_program->get_attrib_location("position");
|
||||||
glEnableVertexAttribArray((GLuint)_openGL_state->timestampAttribute);
|
GLint textureCoordinatesAttribute = _openGL_state->rgb_shader_program->get_attrib_location("srcCoordinates");
|
||||||
|
GLint lateralAttribute = _openGL_state->rgb_shader_program->get_attrib_location("lateral");
|
||||||
|
GLint timestampAttribute = _openGL_state->rgb_shader_program->get_attrib_location("timestamp");
|
||||||
|
|
||||||
const GLsizei vertexStride = kCRTOutputVertexSize;
|
glEnableVertexAttribArray((GLuint)positionAttribute);
|
||||||
glVertexAttribPointer((GLuint)_openGL_state->positionAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)kCRTOutputVertexOffsetOfPosition);
|
glEnableVertexAttribArray((GLuint)textureCoordinatesAttribute);
|
||||||
glVertexAttribPointer((GLuint)_openGL_state->textureCoordinatesAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)kCRTOutputVertexOffsetOfTexCoord);
|
glEnableVertexAttribArray((GLuint)lateralAttribute);
|
||||||
glVertexAttribPointer((GLuint)_openGL_state->timestampAttribute, 4, GL_UNSIGNED_INT, GL_FALSE, vertexStride, (void *)kCRTOutputVertexOffsetOfTimestamp);
|
glEnableVertexAttribArray((GLuint)timestampAttribute);
|
||||||
glVertexAttribPointer((GLuint)_openGL_state->lateralAttribute, 1, GL_UNSIGNED_BYTE, GL_FALSE, vertexStride, (void *)kCRTOutputVertexOffsetOfLateral);
|
|
||||||
|
const GLsizei vertexStride = kCRTOutputVertexSize;
|
||||||
|
glVertexAttribPointer((GLuint)positionAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)kCRTOutputVertexOffsetOfPosition);
|
||||||
|
glVertexAttribPointer((GLuint)textureCoordinatesAttribute, 2, GL_UNSIGNED_SHORT, GL_FALSE, vertexStride, (void *)kCRTOutputVertexOffsetOfTexCoord);
|
||||||
|
glVertexAttribPointer((GLuint)timestampAttribute, 4, GL_UNSIGNED_INT, GL_FALSE, vertexStride, (void *)kCRTOutputVertexOffsetOfTimestamp);
|
||||||
|
glVertexAttribPointer((GLuint)lateralAttribute, 1, GL_UNSIGNED_BYTE, GL_FALSE, vertexStride, (void *)kCRTOutputVertexOffsetOfLateral);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Configuration
|
#pragma mark - Configuration
|
||||||
|
Loading…
Reference in New Issue
Block a user