Skip to content
Snippets Groups Projects
Commit faffcda8 authored by Alexander Rose's avatar Alexander Rose
Browse files

refactored texture to allowdifferent formats and types

parent 42317e49
No related branches found
No related tags found
No related merge requests found
......@@ -10,6 +10,7 @@ import { UniformKind } from '../webgl/uniform';
import { DefineKind } 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';
export type ValueKindType = {
'number': number
......@@ -60,9 +61,9 @@ export function UniformSpec<K extends UniformKind>(kind: K): UniformSpec<K> {
return { type: 'uniform', kind }
}
export type TextureSpec = { type: 'texture', kind: 'image' }
export function TextureSpec(): TextureSpec {
return { type: 'texture', kind: 'image' }
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 ElementsSpec<K extends ElementsKind> = { type: 'elements', kind: K }
......@@ -120,7 +121,7 @@ export const BaseSchema = {
uColorTexSize: UniformSpec('v2'),
uColor: UniformSpec('v3'),
tColor: TextureSpec(),
tColor: TextureSpec('rgb', 'ubyte'),
drawCount: ValueSpec('number'),
instanceCount: ValueSpec('number'),
......
......@@ -11,11 +11,39 @@ import { RenderableSchema } from '../renderable/schema';
import { idFactory } from 'mol-util/id-factory';
const getNextTextureId = idFactory()
export type TextureFormat = 'rgb' | 'rgba'
export type TextureType = 'ubyte' | 'uint'
export function getFormat(ctx: Context, format: TextureFormat) {
const { gl } = ctx
switch (format) {
case 'rgb': return gl.RGB
case 'rgba': return gl.RGBA
}
}
export function getType(ctx: Context, type: TextureType) {
const { gl } = ctx
switch (type) {
case 'ubyte': return gl.UNSIGNED_BYTE
case 'uint': return gl.UNSIGNED_INT
}
}
export interface Texture {
readonly id: number
readonly texture: WebGLTexture
readonly format: number
readonly type: number
readonly width: number
readonly height: number
load: (image: TextureImage) => void
bind: (id: TextureId) => void
unbind: (id: TextureId) => void
setSize: (width: number, height: number) => void
destroy: () => void
}
......@@ -24,7 +52,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): Texture {
export function createTexture(ctx: Context, _format: TextureFormat, _type: TextureType): Texture {
const id = getNextTextureId()
const { gl } = ctx
const texture = gl.createTexture()
......@@ -32,39 +60,54 @@ export function createTexture(ctx: Context): Texture {
throw new Error('Could not create WebGL texture')
}
const _textureType = gl.TEXTURE_2D
const _magFilter = gl.NEAREST
const _minFilter = gl.NEAREST
const _format = gl.RGB
const _arrayType = gl.UNSIGNED_BYTE
const magFilter = gl.NEAREST
const minFilter = gl.NEAREST
const format = getFormat(ctx, _format)
const type = getType(ctx, _type)
let _width = 0
let _height = 0
let destroyed = false
ctx.textureCount += 1
return {
id,
texture,
format,
type,
get width () { return _width },
get height () { return _height },
load: (image: TextureImage) => {
const { array, width, height } = image
gl.bindTexture(_textureType, texture)
gl.bindTexture(gl.TEXTURE_2D, texture)
// unpack alignment of 1 since we use textures only for data
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
gl.texImage2D(_textureType, 0, _format, width, height, 0, _format, _arrayType, array)
gl.texParameteri(_textureType, gl.TEXTURE_MAG_FILTER, _magFilter)
gl.texParameteri(_textureType, gl.TEXTURE_MIN_FILTER, _minFilter)
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)
// clamp-to-edge needed for non-power-of-two textures
gl.texParameteri(_textureType, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(_textureType, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.bindTexture(_textureType, null)
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);
gl.bindTexture(gl.TEXTURE_2D, null)
},
bind: (id: TextureId) => {
gl.activeTexture(gl.TEXTURE0 + id)
gl.bindTexture(_textureType, texture)
gl.bindTexture(gl.TEXTURE_2D, texture)
},
unbind: (id: TextureId) => {
gl.activeTexture(gl.TEXTURE0 + id)
gl.bindTexture(_textureType, null)
gl.bindTexture(gl.TEXTURE_2D, null)
},
setSize: (width: number, height: number) => {
gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, type, null)
_width = width
_height = height
},
destroy: () => {
if (destroyed) return
gl.deleteTexture(texture)
......@@ -79,7 +122,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)
const texture = createTexture(ctx, spec.format, spec.dataType)
texture.load(values[k].ref.value)
textures[k] = texture
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment