diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index c60adc189..fd262e6e2 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 4B14145E1B5887AA00E04248 /* CPU6502AllRAM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1414591B58879D00E04248 /* CPU6502AllRAM.cpp */; }; 4B1414601B58885000E04248 /* WolfgangLorenzTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */; }; 4B1414621B58888700E04248 /* KlausDormannTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1414611B58888700E04248 /* KlausDormannTests.swift */; }; + 4B2039941C67E20B001375C3 /* TextureTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2039921C67E20B001375C3 /* TextureTarget.cpp */; }; 4B2409551C45AB05004DA684 /* Speaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2409531C45AB05004DA684 /* Speaker.cpp */; }; 4B2E2D951C399D1200138695 /* ElectronDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2E2D931C399D1200138695 /* ElectronDocument.xib */; }; 4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */; }; @@ -340,6 +341,9 @@ 4B14145A1B58879D00E04248 /* CPU6502AllRAM.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CPU6502AllRAM.hpp; sourceTree = ""; }; 4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WolfgangLorenzTests.swift; sourceTree = ""; }; 4B1414611B58888700E04248 /* KlausDormannTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KlausDormannTests.swift; sourceTree = ""; }; + 4B2039921C67E20B001375C3 /* TextureTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureTarget.cpp; sourceTree = ""; }; + 4B2039931C67E20B001375C3 /* TextureTarget.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TextureTarget.hpp; sourceTree = ""; }; + 4B2039951C67E2A3001375C3 /* OpenGL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OpenGL.h; sourceTree = ""; }; 4B2409531C45AB05004DA684 /* Speaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Speaker.cpp; path = ../../Outputs/Speaker.cpp; sourceTree = ""; }; 4B2409541C45AB05004DA684 /* Speaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Speaker.hpp; path = ../../Outputs/Speaker.hpp; sourceTree = ""; }; 4B24095A1C45DF85004DA684 /* Stepper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Stepper.hpp; sourceTree = ""; }; @@ -690,6 +694,9 @@ 4B0CCC441C62D0B3001CAC5F /* CRTFrame.h */, 4B0CCC461C62D1A8001CAC5F /* CRTOpenGL.cpp */, 4B7BFEFD1C6446EF00089C1C /* CRTFrameBuilder.cpp */, + 4B2039921C67E20B001375C3 /* TextureTarget.cpp */, + 4B2039931C67E20B001375C3 /* TextureTarget.hpp */, + 4B2039951C67E2A3001375C3 /* OpenGL.h */, ); name = CRT; path = ../../Outputs/CRT; @@ -1608,6 +1615,7 @@ 4B55CE4B1C3B3B0C0093A61B /* CSAtari2600.mm in Sources */, 4B55CE581C3B7D360093A61B /* Atari2600Document.swift in Sources */, 4B0CCC471C62D1A8001CAC5F /* CRTOpenGL.cpp in Sources */, + 4B2039941C67E20B001375C3 /* TextureTarget.cpp in Sources */, 4B0EBFB81C487F2F00A11F35 /* AudioQueue.m in Sources */, 4B7BFEFE1C6446EF00089C1C /* CRTFrameBuilder.cpp in Sources */, 4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */, diff --git a/Outputs/CRT/CRTOpenGL.cpp b/Outputs/CRT/CRTOpenGL.cpp index 6fbabba30..e20fb1f18 100644 --- a/Outputs/CRT/CRTOpenGL.cpp +++ b/Outputs/CRT/CRTOpenGL.cpp @@ -9,9 +9,7 @@ #include "CRT.hpp" #include -// TODO: figure out correct include paths for other platforms. -#include -#include +#include "OpenGL.h" using namespace Outputs; @@ -90,6 +88,9 @@ void CRT::draw_frame(int output_width, int output_height, bool only_if_dirty) { _current_frame_mutex->lock(); + GLint defaultFramebuffer; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFramebuffer); + if(!_current_frame && !only_if_dirty) { glClear(GL_COLOR_BUFFER_BIT); diff --git a/Outputs/CRT/OpenGL.h b/Outputs/CRT/OpenGL.h new file mode 100644 index 000000000..ed9899546 --- /dev/null +++ b/Outputs/CRT/OpenGL.h @@ -0,0 +1,16 @@ +// +// OpenGL.h +// Clock Signal +// +// Created by Thomas Harte on 07/02/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#ifndef OpenGL_h +#define OpenGL_h + +// TODO: figure out correct include paths for other platforms. +#include +#include + +#endif /* OpenGL_h */ diff --git a/Outputs/CRT/TextureTarget.cpp b/Outputs/CRT/TextureTarget.cpp new file mode 100644 index 000000000..8b61dcf7a --- /dev/null +++ b/Outputs/CRT/TextureTarget.cpp @@ -0,0 +1,46 @@ +// +// TextureTarget.cpp +// Clock Signal +// +// Created by Thomas Harte on 07/02/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#include "TextureTarget.hpp" + +using namespace OpenGL; + +TextureTarget::TextureTarget(unsigned int width, unsigned int height) +{ + glGenFramebuffers(1, &_framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); + + glGenTextures(1, &_texture); + glBindTexture(GL_TEXTURE_2D, _texture); + + uint8_t *emptySpace = new uint8_t[width*height*4]; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, emptySpace); + delete[] emptySpace; + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0); + + // TODO: raise an exception if check framebuffer status fails. +// if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) +// return nil; +} + +TextureTarget::~TextureTarget() +{ + glDeleteFramebuffers(1, &_framebuffer); + glDeleteTextures(1, &_texture); +} + +void TextureTarget::bind_framebuffer() +{ + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); +} + +void TextureTarget::bind_texture() +{ + glBindTexture(GL_TEXTURE_2D, _texture); +} diff --git a/Outputs/CRT/TextureTarget.hpp b/Outputs/CRT/TextureTarget.hpp new file mode 100644 index 000000000..f98ad8305 --- /dev/null +++ b/Outputs/CRT/TextureTarget.hpp @@ -0,0 +1,30 @@ +// +// TextureTarget.hpp +// Clock Signal +// +// Created by Thomas Harte on 07/02/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#ifndef TextureTarget_hpp +#define TextureTarget_hpp + +#include "OpenGL.h" + +namespace OpenGL { + +class TextureTarget { + public: + TextureTarget(unsigned int width, unsigned int height); + ~TextureTarget(); + + void bind_framebuffer(); + void bind_texture(); + + private: + GLuint _framebuffer, _texture; +}; + +} + +#endif /* TextureTarget_hpp */