1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-01 13:58:20 +00:00

Fixed those issues breaking GL state, I hope.

This commit is contained in:
Thomas Harte 2016-05-01 16:17:52 -04:00
parent 4ec4cceb84
commit 6982e945fb
6 changed files with 80 additions and 35 deletions

View File

@ -66,12 +66,15 @@
}
- (void)clearAllKeys {
@synchronized(self) {
_electron.clear_all_keys();
}
// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
@synchronized(self) {
_electron.clear_all_keys();
}
// });
}
- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed {
// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
@synchronized(self) {
switch(key)
{
@ -149,13 +152,16 @@
break;
}
}
// });
}
- (void)setUseFastLoadingHack:(BOOL)useFastLoadingHack {
@synchronized(self) {
_useFastLoadingHack = useFastLoadingHack;
_electron.set_use_fast_tape_hack(useFastLoadingHack ? true : false);
}
// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
@synchronized(self) {
_useFastLoadingHack = useFastLoadingHack;
_electron.set_use_fast_tape_hack(useFastLoadingHack ? true : false);
}
// });
}
- (void)setUseTelevisionOutput:(BOOL)useTelevisionOutput {

View File

@ -78,6 +78,7 @@ namespace {
static const GLenum filtered_y_texture_unit = GL_TEXTURE1;
static const GLenum filtered_texture_unit = GL_TEXTURE2;
static const GLenum source_data_texture_unit = GL_TEXTURE3;
static const GLenum pixel_accumulation_texture_unit = GL_TEXTURE4;
}
OpenGLOutputBuilder::OpenGLOutputBuilder(unsigned int buffer_depth) :
@ -103,15 +104,9 @@ OpenGLOutputBuilder::OpenGLOutputBuilder(unsigned int buffer_depth) :
glBlendColor(0.4f, 0.4f, 0.4f, 0.5f);
// Create intermediate textures and bind to slots 0, 1 and 2
glActiveTexture(composite_texture_unit);
compositeTexture = std::unique_ptr<OpenGL::TextureTarget>(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight));
compositeTexture->bind_texture();
glActiveTexture(filtered_y_texture_unit);
filteredYTexture = std::unique_ptr<OpenGL::TextureTarget>(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight));
filteredYTexture->bind_texture();
glActiveTexture(filtered_texture_unit);
filteredTexture = std::unique_ptr<OpenGL::TextureTarget>(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight));
filteredTexture->bind_texture();
compositeTexture = std::unique_ptr<OpenGL::TextureTarget>(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight, composite_texture_unit));
filteredYTexture = std::unique_ptr<OpenGL::TextureTarget>(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight, filtered_y_texture_unit));
filteredTexture = std::unique_ptr<OpenGL::TextureTarget>(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight, filtered_texture_unit));
// create the surce texture
glGenTextures(1, &textureName);
@ -153,9 +148,6 @@ OpenGLOutputBuilder::OpenGLOutputBuilder(unsigned int buffer_depth) :
// map that buffer too, for any CRT activity that may occur before the first draw
_source_buffer_data = (uint8_t *)glMapBufferRange(GL_ARRAY_BUFFER, 0, SourceVertexBufferDataSize, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
// map back the default framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
OpenGLOutputBuilder::~OpenGLOutputBuilder()
@ -196,6 +188,21 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
defaultFramebuffer = 0;
}
// make sure there's a target to draw to
if(!framebuffer || framebuffer->get_height() != output_height || framebuffer->get_width() != output_width)
{
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
std::unique_ptr<OpenGL::TextureTarget> new_framebuffer = std::unique_ptr<OpenGL::TextureTarget>(new OpenGL::TextureTarget((GLsizei)output_width, (GLsizei)output_height, pixel_accumulation_texture_unit));
if(framebuffer)
{
new_framebuffer->bind_framebuffer();
framebuffer->draw((float)output_width / (float)output_height);
}
framebuffer = std::move(new_framebuffer);
glActiveTexture(source_data_texture_unit);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _input_texture_array);
}
// lock down any further work on the current frame
_output_mutex->lock();
@ -288,11 +295,6 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
glDrawArrays(GL_LINES, drawing_zones[c*2] / SourceVertexSize, drawing_zones[c*2 + 1] / SourceVertexSize);
}
}
// switch back to screen output
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
glViewport(0, 0, (GLsizei)output_width, (GLsizei)output_height);
glClearColor(0.0, 0.0, 0.0, 1.0);
}
// transfer to screen
@ -317,6 +319,9 @@ void OpenGLOutputBuilder::perform_output_stage(unsigned int output_width, unsign
{
if(shader)
{
// bind the target
framebuffer->bind_framebuffer();
// draw all pending lines
GLsizei drawing_zones[4];
int number_of_drawing_zones = getCircularRanges(_drawn_output_buffer_data_pointer, _output_buffer_data_pointer, OutputVertexBufferDataSize, 6*OutputVertexSize, drawing_zones);
@ -349,6 +354,11 @@ void OpenGLOutputBuilder::perform_output_stage(unsigned int output_width, unsign
glDrawArrays(GL_TRIANGLE_STRIP, drawing_zones[c*2] / OutputVertexSize, drawing_zones[c*2 + 1] / OutputVertexSize);
}
}
// copy to the intended place
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT);
framebuffer->draw((float)output_width / (float)output_height);
}
}

View File

@ -77,6 +77,8 @@ class OpenGLOutputBuilder {
std::unique_ptr<OpenGL::TextureTarget> filteredYTexture; // receives filtered Y in the R channel plus unfiltered I/U and Q/V in G and B
std::unique_ptr<OpenGL::TextureTarget> filteredTexture; // receives filtered YIQ or YUV
std::unique_ptr<OpenGL::TextureTarget> framebuffer; // the current pixel output
void perform_output_stage(unsigned int output_width, unsigned int output_height, OpenGL::OutputShader *const shader);
void set_timing_uniforms();
void set_colour_space_uniforms();

View File

@ -95,7 +95,6 @@ void Shader::bind()
glUseProgram(_shader_program);
bound_shader = this;
}
else printf("-");
}
void Shader::unbind()

View File

@ -7,23 +7,29 @@
//
#include "TextureTarget.hpp"
#include <math.h>
using namespace OpenGL;
TextureTarget::TextureTarget(GLsizei width, GLsizei height) :
TextureTarget::TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit) :
_width(width),
_height(height),
_pixel_shader(nullptr),
_drawing_vertex_array(0),
_drawing_array_buffer(0),
_set_aspect_ratio(0.0f)
_set_aspect_ratio(0.0f),
_texture_unit(texture_unit)
{
glGenFramebuffers(1, &_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
_expanded_width = 1 << (GLsizei)ceil(log2(width));
_expanded_height = 1 << (GLsizei)ceil(log2(height));
glGenTextures(1, &_texture);
glActiveTexture(texture_unit);
glBindTexture(GL_TEXTURE_2D, _texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)_expanded_width, (GLsizei)_expanded_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@ -52,7 +58,7 @@ void TextureTarget::bind_texture()
glBindTexture(GL_TEXTURE_2D, _texture);
}
void TextureTarget::draw(float aspect_ratio, GLenum texture_unit)
void TextureTarget::draw(float aspect_ratio)
{
if(!_pixel_shader)
{
@ -86,8 +92,8 @@ void TextureTarget::draw(float aspect_ratio, GLenum texture_unit)
glGenVertexArrays(1, &_drawing_vertex_array);
glGenBuffers(1, &_drawing_array_buffer);
glBindVertexArray(_drawing_array_buffer);
glBindBuffer(GL_ARRAY_BUFFER, _drawing_vertex_array);
glBindVertexArray(_drawing_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, _drawing_array_buffer);
GLint positionAttribute = _pixel_shader->get_attrib_location("position");
GLint texCoordAttribute = _pixel_shader->get_attrib_location("texCoord");
@ -98,6 +104,9 @@ void TextureTarget::draw(float aspect_ratio, GLenum texture_unit)
const GLsizei vertexStride = 12;
glVertexAttribPointer((GLuint)positionAttribute, 2, GL_FLOAT, GL_FALSE, vertexStride, (void *)0);
glVertexAttribPointer((GLuint)texCoordAttribute, 2, GL_BYTE, GL_FALSE, vertexStride, (void *)(2 * sizeof(GLfloat)));
GLint texIDUniform = _pixel_shader->get_uniform_location("texID");
glUniform1i(texIDUniform, (GLint)(_texture_unit - GL_TEXTURE0));
}
if(_set_aspect_ratio != aspect_ratio)
@ -133,7 +142,7 @@ void TextureTarget::draw(float aspect_ratio, GLenum texture_unit)
}
// upload buffer
glBindBuffer(GL_ARRAY_BUFFER, _drawing_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, _drawing_array_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(buffer), buffer, GL_STATIC_DRAW);
}

View File

@ -24,12 +24,13 @@ class TextureTarget {
/*!
Creates a new texture target.
Throws ErrorFramebufferIncomplete if creation fails.
Throws ErrorFramebufferIncomplete if creation fails. Leaves both the generated texture and framebuffer bound.
@param width The width of target to create.
@param height The height of target to create.
@param texture_unit A texture unit on which to bind the texture.
*/
TextureTarget(GLsizei width, GLsizei height);
TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit);
~TextureTarget();
/*!
@ -42,10 +43,26 @@ class TextureTarget {
*/
void bind_texture();
/*!
@returns the width of the texture target.
*/
GLsizei get_width()
{
return _width;
}
/*!
@returns the height of the texture target.
*/
GLsizei get_height()
{
return _height;
}
/*!
*/
void draw(float aspect_ratio, GLenum texture_unit);
void draw(float aspect_ratio);
enum {
ErrorFramebufferIncomplete
@ -54,6 +71,8 @@ class TextureTarget {
private:
GLuint _framebuffer, _texture;
GLsizei _width, _height;
GLsizei _expanded_width, _expanded_height;
GLenum _texture_unit;
std::unique_ptr<Shader> _pixel_shader;
GLuint _drawing_vertex_array, _drawing_array_buffer;