mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-03 22:33:29 +00:00
Added a very basic attempt at shadow mask emulation.
This commit is contained in:
parent
63b648be65
commit
5feef2110f
@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
21
OSBindings/Mac/Clock Signal/Assets.xcassets/ShadowMask.imageset/Contents.json
vendored
Normal file
21
OSBindings/Mac/Clock Signal/Assets.xcassets/ShadowMask.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "ShadowMask.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
BIN
OSBindings/Mac/Clock Signal/Assets.xcassets/ShadowMask.imageset/ShadowMask.png
vendored
Normal file
BIN
OSBindings/Mac/Clock Signal/Assets.xcassets/ShadowMask.imageset/ShadowMask.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
@ -8,6 +8,7 @@
|
||||
|
||||
#import "CSCathodeRayView.h"
|
||||
@import CoreVideo;
|
||||
@import GLKit;
|
||||
#import <OpenGL/gl3.h>
|
||||
#import <OpenGL/gl3ext.h>
|
||||
#import <libkern/OSAtomic.h>
|
||||
@ -23,11 +24,10 @@
|
||||
GLint _textureCoordinatesAttribute;
|
||||
GLint _lateralAttribute;
|
||||
|
||||
GLint _texIDUniform;
|
||||
GLint _textureSizeUniform;
|
||||
GLint _textureSizeUniform, _windowSizeUniform;
|
||||
GLint _alphaUniform;
|
||||
|
||||
GLuint _textureName;
|
||||
GLuint _textureName, _shadowMaskTextureName;
|
||||
CRTSize _textureSize;
|
||||
|
||||
CRTFrame *_crtFrame;
|
||||
@ -37,6 +37,24 @@
|
||||
int32_t _compiledSignalDecoderGeneration;
|
||||
}
|
||||
|
||||
- (GLuint)textureForImageNamed:(NSString *)name
|
||||
{
|
||||
NSImage *const image = [NSImage imageNamed:name];
|
||||
NSBitmapImageRep *bitmapRepresentation = [[NSBitmapImageRep alloc] initWithData: [image TIFFRepresentation]];
|
||||
|
||||
GLuint textureName;
|
||||
glGenTextures(1, &textureName);
|
||||
glBindTexture(GL_TEXTURE_2D, textureName);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)image.size.width, (GLsizei)image.size.height, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmapRepresentation.bitmapData);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
return textureName;
|
||||
}
|
||||
|
||||
- (void)prepareOpenGL
|
||||
{
|
||||
// Synchronize buffer swaps with vertical refresh rate
|
||||
@ -54,6 +72,13 @@
|
||||
CGLPixelFormatObj cglPixelFormat = [[self pixelFormat] CGLPixelFormatObj];
|
||||
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, cglContext, cglPixelFormat);
|
||||
|
||||
// install the shadow mask texture as the second texture
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
_shadowMaskTextureName = [self textureForImageNamed:@"ShadowMask"];
|
||||
|
||||
// otherwise, we'll be working on the first texture
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
// get the shader ready, set the clear colour
|
||||
[self.openGLContext makeCurrentContext];
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
@ -87,6 +112,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
||||
glDeleteBuffers(1, &_arrayBuffer);
|
||||
glDeleteVertexArrays(1, &_vertexArray);
|
||||
glDeleteTextures(1, &_textureName);
|
||||
glDeleteTextures(1, &_shadowMaskTextureName);
|
||||
glDeleteProgram(_shaderProgram);
|
||||
}
|
||||
|
||||
@ -101,6 +127,8 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
||||
NSPoint viewSize = [self convertPointToBacking:backingSize];
|
||||
glViewport(0, 0, (GLsizei)viewSize.x, (GLsizei)viewSize.y);
|
||||
|
||||
glUniform2f(_windowSizeUniform, (GLfloat)viewSize.x, (GLfloat)viewSize.y);
|
||||
|
||||
CGLUnlockContext([[self openGLContext] CGLContextObj]);
|
||||
}
|
||||
|
||||
@ -186,9 +214,12 @@ static NSString *const vertexShader =
|
||||
"out vec2 srcCoordinatesVarying[4];\n"
|
||||
"out float lateralVarying;\n"
|
||||
"out float phase;\n"
|
||||
"out vec2 shadowMaskCoordinates;\n"
|
||||
"\n"
|
||||
"uniform vec2 textureSize;\n"
|
||||
"\n"
|
||||
"const float shadowMaskMultiple = 300;\n"
|
||||
"\n"
|
||||
"void main (void)\n"
|
||||
"{\n"
|
||||
"srcCoordinatesVarying[0] = vec2(srcCoordinates.x / textureSize.x, (srcCoordinates.y + 0.5) / textureSize.y);\n"
|
||||
@ -200,6 +231,8 @@ static NSString *const vertexShader =
|
||||
"lateralVarying = lateral + 1.0707963267949;\n"
|
||||
"phase = srcCoordinates.x * 6.283185308;\n"
|
||||
"\n"
|
||||
"shadowMaskCoordinates = position * vec2(shadowMaskMultiple, shadowMaskMultiple * 0.85057471264368);\n"
|
||||
"\n"
|
||||
"gl_Position = vec4(position.x * 2.0 - 1.0, 1.0 - position.y * 2.0 + position.x / 131.0, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
@ -211,13 +244,18 @@ static NSString *const fragmentShader =
|
||||
"in vec2 srcCoordinatesVarying[4];\n"
|
||||
"in float lateralVarying;\n"
|
||||
"in float phase;\n"
|
||||
"in vec2 shadowMaskCoordinates;\n"
|
||||
"out vec4 fragColour;\n"
|
||||
"\n"
|
||||
"uniform sampler2D texID;\n"
|
||||
"uniform sampler2D shadowMaskTexID;\n"
|
||||
"uniform float alpha;\n"
|
||||
"\n"
|
||||
"%@"
|
||||
"\n"
|
||||
"// for conversion from i and q are in the range [-0.5, 0.5] (so i needs to be multiplied by 1.1914 and q by 1.0452)\n"
|
||||
"const mat3 yiqToRGB = mat3(1.0, 1.0, 1.0, 1.1389784, -0.3240608, -1.3176884, 0.6490692, -0.6762444, 1.7799756);\n"
|
||||
"\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
"vec4 angles = vec4(phase) + vec4(-2.35619449019234, -0.78539816339745, 0.78539816339745, 2.35619449019234);\n"
|
||||
@ -234,9 +272,7 @@ static NSString *const fragmentShader =
|
||||
"float i = dot(cos(angles), samples);\n"
|
||||
"float q = dot(sin(angles), samples);\n"
|
||||
"\n"
|
||||
"// now i and q are in the range [-0.5, 0.5], so i needs to be multiplied by 1.1914 and q by 1.0452\n"
|
||||
"const mat3 yiqToRGB = mat3(1.0, 1.0, 1.0, 1.1389784, -0.3240608, -1.3176884, 0.6490692, -0.6762444, 1.7799756);\n"
|
||||
"fragColour = vec4( yiqToRGB * vec3(y, i, q), 1.0);//sin(lateralVarying));\n"
|
||||
"fragColour = 5.0 * texture(shadowMaskTexID, shadowMaskCoordinates) * vec4(yiqToRGB * vec3(y, i, q), 1.0);//sin(lateralVarying));\n"
|
||||
"}\n";
|
||||
|
||||
#if defined(DEBUG)
|
||||
@ -306,9 +342,15 @@ static NSString *const fragmentShader =
|
||||
_positionAttribute = glGetAttribLocation(_shaderProgram, "position");
|
||||
_textureCoordinatesAttribute = glGetAttribLocation(_shaderProgram, "srcCoordinates");
|
||||
_lateralAttribute = glGetAttribLocation(_shaderProgram, "lateral");
|
||||
_texIDUniform = glGetUniformLocation(_shaderProgram, "texID");
|
||||
_alphaUniform = glGetUniformLocation(_shaderProgram, "alpha");
|
||||
_textureSizeUniform = glGetUniformLocation(_shaderProgram, "textureSize");
|
||||
_windowSizeUniform = glGetUniformLocation(_shaderProgram, "windowSize");
|
||||
|
||||
GLint texIDUniform = glGetUniformLocation(_shaderProgram, "texID");
|
||||
GLint shadowMaskTexIDUniform = glGetUniformLocation(_shaderProgram, "shadowMaskTexID");
|
||||
|
||||
glUniform1i(texIDUniform, 0);
|
||||
glUniform1i(shadowMaskTexIDUniform, 1);
|
||||
|
||||
glEnableVertexAttribArray((GLuint)_positionAttribute);
|
||||
glEnableVertexAttribArray((GLuint)_textureCoordinatesAttribute);
|
||||
|
Loading…
x
Reference in New Issue
Block a user