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'; ...@@ -10,6 +10,7 @@ import { UniformKind } from '../webgl/uniform';
import { DefineKind } from '../shader-code'; import { DefineKind } from '../shader-code';
import { Vec2, Vec3, Vec4, Mat3, Mat4 } from 'mol-math/linear-algebra'; import { Vec2, Vec3, Vec4, Mat3, Mat4 } from 'mol-math/linear-algebra';
import { TextureImage } from './util'; import { TextureImage } from './util';
import { TextureValues, TextureType, TextureFormat } from '../webgl/texture';
export type ValueKindType = { export type ValueKindType = {
'number': number 'number': number
...@@ -60,9 +61,9 @@ export function UniformSpec<K extends UniformKind>(kind: K): UniformSpec<K> { ...@@ -60,9 +61,9 @@ export function UniformSpec<K extends UniformKind>(kind: K): UniformSpec<K> {
return { type: 'uniform', kind } return { type: 'uniform', kind }
} }
export type TextureSpec = { type: 'texture', kind: 'image' } export type TextureSpec = { type: 'texture', kind: 'image', format: TextureFormat, dataType: TextureType }
export function TextureSpec(): TextureSpec { export function TextureSpec(format: TextureFormat, dataType: TextureType): TextureSpec {
return { type: 'texture', kind: 'image' } return { type: 'texture', kind: 'image', format, dataType }
} }
export type ElementsSpec<K extends ElementsKind> = { type: 'elements', kind: K } export type ElementsSpec<K extends ElementsKind> = { type: 'elements', kind: K }
...@@ -120,7 +121,7 @@ export const BaseSchema = { ...@@ -120,7 +121,7 @@ export const BaseSchema = {
uColorTexSize: UniformSpec('v2'), uColorTexSize: UniformSpec('v2'),
uColor: UniformSpec('v3'), uColor: UniformSpec('v3'),
tColor: TextureSpec(), tColor: TextureSpec('rgb', 'ubyte'),
drawCount: ValueSpec('number'), drawCount: ValueSpec('number'),
instanceCount: ValueSpec('number'), instanceCount: ValueSpec('number'),
......
...@@ -11,11 +11,39 @@ import { RenderableSchema } from '../renderable/schema'; ...@@ -11,11 +11,39 @@ import { RenderableSchema } from '../renderable/schema';
import { idFactory } from 'mol-util/id-factory'; import { idFactory } from 'mol-util/id-factory';
const getNextTextureId = idFactory() 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 { export interface Texture {
readonly id: number readonly id: number
readonly texture: WebGLTexture
readonly format: number
readonly type: number
readonly width: number
readonly height: number
load: (image: TextureImage) => void load: (image: TextureImage) => void
bind: (id: TextureId) => void bind: (id: TextureId) => void
unbind: (id: TextureId) => void unbind: (id: TextureId) => void
setSize: (width: number, height: number) => void
destroy: () => void destroy: () => void
} }
...@@ -24,7 +52,7 @@ export type TextureId = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 1 ...@@ -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 TextureValues = { [k: string]: ValueCell<TextureImage> }
export type Textures = { [k: string]: Texture } 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 id = getNextTextureId()
const { gl } = ctx const { gl } = ctx
const texture = gl.createTexture() const texture = gl.createTexture()
...@@ -32,39 +60,54 @@ export function createTexture(ctx: Context): Texture { ...@@ -32,39 +60,54 @@ export function createTexture(ctx: Context): Texture {
throw new Error('Could not create WebGL texture') throw new Error('Could not create WebGL texture')
} }
const _textureType = gl.TEXTURE_2D const magFilter = gl.NEAREST
const _magFilter = gl.NEAREST const minFilter = gl.NEAREST
const _minFilter = gl.NEAREST const format = getFormat(ctx, _format)
const _format = gl.RGB const type = getType(ctx, _type)
const _arrayType = gl.UNSIGNED_BYTE
let _width = 0
let _height = 0
let destroyed = false let destroyed = false
ctx.textureCount += 1 ctx.textureCount += 1
return { return {
id, id,
texture,
format,
type,
get width () { return _width },
get height () { return _height },
load: (image: TextureImage) => { load: (image: TextureImage) => {
const { array, width, height } = image 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 // unpack alignment of 1 since we use textures only for data
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
gl.texImage2D(_textureType, 0, _format, width, height, 0, _format, _arrayType, array) gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, type, array)
gl.texParameteri(_textureType, gl.TEXTURE_MAG_FILTER, _magFilter) _width = width
gl.texParameteri(_textureType, gl.TEXTURE_MIN_FILTER, _minFilter) _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 // clamp-to-edge needed for non-power-of-two textures
gl.texParameteri(_textureType, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(_textureType, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.bindTexture(_textureType, null) gl.bindTexture(gl.TEXTURE_2D, null)
}, },
bind: (id: TextureId) => { bind: (id: TextureId) => {
gl.activeTexture(gl.TEXTURE0 + id) gl.activeTexture(gl.TEXTURE0 + id)
gl.bindTexture(_textureType, texture) gl.bindTexture(gl.TEXTURE_2D, texture)
}, },
unbind: (id: TextureId) => { unbind: (id: TextureId) => {
gl.activeTexture(gl.TEXTURE0 + id) 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: () => { destroy: () => {
if (destroyed) return if (destroyed) return
gl.deleteTexture(texture) gl.deleteTexture(texture)
...@@ -79,7 +122,7 @@ export function createTextures(ctx: Context, schema: RenderableSchema, values: T ...@@ -79,7 +122,7 @@ export function createTextures(ctx: Context, schema: RenderableSchema, values: T
Object.keys(schema).forEach((k, i) => { Object.keys(schema).forEach((k, i) => {
const spec = schema[k] const spec = schema[k]
if (spec.type === 'texture') { if (spec.type === 'texture') {
const texture = createTexture(ctx) const texture = createTexture(ctx, spec.format, spec.dataType)
texture.load(values[k].ref.value) texture.load(values[k].ref.value)
textures[k] = texture 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