Skip to content

Commit

Permalink
feat: example 3, textured & indexed plane.
Browse files Browse the repository at this point in the history
  • Loading branch information
bhouston committed Jun 17, 2020
1 parent 8df88b7 commit ae9660a
Show file tree
Hide file tree
Showing 21 changed files with 132 additions and 39 deletions.
Binary file added assets/textures/uv_grid_opengl.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions examples/gettingstarted/3_texturedPlane/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<title>Threeify - Getting Started - 3 Texture</title>
<script type="module" src="/dist/examples/gettingstarted/3_texturedPlane/index.js"></script>
</head>
<body></body>
</html>
3 changes: 2 additions & 1 deletion src/examples/gettingstarted/1_triangle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ document.body.appendChild(canvasFramebuffer.canvas);

const bufferGeometry = new BufferGeometry(context, geometry);
const program = new Program(context, material);
const uniforms = {};

canvasFramebuffer.renderBufferGeometry(program, {}, bufferGeometry);
canvasFramebuffer.renderBufferGeometry(program, uniforms, bufferGeometry);
3 changes: 2 additions & 1 deletion src/examples/gettingstarted/2_animatedUniforms/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Float32Attribute } from "../../../lib/geometry/Attribute";
import { Float32Attribute, Uint32Attribute } from "../../../lib/geometry/Attribute";
import { Geometry } from "../../../lib/geometry/Geometry";
import { ShaderMaterial } from "../../../lib/materials/ShaderMaterial";
import { Color } from "../../../lib/math/Color";
Expand All @@ -9,6 +9,7 @@ import vertexSourceCode from "./vertex.glsl";

const geometry = new Geometry();
geometry.attributes.set("position", new Float32Attribute([0, 0.5, 0.5, -0.5, -0.5, -0.5], 2));
geometry.indices = new Uint32Attribute([0, 1, 2], 1);

const material = new ShaderMaterial(vertexSourceCode, fragmentSourceCode);

Expand Down
11 changes: 11 additions & 0 deletions src/examples/gettingstarted/3_texturedPlane/fragment.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
precision highp float;

uniform sampler2D map;

varying vec2 v_texCoord;

void main() {

gl_FragColor = texture2D(map, v_texCoord);

}
28 changes: 28 additions & 0 deletions src/examples/gettingstarted/3_texturedPlane/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { plane } from "../../../lib/geometry/primitives/Plane";
import { fetchImage } from "../../../lib/io/loaders/Image";
import { ShaderMaterial } from "../../../lib/materials/ShaderMaterial";
import { Program, RenderingContext, TexImage2D } from "../../../lib/renderers/webgl2";
import { BufferGeometry } from "../../../lib/renderers/webgl2/buffers/BufferGeometry";
import { Texture } from "../../../lib/textures";
import fragmentSourceCode from "./fragment.glsl";
import vertexSourceCode from "./vertex.glsl";

async function init(): Promise<null> {
const geometry = plane(1, 1, 1, 1);
const material = new ShaderMaterial(vertexSourceCode, fragmentSourceCode);
const texture = new Texture(await fetchImage("/assets/textures/uv_grid_opengl.jpg"));

const context = new RenderingContext();
const canvasFramebuffer = context.canvasFramebuffer;
document.body.appendChild(canvasFramebuffer.canvas);

const bufferGeometry = new BufferGeometry(context, geometry);
const program = new Program(context, material);
const texImage2D = new TexImage2D(context, texture);
const uniforms = { map: texImage2D };

canvasFramebuffer.renderBufferGeometry(program, uniforms, bufferGeometry);

return null;
}
init();
11 changes: 11 additions & 0 deletions src/examples/gettingstarted/3_texturedPlane/vertex.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
attribute vec3 position;
attribute vec2 uv;

varying vec2 v_texCoord;

void main() {

v_texCoord = uv;
gl_Position = vec4( position.y, position.x, 0.5, 1.0 );

}
2 changes: 1 addition & 1 deletion src/examples/testing/testrig1/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ async function test(): Promise<void> {
canvasFramebuffer.clear(Attachments.Default, depthClear);
canvasFramebuffer.render(rootNode, camera);

const texImage2D = new TexImage2D(context, texture.image);
const texImage2D = new TexImage2D(context, texture);
console.log(texImage2D);

const boxBufferGeometry = new BufferGeometry(context, mesh.geometry);
Expand Down
17 changes: 14 additions & 3 deletions src/lib/geometry/Attribute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class Attribute {
// see here for ideas: https://www.typescriptlang.org/docs/handbook/advanced-types.html

export class Int16Attribute extends Attribute {
constructor(array: Int16Array | number[], componentsPerVertex: number) {
constructor(array: Int16Array | number[], componentsPerVertex = 1) {
super(
new AttributeData(array instanceof Int16Array ? array : new Int16Array(array), 0, -1, 2 * componentsPerVertex),
0,
Expand All @@ -44,8 +44,19 @@ export class Int16Attribute extends Attribute {
}
}

export class Uint32Attribute extends Attribute {
constructor(array: Uint32Array | number[], componentsPerVertex = 1) {
super(
new AttributeData(array instanceof Uint32Array ? array : new Uint32Array(array), 0, -1, 4 * componentsPerVertex),
0,
ComponentType.UnsignedInt,
componentsPerVertex,
-1,
);
}
}
export class Int32Attribute extends Attribute {
constructor(array: Int32Array | number[], componentsPerVertex: number) {
constructor(array: Int32Array | number[], componentsPerVertex = 1) {
super(
new AttributeData(array instanceof Int32Array ? array : new Int32Array(array), 0, -1, 4 * componentsPerVertex),
0,
Expand All @@ -57,7 +68,7 @@ export class Int32Attribute extends Attribute {
}

export class Float32Attribute extends Attribute {
constructor(array: Float32Array | number[], componentsPerVertex: number) {
constructor(array: Float32Array | number[], componentsPerVertex = 1) {
super(
new AttributeData(
array instanceof Float32Array ? array : new Float32Array(array),
Expand Down
4 changes: 0 additions & 4 deletions src/lib/geometry/Geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,4 @@ export class Geometry implements IVersionable, IDisposable {
this.dirty();
}
}

setIndices(indices: Attribute): void {
this.indices = indices;
}
}
10 changes: 5 additions & 5 deletions src/lib/geometry/primitives/Box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//

import { Vector3 } from "../../math/Vector3";
import { Float32Attribute, Int32Attribute } from "../Attribute";
import { Float32Attribute, Uint32Attribute } from "../Attribute";
import { Geometry } from "../Geometry";

export function box(
Expand Down Expand Up @@ -120,10 +120,10 @@ export function box(
// build geometry

const geometry = new Geometry();
geometry.setIndices(new Int32Attribute(new Int32Array(indices), 1));
geometry.attributes.set("position", new Float32Attribute(new Float32Array(vertices), 3));
geometry.attributes.set("normal", new Float32Attribute(new Float32Array(normals), 3));
geometry.attributes.set("uv", new Float32Attribute(new Float32Array(uvs), 2));
geometry.indices = new Uint32Attribute(indices);
geometry.attributes.set("position", new Float32Attribute(vertices, 3));
geometry.attributes.set("normal", new Float32Attribute(normals, 3));
geometry.attributes.set("uv", new Float32Attribute(uvs, 2));

return geometry;
}
10 changes: 5 additions & 5 deletions src/lib/geometry/primitives/Plane.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// * @bhouston
//

import { Float32Attribute, Int32Attribute } from "../Attribute";
import { Float32Attribute, Uint32Attribute } from "../Attribute";
import { Geometry } from "../Geometry";

export function plane(width = 1, height = 1, widthSegments = 1, heightSegments = 1): Geometry {
Expand Down Expand Up @@ -64,10 +64,10 @@ export function plane(width = 1, height = 1, widthSegments = 1, heightSegments =
// build geometry

const geometry = new Geometry();
geometry.setIndices(new Int32Attribute(new Int32Array(indices), 1));
geometry.attributes.set("position", new Float32Attribute(new Float32Array(vertices), 3));
geometry.attributes.set("normal", new Float32Attribute(new Float32Array(normals), 3));
geometry.attributes.set("uv", new Float32Attribute(new Float32Array(uvs), 2));
geometry.indices = new Uint32Attribute(indices);
geometry.attributes.set("position", new Float32Attribute(vertices, 3));
geometry.attributes.set("normal", new Float32Attribute(normals, 3));
geometry.attributes.set("uv", new Float32Attribute(uvs, 2));

return geometry;
}
2 changes: 2 additions & 0 deletions src/lib/renderers/webgl2/buffers/Buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ export class Buffer implements IDisposable {
}

// Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
// console.log(`gl.bindBuffer(${this.target}, ${this.glBuffer})`);
gl.bindBuffer(this.target, this.glBuffer);

// load data
// console.log(`gl.bufferData(${this.target}, ${arrayBuffer}, ${this.usage})`);
gl.bufferData(this.target, arrayBuffer, this.usage);
}

Expand Down
10 changes: 8 additions & 2 deletions src/lib/renderers/webgl2/buffers/BufferAccessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { Attribute } from "../../../geometry/Attribute";
import { RenderingContext } from "../RenderingContext";
import { Buffer } from "./Buffer";
import { BufferTarget } from "./BufferTarget";
import { ComponentType } from "./ComponentType";

export class BufferAccessor {
Expand All @@ -21,10 +22,15 @@ export class BufferAccessor {
public byteOffset: number,
) {}

static FromAttribute(context: RenderingContext, attribute: Attribute): BufferAccessor {
static FromAttribute(
context: RenderingContext,
attribute: Attribute,
bufferTarget: BufferTarget | undefined = undefined,
): BufferAccessor {
const attributeData = attribute.attributeData;

const buffer = new Buffer(context, attributeData.arrayBuffer, attributeData.target);
const target = bufferTarget !== undefined ? bufferTarget : attributeData.target;
const buffer = new Buffer(context, attributeData.arrayBuffer, target);
const bufferAccessor = new BufferAccessor(
buffer,
attribute.componentType,
Expand Down
3 changes: 2 additions & 1 deletion src/lib/renderers/webgl2/buffers/BufferGeometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Dictionary } from "../../../core/Dictionary";
import { Geometry } from "../../../geometry/Geometry";
import { RenderingContext } from "../RenderingContext";
import { BufferAccessor } from "./BufferAccessor";
import { BufferTarget } from "./BufferTarget";
import { PrimitiveType } from "./PrimitiveType";

export class BufferGeometry implements IDisposable {
Expand All @@ -22,7 +23,7 @@ export class BufferGeometry implements IDisposable {

constructor(context: RenderingContext, geometry: Geometry) {
if (geometry.indices !== undefined) {
this.setIndices(BufferAccessor.FromAttribute(context, geometry.indices));
this.indices = BufferAccessor.FromAttribute(context, geometry.indices, BufferTarget.ElementArray);
this.count = geometry.indices.count;
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/renderers/webgl2/buffers/BufferTarget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export enum BufferTarget {
/**
* Buffer used for element indices.
*/
ElementArray = GL.ARRAY_BUFFER,
ElementArray = GL.ELEMENT_ARRAY_BUFFER,
/**
* Buffer for copying from one buffer object to another.
*/
Expand Down
5 changes: 4 additions & 1 deletion src/lib/renderers/webgl2/framebuffers/VirtualFramebuffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ export abstract class VirtualFramebuffer implements IDisposable {
// draw
const gl = this.context.gl;
if (bufferGeometry.indices !== undefined) {
throw new Error("not implemented");
// console.log(
// `gl.drawElements(${bufferGeometry.primitive}, ${bufferGeometry.count}, ${bufferGeometry.indices.componentType}//, 0)`,
// );
gl.drawElements(bufferGeometry.primitive, bufferGeometry.count, bufferGeometry.indices.componentType, 0);
} else {
gl.drawArrays(bufferGeometry.primitive, 0, bufferGeometry.count);
}
Expand Down
8 changes: 8 additions & 0 deletions src/lib/renderers/webgl2/programs/Program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ export class Program implements IDisposable {
attribute.setBuffer(bufferAccessor);
}
});
if (bufferGeometry.indices !== undefined) {
// bind the buffer containing the indices
// console.log(
// `gl.bindBuffer(${bufferGeometry.indices.buffer.target}, ${bufferGeometry.indices.buffer.glBuffer})`,
// );

gl.bindBuffer(bufferGeometry.indices.buffer.target, bufferGeometry.indices.buffer.glBuffer);
}
} else if (buffers instanceof VertexArrayObject) {
const vao = buffers as VertexArrayObject;
gl.bindVertexArray(vao.glVertexArrayObject);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/renderers/webgl2/programs/ProgramUniform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ export class ProgramUniform {
case UniformType.UnsignedIntSampler2D:
case UniformType.Sampler2DShadow: {
const t = value as TexImage2D;
gl.uniform1i(this.glLocation, this.textureUnit);
gl.activeTexture(GL2.TEXTURE0 + this.textureUnit);
gl.bindTexture(GL2.TEXTURE_2D, t.glTexture);
gl.uniform1i(this.glLocation, this.textureUnit);
return this;
}
}
Expand Down
30 changes: 18 additions & 12 deletions src/lib/renderers/webgl2/textures/TexImage2D.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
// * @bhouston
//

import { Vector2 } from "lib/math/Vector2";
import { IDisposable } from "../../../core/types";
import { Vector2 } from "../../../math/Vector2";
import { ArrayBufferImage, Texture } from "../../../textures/Texture";
import { Pool } from "../../Pool";
import { RenderingContext } from "../RenderingContext";
Expand Down Expand Up @@ -40,16 +40,16 @@ export enum TextureSourceType {
export class TexImage2D implements IDisposable {
disposed = false;
glTexture: WebGLTexture;
dataType: DataType;
pixelFormat: PixelFormat;
size: Vector2;

constructor(
public context: RenderingContext,
public image: ArrayBufferImage | HTMLImageElement,
public texture: Texture,
public target: TextureTarget = TextureTarget.Texture2D,
public level = 0,
public internalFormat: PixelFormat = PixelFormat.RGBA,
public size: Vector2 = new Vector2(0, 0),
public pixelFormat: PixelFormat = PixelFormat.RGBA,
public dataType: DataType = DataType.UnsignedByte,
public texParameters: TexParameters = new TexParameters(),
) {
const gl = this.context.gl;
Expand All @@ -63,31 +63,35 @@ export class TexImage2D implements IDisposable {
this.glTexture = glTexture;
}

this.dataType = texture.dataType;
this.pixelFormat = texture.pixelFormat;
this.size = texture.size;

gl.bindTexture(this.target, this.glTexture);
if (this.image instanceof ArrayBufferImage) {
if (texture.image instanceof ArrayBufferImage) {
gl.texImage2D(
this.target,
this.level,
this.internalFormat,
this.size.width,
this.size.height,
0,
this.internalFormat,
this.pixelFormat,
this.dataType,
new Uint8Array(this.image.data),
new Uint8Array(texture.image.data),
0,
);
} else if (this.image instanceof HTMLImageElement) {
} else if (texture.image instanceof HTMLImageElement) {
gl.texImage2D(
this.target,
this.level,
this.internalFormat,
this.size.width,
this.size.height,
0,
this.internalFormat,
this.pixelFormat,
this.dataType,
this.image,
texture.image,
);
}

Expand All @@ -101,6 +105,8 @@ export class TexImage2D implements IDisposable {
gl.texParameteri(this.target, gl.TEXTURE_MAG_FILTER, texParameters.magFilter);
gl.texParameteri(this.target, gl.TEXTURE_MIN_FILTER, texParameters.minFilter);

gl.bindTexture(this.target, null);

// gl.texParameteri(this.target, gl.MAX_TEXTURE_MAX_ANISOTROPY_EXT, texParameters.anisotropicLevels);
}

Expand All @@ -116,7 +122,7 @@ export class TexImage2DPool extends Pool<Texture, TexImage2D> {
constructor(context: RenderingContext) {
super(context, (context: RenderingContext, texture: Texture, texImage2D: TexImage2D | undefined) => {
if (texImage2D === undefined) {
texImage2D = new TexImage2D(context, texture.image);
texImage2D = new TexImage2D(context, texture);
}
// TODO: Create a new image here.
// texImage2D.update(texture);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/textures/Texture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class Texture implements IIdentifiable, IVersionable, IDisposable, IPoolU
public wrapS: TextureWrap = TextureWrap.ClampToEdge,
public wrapT: TextureWrap = TextureWrap.ClampToEdge,
public magFilter: TextureFilter = TextureFilter.Linear,
public minFilter: TextureFilter = TextureFilter.LinearMipmapLinear,
public minFilter: TextureFilter = TextureFilter.Linear,
public pixelFormat: PixelFormat = PixelFormat.RGBA,
public dataType: DataType = DataType.UnsignedByte,
public generateMipmaps = true,
Expand Down

0 comments on commit ae9660a

Please sign in to comment.