mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-26 15:32:04 +00:00
Fixed those issues breaking GL state, I hope.
This commit is contained in:
parent
4ec4cceb84
commit
6982e945fb
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -95,7 +95,6 @@ void Shader::bind()
|
||||
glUseProgram(_shader_program);
|
||||
bound_shader = this;
|
||||
}
|
||||
else printf("-");
|
||||
}
|
||||
|
||||
void Shader::unbind()
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user