Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for VAOs that use constant attributes #4995

Merged
merged 3 commits into from
Feb 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Change Log
* Added `Transforms.localFrameToFixedFrameGenerator` to generate a function that computes a 4x4 transformation matrix from a local reference frame to fixed reference frame.
* Fixed an issue where the camera would zoom past an object and flip to the other side of the globe. [#4967](https://github.com/AnalyticalGraphicsInc/cesium/pull/4967) and [#4982](https://github.com/AnalyticalGraphicsInc/cesium/pull/4982)
* Fixed exception in 2D in certain cases with polylines when rotating the map. [#4619](https://github.com/AnalyticalGraphicsInc/cesium/issues/4619)
* Fixed an issue with constant `VertexArray` attributes not being set correctly. [#4995](https://github.com/AnalyticalGraphicsInc/cesium/pull/4995)

### 1.30 - 2017-02-01

Expand Down
28 changes: 24 additions & 4 deletions Source/Renderer/VertexArray.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,11 +256,11 @@ define([
* context : context,
* attributes : attributes
* });
*
*
* @see Buffer#createVertexBuffer
* @see Buffer#createIndexBuffer
* @see Context#draw
*
*
* @private
*/
function VertexArray(options) {
Expand All @@ -285,6 +285,7 @@ define([
var vaAttributes = [];
var numberOfVertices = 1; // if every attribute is backed by a single value
var hasInstancedAttributes = false;
var hasConstantAttributes = false;

var length = attributes.length;
for (i = 0; i < length; ++i) {
Expand All @@ -306,7 +307,9 @@ define([
for (i = 0; i < length; ++i) {
if (vaAttributes[i].instanceDivisor > 0) {
hasInstancedAttributes = true;
break;
}
if (defined(vaAttributes[i].value)) {
hasConstantAttributes = true;
}
}

Expand Down Expand Up @@ -334,6 +337,7 @@ define([

this._numberOfVertices = numberOfVertices;
this._hasInstancedAttributes = hasInstancedAttributes;
this._hasConstantAttributes = hasConstantAttributes;
this._context = context;
this._gl = gl;
this._vao = vao;
Expand Down Expand Up @@ -515,7 +519,7 @@ define([
* // Example 3. When the caller destroys the vertex array, it also destroys the
* // attached vertex buffer(s) and index buffer.
* va = va.destroy();
*
*
* @see Buffer#createVertexBuffer
* @see Buffer#createIndexBuffer
* @see GeometryPipeline.createAttributeLocations
Expand Down Expand Up @@ -714,12 +718,28 @@ define([
}
}

// Vertex attributes backed by a constant value go through vertexAttrib[1234]f[v]
// which is part of context state rather than VAO state.
function setConstantAttributes(vertexArray, gl) {
var attributes = vertexArray._attributes;
var length = attributes.length;
for (var i = 0; i < length; ++i) {
var attribute = attributes[i];
if (attribute.enabled && defined(attribute.value)) {
attribute.vertexAttrib(gl);
}
}
}

VertexArray.prototype._bind = function() {
if (defined(this._vao)) {
this._context.glBindVertexArray(this._vao);
if (this._context.instancedArrays) {
setVertexAttribDivisor(this);
}
if (this._hasConstantAttributes) {
setConstantAttributes(this, this._gl);
}
} else {
bind(this._gl, this._attributes, this._indexBuffer);
}
Expand Down
76 changes: 76 additions & 0 deletions Specs/Renderer/VertexArraySpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,82 @@ defineSuite([
va = va.destroy();
});

it('renders two vertex arrays with constant values', function() {
var vs =
'attribute float firefoxWorkaround;' +
'attribute vec4 attr;' +
'varying vec4 v_color;' +
'void main() { ' +
' v_color = attr + vec4(firefoxWorkaround);' +
' gl_PointSize = 1.0;' +
' gl_Position = vec4(0.0, 0.0, 0.0, 1.0);' +
'}';

var fs =
'varying vec4 v_color;' +
'void main() { gl_FragColor = v_color; }';

var sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations : {
firefoxWorkaround : 0,
attr : 1
}
});

var vertexBuffer = Buffer.createVertexBuffer({
context : context,
sizeInBytes : Float32Array.BYTES_PER_ELEMENT,
usage : BufferUsage.STATIC_DRAW
});

var vaRed = new VertexArray({
context : context,
attributes : [{
vertexBuffer : vertexBuffer,
componentsPerAttribute : 1
}, {
value : [1, 0, 0, 1]
}]
});

var vaGreen = new VertexArray({
context : context,
attributes : [{
vertexBuffer : vertexBuffer,
componentsPerAttribute : 1
}, {
value : [0, 1, 0, 1]
}]
});

var commandRed = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : vaRed,
count : 1
});

var commandGreen = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : vaGreen,
count : 1
});

commandRed.execute(context);
expect(context).toReadPixels([255, 0, 0, 255]);

commandGreen.execute(context);
expect(context).toReadPixels([0, 255, 0, 255]);

sp = sp.destroy();
vaRed = vaRed.destroy();
vaGreen = vaGreen.destroy();
});

it('destroys', function() {
var va = new VertexArray({
context : context,
Expand Down