From caf9557a4c3cfc594c9aad42de9bc5bd691634f2 Mon Sep 17 00:00:00 2001
From: Alexander Rose <alex.rose@rcsb.org>
Date: Fri, 5 Oct 2018 17:13:43 -0700
Subject: [PATCH] texture/renderTarget filter support

---
 src/mol-gl/renderable/schema.ts   | 17 ++++++++++-------
 src/mol-gl/renderable/util.ts     |  6 +++---
 src/mol-gl/webgl/render-target.ts | 10 ++++++----
 src/mol-gl/webgl/texture.ts       | 20 ++++++++++++++------
 4 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/src/mol-gl/renderable/schema.ts b/src/mol-gl/renderable/schema.ts
index f7b7ca4de..ed784e524 100644
--- a/src/mol-gl/renderable/schema.ts
+++ b/src/mol-gl/renderable/schema.ts
@@ -10,7 +10,7 @@ import { UniformKind, UniformValues } from '../webgl/uniform';
 import { DefineKind, DefineValues } from '../shader-code';
 import { Vec2, Vec3, Vec4, Mat3, Mat4 } from 'mol-math/linear-algebra';
 import { TextureImage } from './util';
-import { TextureValues, TextureType, TextureFormat } from '../webgl/texture';
+import { TextureValues, TextureType, TextureFormat, TextureFilter } from '../webgl/texture';
 
 export type ValueKindType = {
     'number': number
@@ -84,9 +84,9 @@ export function UniformSpec<K extends UniformKind>(kind: K): UniformSpec<K> {
     return { type: 'uniform', kind }
 }
 
-export type TextureSpec = { type: 'texture', kind: 'image', format: TextureFormat, dataType: TextureType }
-export function TextureSpec(format: TextureFormat, dataType: TextureType): TextureSpec {
-    return { type: 'texture', kind: 'image', format, dataType }
+export type TextureSpec = { type: 'texture', kind: 'image', format: TextureFormat, dataType: TextureType, filter: TextureFilter }
+export function TextureSpec(format: TextureFormat, dataType: TextureType, filter: TextureFilter): TextureSpec {
+    return { type: 'texture', kind: 'image', format, dataType, filter }
 }
 
 export type ElementsSpec<K extends ElementsKind> = { type: 'elements', kind: K }
@@ -119,6 +119,9 @@ export type RenderableValues = { [k: string]: ValueCell<any> }
 export const GlobalUniformSchema = {
     uModel: UniformSpec('m4'),
     uView: UniformSpec('m4'),
+    uInvView: UniformSpec('m4'),
+    uModelView: UniformSpec('m4'),
+    uInvModelView: UniformSpec('m4'),
     uProjection: UniformSpec('m4'),
     // uLightPosition: Uniform('v3'),
     uLightColor: UniformSpec('v3'),
@@ -145,7 +148,7 @@ export const ColorSchema = {
     aColor: AttributeSpec('float32', 3, 0),
     uColor: UniformSpec('v3'),
     uColorTexDim: UniformSpec('v2'),
-    tColor: TextureSpec('rgb', 'ubyte'),
+    tColor: TextureSpec('rgb', 'ubyte', 'nearest'),
     dColorType: DefineSpec('string', ['uniform', 'attribute', 'instance', 'group', 'group_instance']),
 }
 export type ColorSchema = typeof ColorSchema
@@ -155,7 +158,7 @@ export const SizeSchema = {
     aSize: AttributeSpec('float32', 1, 0),
     uSize: UniformSpec('f'),
     uSizeTexDim: UniformSpec('v2'),
-    tSize: TextureSpec('alpha', 'ubyte'),
+    tSize: TextureSpec('alpha', 'ubyte', 'nearest'),
     dSizeType: DefineSpec('string', ['uniform', 'attribute', 'instance', 'group', 'group_instance']),
 }
 export type SizeSchema = typeof SizeSchema
@@ -173,7 +176,7 @@ export const BaseSchema = {
     uGroupCount: UniformSpec('i'),
     uMarkerTexDim: UniformSpec('v2'),
 
-    tMarker: TextureSpec('alpha', 'ubyte'),
+    tMarker: TextureSpec('alpha', 'ubyte', 'nearest'),
 
     drawCount: ValueSpec('number'),
     instanceCount: ValueSpec('number'),
diff --git a/src/mol-gl/renderable/util.ts b/src/mol-gl/renderable/util.ts
index 9f64d61e8..86f3a8565 100644
--- a/src/mol-gl/renderable/util.ts
+++ b/src/mol-gl/renderable/util.ts
@@ -17,9 +17,9 @@ export function calculateTextureInfo (n: number, itemSize: number) {
 }
 
 export interface TextureImage {
-    array: Uint8Array
-    width: number
-    height: number
+    readonly array: Uint8Array
+    readonly width: number
+    readonly height: number
 }
 
 export function createTextureImage (n: number, itemSize: number): TextureImage {
diff --git a/src/mol-gl/webgl/render-target.ts b/src/mol-gl/webgl/render-target.ts
index 4f2e4d81d..bce6528dd 100644
--- a/src/mol-gl/webgl/render-target.ts
+++ b/src/mol-gl/webgl/render-target.ts
@@ -6,7 +6,7 @@
 
 import { Context, createImageData } from './context'
 import { idFactory } from 'mol-util/id-factory';
-import { createTexture } from './texture';
+import { createTexture, Texture } from './texture';
 import { createFramebuffer } from './framebuffer';
 import { createRenderbuffer } from './renderbuffer';
 import { TextureImage } from '../renderable/util';
@@ -17,7 +17,8 @@ export interface RenderTarget {
     readonly id: number
     readonly width: number
     readonly height: number
-    readonly image: Readonly<TextureImage>
+    readonly image: TextureImage
+    readonly texture: Texture
 
     bind: () => void
     setSize: (width: number, height: number) => void
@@ -30,13 +31,13 @@ export interface RenderTarget {
 export function createRenderTarget (ctx: Context, _width: number, _height: number): RenderTarget {
     const { gl } = ctx
 
-    const image: TextureImage = {
+    const image: Helpers.Mutable<TextureImage> = {
         array: new Uint8Array(_width * _height * 4),
         width: _width,
         height: _height
     }
 
-    const targetTexture = createTexture(ctx, 'rgba', 'ubyte')
+    const targetTexture = createTexture(ctx, 'rgba', 'ubyte', 'linear')
     targetTexture.load(image)
 
     const framebuffer = createFramebuffer(ctx)
@@ -64,6 +65,7 @@ export function createRenderTarget (ctx: Context, _width: number, _height: numbe
         get width () { return _width },
         get height () { return _height },
         image,
+        texture: targetTexture,
 
         bind: () => {
             framebuffer.bind()
diff --git a/src/mol-gl/webgl/texture.ts b/src/mol-gl/webgl/texture.ts
index e6bf1a498..72f0bc3f9 100644
--- a/src/mol-gl/webgl/texture.ts
+++ b/src/mol-gl/webgl/texture.ts
@@ -16,6 +16,7 @@ const getNextTextureId = idFactory()
 export type TextureFormat = 'alpha' | 'rgb' | 'rgba'
 export type TextureType = 'ubyte' | 'uint'
 export type TextureAttachment = 'depth' | 'stencil' | 'color0'
+export type TextureFilter = 'nearest' | 'linear'
 
 export function getFormat(ctx: Context, format: TextureFormat) {
     const { gl } = ctx
@@ -34,6 +35,14 @@ export function getType(ctx: Context, type: TextureType) {
     }
 }
 
+export function getFilter(ctx: Context, type: TextureFilter) {
+    const { gl } = ctx
+    switch (type) {
+        case 'nearest': return gl.NEAREST
+        case 'linear': return gl.LINEAR
+    }
+}
+
 export function getAttachment(ctx: Context, attachment: TextureAttachment) {
     const { gl } = ctx
     switch (attachment) {
@@ -63,7 +72,7 @@ export type TextureId = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 1
 export type TextureValues = { [k: string]: ValueCell<TextureImage> }
 export type Textures = { [k: string]: Texture }
 
-export function createTexture(ctx: Context, _format: TextureFormat, _type: TextureType): Texture {
+export function createTexture(ctx: Context, _format: TextureFormat, _type: TextureType, _filter: TextureFilter): Texture {
     const id = getNextTextureId()
     const { gl } = ctx
     const texture = gl.createTexture()
@@ -71,8 +80,7 @@ export function createTexture(ctx: Context, _format: TextureFormat, _type: Textu
         throw new Error('Could not create WebGL texture')
     }
 
-    const magFilter = gl.NEAREST
-    const minFilter = gl.NEAREST
+    const filter = getFilter(ctx, _filter)
     const format = getFormat(ctx, _format)
     const type = getType(ctx, _type)
 
@@ -99,8 +107,8 @@ export function createTexture(ctx: Context, _format: TextureFormat, _type: Textu
             gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, type, array)
             _width = width
             _height = height
-            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter)
-            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter)
+            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter)
+            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter)
             // clamp-to-edge needed for non-power-of-two textures
             gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
             gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
@@ -132,7 +140,7 @@ export function createTextures(ctx: Context, schema: RenderableSchema, values: T
     Object.keys(schema).forEach((k, i) => {
         const spec = schema[k]
         if (spec.type === 'texture') {
-            const texture = createTexture(ctx, spec.format, spec.dataType)
+            const texture = createTexture(ctx, spec.format, spec.dataType, spec.filter)
             texture.load(values[k].ref.value)
             textures[k] = texture
         }
-- 
GitLab