I'm Sorry to paste a list of code, but it's very simple.I don't know why, not warnings no errors, it breaks down in silence.Here is the source code, it refer to a utils.js file, I promise there is no errors in the outer file. Because other programs base on that work pretty well.
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<style>
body { background: pink }
canvas { background: orange }
</style>
<script src="utils.js"></script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec4 aVertexPosition;
uniform float uCosB, uSinB;
void main() {
gl_Position.x = aVertexPosition.x * uCosB - aVertexPosition.y * uSinB;
gl_Position.y = aVertexPosition.x * uCosB + aVertexPosition.y * uSinB;
gl_Position.z = aVertexPosition.z;
gl_Position.w = 1.0;
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
</script>
<script>
var gl, canvas, shaderProgram;
window.onload = function() {
initCanvasAndGL("canvas");
initProgram();
initBuffer();
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
var angle = 90 / 180 * Math.PI;
var uSinB = gl.getUniformLocation(shaderProgram, "uSinB");
var uCosB = gl.getUniformLocation(shaderProgram, "uCosB");
gl.uniform1f(uSinB, Math.sin(angle));
gl.uniform1f(uCosB, Math.cos(angle));
gl.drawArrays(gl.TRIANGLES, 0, 3);
}
function initBuffer() {
var vertices = [0.0, 0.5, -0.5, -0.5, 0.5, -0.5];
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
var aVertexPosition = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.vertexAttribPointer(aVertexPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aVertexPosition);
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="400">
Canvas Not Supported! :(
</canvas>
</body>
If you do suspect the utils.js, Here is the source code.
function initCanvasAndGL(canvasID) {
canvas = document.getElementById(canvasID);
var names = [
"webgl", "experimental-webgl",
"webkit-3d", "moz-webgl"
];
for(var i = 0; i < names.length; ++i) {
try {
gl = canvas.getContext(names[i]);
} catch(e) {}
if(gl) {
break;
}
}
if(!gl) {
alert("WebGL is not available! :(");
}
}
function getShader(gl, id) {
var shaderScript = document.getElementById(id);
if(!shaderScript) {
return null;
}
var str = "";
var k = shaderScript.firstChild;
while(k) {
if(k.nodeType == 3) {
str += k.textContent;
}
k = k.nextSibling;
}
var shader;
if(shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else if(shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else {
return null;
}
gl.shaderSource(shader, str);
gl.compileShader(shader);
if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
function initProgram() {
var vertexShader = getShader(gl, "shader-vs");
var fragmentShader = getShader(gl, "shader-fs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if(!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders! :(");
}
gl.useProgram(shaderProgram);
}
You can put it together to run the program. But the result really makes me crazy.
yes as the other person commented - you need to change your gl_Position.y as
gl_Position.y = aVertexPosition.x * uSinB + aVertexPosition.y * uCosB;
then you get a red triangle displayed
enjoy
Related
Three js
I want cubeTextureLoader cube map background. but it doesn't work and showing nothing only white background and my object, But I want 3d background. It gives me error like this one-
"Access to image at 'file:///C:/Users/Mili%20Murmu/Documents/Arena_web/Mili/ThreeJs/Bts_music-player/images/posx.jpg' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.".
second error -
"Failed to load resource: net::ERR_FAILED".
I don't understand why isn't showing any cube map background? Please help me! How can I solve this?
const scene = new THREE.Scene();
//light
const light = new THREE.PointLight(0xffffff, 1)
light.position.set(2000, 2000, 1500);
scene.add(light);
const ambientlight = new THREE.AmbientLight(0xffffff, 0.2);
scene.add(ambientlight);
//set up camera
// Set up camera
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.3, 10000)
camera.position.set(1300, 0, 0);
function onWindowResize() {
HEIGHT = window.innerHeight;
WIDTH = window.innerWidth;
windowHalfX = WIDTH / 2;
windowHalfY = HEIGHT / 2;
renderer.setSize(WIDTH, HEIGHT);
camera.aspect = WIDTH / HEIGHT;
camera.updateProjectionMatrix();
}
// renderer
//set up renderer
const renderer = new THREE.WebGLRenderer({antialias : true, alpha : true});
renderer.setSize(window.innerWidth - 8, window.innerHeight - 8) ;
renderer.render(scene, camera);
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setClearColor("#803855");
renderer.shadowMapEnabled = true;
const container = document.getElementById('world');
container.appendChild(renderer.domElement);
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls( camera, renderer.domElement);
const group = new THREE.Group();
scene.add(group);
const imgLoc = "https://eyes.nasa.gov/apps/exo/assets/image/exoplanet/";
const geometry = new THREE.SphereGeometry (500, 32, 32);
const material = new THREE.MeshPhongMaterial();
const planet = new THREE.Mesh(geometry, material);
group.add(planet);
const starGeometry = new THREE.BoxGeometry(20, 20, 20);
const starMaterial = new THREE.MeshBasicMaterial( );
const starsphere = new THREE.Mesh(starGeometry, starMaterial );
scene.add(starsphere);
let loader = new THREE.TextureLoader();
material.map = loader.load(imgLoc+'GJ_504_b.jpg');
material.bumpMap = loader.load(imgLoc+'GJ_504_b.jpg');
material.bumpScale = 8;
material.specular = new THREE.Color('#000000');
var textureCubeLoader = new THREE.CubeTextureLoader();
var path = 'images/';
var textureCube = textureCubeLoader.load( [ path + 'posx.jpg' , path + 'negx.jpg', path + 'posy.jpg' , path + 'negy.jpg', path + 'posz.jpg' , path + 'negz.jpg' ] );
scene.background = textureCube;
const animate = () => {
requestAnimationFrame(animate);
planet.rotation.y += 0.001;
renderer.render(scene, camera);
};
animate();
*{
box-sizing: border-box;
}
body{
margin: 0;
padding: 0;
}
#world{
margin: 0;
padding: 0;
}
<html>
<head>
<meta charset="utf-8">
<title>BTS_Music Player</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r126/three.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/OrbitControls.js"></script>
</head>
<body>
<div id="world"></div>
<script src="js/main.js"></script>
</body>
</html>
I am trying to implement generic solution since my html content won't be fixed,i want to convert html 2 pdf but problem is getting cut between the pages, page break not working correctly.
//var staticHeight = 0;
//$('div').each(function () {
// staticHeight += $(this).filter(':visible').outerHeight(true);
// var pageHeight = 100
// console.log(staticHeight)
// if (staticHeight > pageHeight) {
// $(this).after('<div class="page-break" id="activediv2"> asasjjasasa asas </div>');
// staticHeight = 0;
// }
//});
//return html2canvas(document.getElementsByClassName('custom-content')[0], {
// onrendered: function (canvasObj) {
// startPrintProcess(canvasObj, 'printedPDF', function () {
// alert('PDF saved');
// });
// //save this object to the pdf
// }
//});
//return html2canvas($(element)[0], {
// background: "#ffffff",
// onrendered: function (canvas) {
// var myImage = canvas.toDataURL("image/jpeg,1.0");
// // Adjust width and height
// var imgWidth = (canvas.width * 60) / 247;
// var imgHeight = (canvas.height * 70) / 247;
// // jspdf changes
// var pdf = new jsPDF('l', 'mm', 'a4');
// pdf.addImage(myImage, 'png', 15, 2, imgWidth, imgHeight); // 2: 19
// pdf.save('sample.pdf');
// }
//});
var HTML_Width = $(element).width();
var HTML_Height = $(element).height();
var top_left_margin = 15;
var PDF_Width = HTML_Width + (top_left_margin * 2);
var PDF_Height = (PDF_Width * 1.5) + (top_left_margin * 2);
var canvas_image_width = HTML_Width;
var canvas_image_height = HTML_Height;
pdf = "";
html2canvas(element, {
background: '#FFFFFF',
onclone: function (doc) {
hiddenDiv = document.getElementsByClassName('custom-content')[0];
hiddenDiv.style.display = 'block';
},
onrendered: function (canvas) {
var width = canvas.width;
var height = canvas.height;
var millimeters = {};
millimeters.width = Math.floor(width * 0.274583);
millimeters.height = Math.floor(height * 0.274583);
var context = canvas.getContext('2d');
context.scale(2, 2);
var imgData = canvas.toDataURL('image/png');
var doc = new jsPDF("l", "mm", "a4");
// doc.deletePage(1);
// doc.addPage(millimeters.width, millimeters.height);
//doc.addImage(imgData, 'PNG', 0, 0, width, height);
//doc.save('wardrobemodel.pdf');
var totalPDFPages = Math.ceil(HTML_Height / PDF_Height) - 1;
for (var i = 0; i <= totalPDFPages; i++) {
doc.addPage(PDF_Width, PDF_Height);
doc.addImage(imgData, 'JPG', 0, -(PDF_Height * i) + (top_left_margin * 4), canvas_image_width, canvas_image_height);
}
doc.save('wardrobemodel.pdf');
}
});
//var worker = html2pdf().from(element).toPdf();
////for (let i = 0; i < pages.length; i++) {
//// worker = worker.set(opt).from(pages[i]).toContainer().toCanvas().toPdf().get('pdf').then((pdf) => {
//// if (i < pages.length - 1) { // Bump cursor ahead to new page until on last page
//// pdf.addPage();
//// }
//// });
////}
//worker = worker.save();
//$('.tile-body').find('div').each(function () {
// var eleHeight = $(this).filter(':visible').outerHeight(true);
// staticHeight += pix2mm(eleHeight, 300);
// var pageHeight = 257
// console.log(staticHeight)
// if (staticHeight > pageHeight) {
// $(this).after('<div class="page-break mt-1 mb-1" id="activediv2"></div>');
// staticHeight = 0;
// }
//});
return html2canvas(element, {
onrendered: function (canvasObj) {
startPrintProcess(canvasObj, 'printedPDF', function () {
alert('PDF saved');
});
//save this object to the pdf
}
});
//$('.tile-body').children('div').each(function () {
// var eleHeight = $(this).filter(':visible').outerHeight(true);
// staticHeight += pix2mm(eleHeight, 300);
// var pageHeight = 257
// console.log(staticHeight)
// if (staticHeight > pageHeight) {
// $(this).after('<div class="page-break mt-3 mb-5" id="activediv2"></div>');
// staticHeight = 0;
// }
//});
staticHeight = 0;
//var opt = {
// margin: 0.25,
// filename: 'ontract.pdf',
// image: { type: 'jpeg', quality: 0.98 },
// html2canvas: { scale: 2 },
// jsPDF: { unit: 'mm', format: 'a4', orientation: 'landscape' },
// pagebreak: { mode: 'avoid-all', after: '#activediv2' }
//};
//var worker = html2pdf().from(element).toPdf();
//worker.save();
// html2pdf().from(element).set(opt).toPdf().get('pdf').save()
// return;
//html2canvas(element, {
// logging: false
//}).then(function (canvas) {
// var pdf = new jsPDF('l', 'mm', 'a4');//A4 paper, portrait
// /// pdf.internal.scaleFactor = 30;
// var ctx = canvas.getContext('2d'),
// a4w = 190, a4h = 257,//A4 size, 210mm x 297mm, 10 mm margin on each side, display area 190x277
// imgHeight = Math.floor(a4h * canvas.width / a4w),//Convert pixel height of one page image to A4 display scale
// renderedHeight = 0;
// var pdfConf = {
// pagesplit: true,
// pagebreak: { mode: 'avoid-all', before: '#activediv2' }
// };
// var logo = document.getElementsByClassName(".logo-img")[0];//Icon placed in header
// while (renderedHeight < canvas.height) {
// var page = document.createElement("canvas");
// page.width = canvas.width;
// page.height = Math.min(imgHeight, canvas.height - renderedHeight);//Maybe less than one page
// //Trim the specified area with getImageData and draw it into the canvas object created earlier
// page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0);
// //Add an image to the page with a 10 mm / 20 mm margin
// pdf.addImage(page.toDataURL('image/jpeg', 1.0), 'JPEG', 10, 20, a4w, Math.min(a4h, a4w * page.height / page.width));
// //Add header logo
// // pdf.addImage(logo, 'SVG', 5, 3);
// var context = page.getContext('2d');
// context.scale(2, 2);
// //pdf.addHTML(element, { pagesplit: true, canvas: page }, function () {
// // // var out = pdf.output('dataurlnewwindow'); // crashed if bigger file
// // pdf.save('two-by-four.pdf')
// //});
// renderedHeight += imgHeight;
// if (renderedHeight < canvas.height)
// pdf.addPage();//Add an empty page if there is more to follow
// delete page;
// }
// pdf.save('content.pdf');
//});
//return;
//var HTML_Width = $(element).width();
//var HTML_Height = $(element).height();
//var top_left_margin = 15;
//var PDF_Width = HTML_Width + (top_left_margin * 2);
//var PDF_Height = (PDF_Width * 1.5) + (top_left_margin * 2);
//var canvas_image_width = HTML_Width;
//var canvas_image_height = HTML_Height;
//var totalPDFPages = Math.ceil(HTML_Height / PDF_Height) - 1;
//html2canvas($(element)[0], { allowTaint: true }).then(function (canvas) {
// var context = canvas.getContext('2d');
// context.scale(2, 2);
// console.log(canvas.height + " " + canvas.width);
// var imgData = canvas.toDataURL("image/jpeg", 1.0);
// var pdf = new jsPDF('l', 'pt', [PDF_Width, PDF_Height]);
// pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, canvas_image_width, canvas_image_height);
// for (var i = 1; i <= totalPDFPages; i++) {
// pdf.addPage(PDF_Width, PDF_Height);
// pdf.addImage(imgData, 'JPG', top_left_margin, -(PDF_Height * i) + (top_left_margin * 4), canvas_image_width, canvas_image_height);
// }
// pdf.save("HTML-Document.pdf");
//});
//return;
///
//html2canvas($(element)[0], { allowTaint: true }).then(function (canvas) {
// calculatePDF_height_width(".print-wrap", 1);
// var imgData = canvas.toDataURL("image/png", 1.0);
// pdf.addPage(PDF_Width, PDF_Height);
// pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, HTML_Width, HTML_Height);
// pdf.save("11.pdf")
//});
div {
page-break-inside: avoid;
}
this is what i tried
In short my target to achieve add page break if generated pdf is breaking html content between two pages.
I solve my problem for export HTML to multiple-page PDF. I create canvas per div. Perhaps this is will help you all.
private canvas: any = {
monthYearCanvas: null,
monthYearHeight: 0,
periodCanvas: null,
periodHeight: 0,
assetCanvas: null,
assetHeight: 0,
badActorCanvas: null,
badActorHeight: 0,
eventCanvas: null,
eventHeight: 0,
tenLowOffCanvas: null,
tenLowOffHeight: 0,
};
public triggerPrintReport(): void {
if (
this.isLoadingMonthYear ||
this.isLoadingOnPeriod ||
this.isLoadingOnAsset ||
this.isLoadingOnBadActor ||
this.isLoadingOnEvent ||
this.isLoadingTenLowOff
) {
alert('Wait for load data');
return;
}
this.messageReport = true;
const monthYearHTML = document.getElementById('htmlData-monthYear');
const periodHTML = document.getElementById('htmlData-period');
const assetHTML = document.getElementById('htmlData-asset');
const badActorHTML = document.getElementById('htmlData-badActor');
const eventHTML = document.getElementById('htmlData-event');
const tenLowOffHTML = document.getElementById('htmlData-tenLowOff');
this.createCanvasURL(monthYearHTML, 'monthYear');
this.createCanvasURL(periodHTML, 'period');
this.createCanvasURL(assetHTML, 'asset');
this.createCanvasURL(badActorHTML, 'badActor');
this.createCanvasURL(eventHTML, 'event');
this.createCanvasURL(tenLowOffHTML, 'tenLowOff');
}
private createCanvasURL(element: any, type: string): void {
html2canvas(element).then(canvas => {
const width = 208;
if (type === 'monthYear') {
this.canvas.monthYearHeight = canvas.height * width / canvas.width;
this.canvas.monthYearCanvas = canvas.toDataURL('image/png');
} else if (type === 'period') {
this.canvas.periodHeight = canvas.height * width / canvas.width;
this.canvas.periodCanvas = canvas.toDataURL('image/png');
} else if (type === 'asset') {
this.canvas.assetHeight = canvas.height * width / canvas.width;
this.canvas.assetCanvas = canvas.toDataURL('image/png');
} else if (type === 'badActor') {
this.canvas.badActorHeight = canvas.height * width / canvas.width;
this.canvas.badActorCanvas = canvas.toDataURL('image/png');
} else if (type === 'event') {
this.canvas.eventHeight = canvas.height * width / canvas.width;
this.canvas.eventCanvas = canvas.toDataURL('image/png');
} else if (type === 'tenLowOff') {
this.canvas.tenLowOffHeight = canvas.height * width / canvas.width;
this.canvas.tenLowOffCanvas = canvas.toDataURL('image/png');
}
this.exportPDF();
});
}
private exportPDF(): void {
const PDF = new jsPDF('p', 'mm', 'a4');
if (
this.canvas.monthYearCanvas &&
this.canvas.periodCanvas &&
this.canvas.assetCanvas &&
this.canvas.badActorCanvas &&
this.canvas.badActorCanvas &&
this.canvas.tenLowOffCanvas
) {
PDF.addImage(this.canvas.monthYearCanvas, 'PNG', 1, 10, 208, this.canvas.monthYearHeight);
PDF.addImage(this.canvas.periodCanvas, 'PNG', 1, 125, 208, this.canvas.periodHeight);
PDF.addPage();
PDF.addImage(this.canvas.assetCanvas, 'PNG', 1, 10, 208, this.canvas.assetHeight);
PDF.addPage();
PDF.addImage(this.canvas.badActorCanvas, 'PNG', 1, 10, 208, this.canvas.badActorHeight);
PDF.addPage();
PDF.addImage(this.canvas.eventCanvas, 'PNG', 1, 10, 208, this.canvas.eventHeight);
PDF.addPage('l');
PDF.addImage(this.canvas.tenLowOffCanvas, 'PNG', 1, 10, 208, this.canvas.tenLowOffHeight);
this.messageReport = false;
PDF.save('angular-demo.pdf');
}
}
(function() {
var form = $('#printContent');
$('#create_pdf').on('click', function() {
$('body').scrollTop(0);
createPDF();
});
//create pdf
function createPDF() {
getCanvas().then(function(canvas) {
var imgData = canvas.toDataURL("image/png");
var imgWidth = 210;
var pageHeight = 295;
var imgHeight = (canvas.height) * imgWidth / canvas.width;
var heightLeft = imgHeight;
var doc = new jsPDF('p', 'mm');
var position = 0;
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
console.log(canvas.height);
while(heightLeft >= 0) {
position = heightLeft - imgHeight;
doc.addPage();
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
// console.log(position);
}
doc.save('file.pdf');
});
}
// create canvas object
function getCanvas() {
return html2canvas(form, {
imageTimeout: 0,
removeContainer: false
});
}
}());
I use the html2canvas to make PDF, but the charts in the PDF is blurry, is there solution to solve it? the title and the legend are blurry, and the code is below?
If you set legend to useHTML this solves the problem:
legend: {
useHTML: true
}
I have to draw multiple shapes in a simple WebGL program and there occurs a problem which seems unplausible for me. If I try to draw only a single shape, everything works fine.
In the "main" function I create the following instances and render them
_coneInstance = new Cone();
_coneInstance.initCone();
_cylinderInstance = new Cylinder();
_cylinderInstance.initCylinder();
_sphereInstance = new Sphere();
_sphereInstance.initSphere();
renderAll();
This leads to the problem, that all three objets looks like shapes
In renderAll() the render function of each object is called - these functions are shown below.
This looks like, that all vertices from the cone and the cylinder are overwritten by the sphere.
Since each object drawn separately is correctly working, I will not post the vertex-building process.
function Cone()
{
...
this.vertexBuffer = 0;
this.initCone = function()
{
this.generateCone();
this.initBuffers();
}
this.generateCone = function()
{
...
}
this.initBuffers = function()
{
this.vertexBuffer = gl.createBuffer();
this.bind();
gl.bufferData(gl.ARRAY_BUFFER, flatten(this.triangleList), gl.STATIC_DRAW);
gl.enableVertexAttribArray(vPosition);
gl.vertexAttribPointer(vPosition, 4, gl.FLOAT, false, 0, 0);
this.unbind();
}
this.render = function()
{
this.bind();
gl.drawArrays(gl.TRIANGLE_FAN, 0, this.numTrianglesUpperPart);
gl.drawArrays(gl.TRIANGLE_FAN, this.numTrianglesUpperPart, this.numTrianglesLowerPart);
this.unbind();
}
this.bind = function()
{
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
console.log(gl.isBuffer(this.vertexBuffer ));
}
this.unbind = function()
{
gl.bindBuffer(gl.ARRAY_BUFFER, null);
}
}
function Cylinder()
{
...
this.vertexBuffer = 0;
this.initCylinder = function()
{
this.generateCylinder();
this.initCylinderBuffers();
}
this.generateCylinder = function()
{
...
}
this.initCylinderBuffers = function()
{
this.vertexBuffer = gl.createBuffer();
this.bind();
gl.bufferData(gl.ARRAY_BUFFER, flatten(this.cylinderVertexList), gl.STATIC_DRAW);
gl.enableVertexAttribArray(vPosition);
gl.vertexAttribPointer(vPosition, 4, gl.FLOAT, false, 0, 0);
this.unbind();
}
this.render = function()
{
this.bind();
gl.drawArrays(gl.TRIANGLE_FAN, 0, this.cylinderNumTrianglesUpperPart);
gl.drawArrays(gl.TRIANGLE_FAN, this.cylinderNumTrianglesUpperPart, this.cylinderNumTrianglesLowerPart);
gl.drawArrays(gl.TRIANGLES, this.cylinderNumTrianglesUpperPart+this.cylinderNumTrianglesLowerPart, this.cylinderNumTrianglesMiddlePart);
this.unbind();
}
this.bind = function()
{
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
console.log(gl.isBuffer(this.vertexBuffer ));
}
this.unbind = function()
{
gl.bindBuffer(gl.ARRAY_BUFFER, null);
}
}
function Sphere()
{
...
this.vertexBuffer = 0;
this.initSphere = function()
{
this.generateSphere();
this.initSphereBuffers();
}
this.generateSphere = function()
{
...
}
this.initSphereBuffers = function()
{
this.vertexBuffer = gl.createBuffer();
this.bind();
gl.bufferData(gl.ARRAY_BUFFER, flatten(this.unindexedVertices), gl.STATIC_DRAW);
gl.enableVertexAttribArray(vPosition);
gl.vertexAttribPointer(vPosition, 4, gl.FLOAT, false, 0, 0);
this.unbind();
}
this.render = function()
{
this.bind();
gl.drawArrays(gl.TRIANGLES, 0, this.numTriangles);
this.unbind();
}
this.bind = function()
{
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
console.log(gl.isBuffer(this.vertexBuffer ));
}
this.unbind = function()
{
gl.bindBuffer(gl.ARRAY_BUFFER, null);
}
}
You have to update the attribute pointers to the buffer every time.
When binding a vertex attribute pointer you're setting a global pointer to the buffer currently bound. Having a bound buffer is a prerequisite for that, but it does not store any state in regards to vertex attribute pointers. So you have to either move the pointer setup into your render method or use the OES_vertex_array_object extension.
Your initBuffers functions need to be split
This part is "initing" a buffer and only needs to happen at init time
this.vertexBuffer = gl.createBuffer();
this.bind();
gl.bufferData(gl.ARRAY_BUFFER, flatten(this.unindexedVertices), gl.STATIC_DRAW);
This part needs to happen every time before you render
this.bind();
gl.enableVertexAttribArray(vPosition);
gl.vertexAttribPointer(vPosition, 4, gl.FLOAT, false, 0, 0);
We use an embedded map to track our location while driving in the field. Currently the map rotates to match the GPS's orientation. We've found that to be very disorienting and I'd like to lock the orientation North (0 degrees). I still would like the map to track location and indicate heading if available. Below is the snipped from the map's javascript file pertaining to geolocation.
map.addLayer(addressLayer);
// Geolocation marker
var markerEl = document.getElementById('geolocation_marker');
var marker = new ol.Overlay({
positioning: 'center-center',
element: markerEl,
stopEvent: false
});
map.addOverlay(marker);
// LineString to store the different geolocation positions. This LineString
// is time aware.
// The Z dimension is actually used to store the rotation (heading).
var positions = new ol.geom.LineString([],
/** #type {ol.geom.GeometryLayout} */ ('XYZM'));
// Geolocation Control
var geolocation = new ol.Geolocation(/** #type {olx.GeolocationOptions} */ ({
projection: view.getProjection(),
tracking: true,
trackingOptions: {
maximumAge: 10000,
enableHighAccuracy: true,
timeout: 600000
}
}));
var deltaMean = 500; // the geolocation sampling period mean in ms
// Listen to position changes
geolocation.on('change', function(evt) {
var position = geolocation.getPosition();
var accuracy = geolocation.getAccuracy();
var heading = geolocation.getHeading() || 0;
var speed = geolocation.getSpeed() || 0;
var m = Date.now();
addPosition(position, heading, m, speed);
map.getView().setCenter(geolocation.getPosition());
document.getElementById("locate").style.backgroundColor = 'rgba(0,128,0,1)';
locateUser = true;
});
geolocation.on('error', function(error) {
var errors = {
1: 'Permission denied to locate device',
2: 'Position unavailable',
3: 'Request timeout'
};
if (error.code){
document.getElementById("locate").style.backgroundColor = 'rgba(255,0,0,1)';
locateUser = false;
}
alert("Error: " + errors[error.code]);
});
// convert radians to degrees
function radToDeg(rad) {
return rad * 360 / (Math.PI * 2);
}
// convert degrees to radians
function degToRad(deg) {
return deg * Math.PI * 2 / 360;
}
// modulo for negative values
function mod(n) {
return ((n % (2 * Math.PI)) + (2 * Math.PI)) % (2 * Math.PI);
}
function addPosition(position, heading, m, speed) {
var x = position[0];
var y = position[1];
var fCoords = positions.getCoordinates();
var previous = fCoords[fCoords.length - 1];
var prevHeading = previous && previous[2];
if (prevHeading) {
var headingDiff = heading - mod(prevHeading);
// force the rotation change to be less than 180°
if (Math.abs(headingDiff) > Math.PI) {
var sign = (headingDiff >= 0) ? 1 : -1;
headingDiff = - sign * (2 * Math.PI - Math.abs(headingDiff));
}
heading = prevHeading + headingDiff;
}
positions.appendCoordinate([x, y, heading, m]);
// only keep the 20 last coordinates
positions.setCoordinates(positions.getCoordinates().slice(-20));
// FIXME use speed instead
if (heading && speed) {
markerEl.src = 'images/geolocation_marker_heading.png';
} else {
markerEl.src = 'images/geolocation_marker.png';
}
}
var previousM = 0;
// change center and rotation before render
map.beforeRender(function(map, frameState) {
if (frameState !== null) {
// use sampling period to get a smooth transition
var m = frameState.time - deltaMean * 1.5;
m = Math.max(m, previousM);
previousM = m;
// interpolate position along positions LineString
var c = positions.getCoordinateAtM(m, true);
var view = frameState.viewState;
if (c) {
view.rotation = -c[2];
marker.setPosition(c);
}
}
return true; // Force animation to continue
});
// postcompose callback
function render() {
map.render();
}
// geolocate device
var geolocateBtn = document.getElementById('locate');
geolocateBtn.addEventListener('click', function() {
if(locateUser){
geolocation.setTracking(false);
geolocateBtn.style.backgroundColor = 'rgba(255,0,0,1)';
locateUser = false;
}
else{
geolocation.setTracking(true);
map.getView().setCenter(geolocation.getPosition());
geolocateBtn.style.backgroundColor = 'rgba(0,128,0,1)';
map.on('postcompose', render);
map.render();
locateUser = true;
}
}, false);
addLocations(QueryString);
function addLocations(addressArr) {
if (nextAddress < addressArr.length) {
setTimeout(function(){
if (addressArr[nextAddress] !== undefined){
geocodeAddress(addressArr[nextAddress]);
}
}, delay);
}
if(nextAddress == addressArr.length) {
view.fitExtent(vectorSource.getExtent(), map.getSize());
}
}
function geocodeAddress (location) {
$.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address='+location.address+'&sensor=false', null, function (data) {
if(data.status === 'OK'){
var p = data.results[0].geometry.location;
var color = location.status == 'incomplete' ? 'red' : 'green';
var pointFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([p.lng, p.lat], 'EPSG:4326',
'EPSG:3857')),
fillColor: color,
id: location.id
});
vectorSource.addFeature(pointFeature);
addresses.push(pointFeature);
nextAddress+=1;
addLocations(QueryString);
}
if(data.status === 'OVER_QUERY_LIMIT'){
delay += delay;
}
});
}
Here is the relevant ol3 code that's causing the rotation to happen.
By setting view.rotation = 0; you may resolve the issue.