I have a problem where I kwow that my bluetooth module (HC-05) is connected to a processing sketch, but nothing ever gets sent from the processing sketch,why?
No error messages but the info never gets sent over because I never see it in Arduino, where it would be printed to the Serial Monitor.
Full Processing Code:
import processing.serial.*;
import controlP5.*;
Serial myPort;
ControlP5 cp5;
int slider1 = 0;
int slider2 = 0;
int slider3 = 0;
void setup() {
size(800, 800);
cp5 = new ControlP5(this);
PFont roboto = createFont("Roboto-Bold.ttf", 1, true);
ControlFont font = new ControlFont(roboto, 28);
Controller Aslider1 = cp5.addSlider("slider1")
.setPosition(85, 100)
.setCaptionLabel("Red")
.setRange(0, 255)
.setWidth(191)
.setHeight(50);
cp5.getController("slider1").getValueLabel().setFont(font).align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
cp5.getController("slider1").getCaptionLabel().setFont(font).align(ControlP5.RIGHT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
Controller Aslider2 = cp5.addSlider("slider2")
.setPosition(301, 100)
.setCaptionLabel("Green")
.setRange(0, 255)
.setWidth(191)
.setHeight(50);
cp5.getController("slider2").getValueLabel().setFont(font).align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
cp5.getController("slider2").getCaptionLabel().setFont(font).align(ControlP5.RIGHT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
Controller Aslider3 = cp5.addSlider("slider3")
.setPosition(517, 100)
.setCaptionLabel("Blue")
.setRange(0, 255)
.setWidth(191)
.setHeight(50);
cp5.getController("slider3").getValueLabel().setFont(font).align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
cp5.getController("slider3").getCaptionLabel().setFont(font).align(ControlP5.RIGHT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
myPort = new Serial(this, "COM5", 9600);
}
void draw() {
background(255, 100, 100);
fill(255);
stroke(1);
rectMode(CENTER);
rect(width/2, 350, 200, 75);
fill(0);
textSize(32);
text("Send", width/2 - textWidth("Send") / 2, 350 + 10);
if (mouseX > width/2 - 100 && mouseX < width/2 + 100 && mouseY > 350 - 75/2 && mouseY < 350 + 75/2) {
if (mousePressed) {
fill(100);
stroke(1);
rectMode(CENTER);
rect(width/2, 350, 200, 75);
fill(0);
textSize(32);
text("Send", width/2 - textWidth("Send") / 2, 350 + 10);
} else {
fill(170);
stroke(1);
rectMode(CENTER);
rect(width/2, 350, 200, 75);
fill(0);
textSize(32);
text("Send", width/2 - textWidth("Send") / 2, 350 + 10);
}
}
}
void mouseReleased() {
if (mouseX > width/2 - 100 && mouseX < width/2 + 100 && mouseY > 350 - 75/2 && mouseY < 350 + 75/2) {
fill(100);
stroke(1);
rectMode(CENTER);
rect(width/2, 350, 200, 75);
fill(0);
textSize(32);
text("Send", width/2 - textWidth("Send") / 2, 350 + 10);
println(hex(color(int(slider1), int(slider2), int(slider3))).toString().substring(2));
myPort.write(hex(color(int(slider1), int(slider2), int(slider3))).toString().substring(2));
myPort.clear();
}
}
Full Arduino Code:
#include <SoftwareSerial.h>
#include <Adafruit_NeoPixel.h>
const int PIN = 6;
const int NUMPIXELS = 30;
const byte rxPin = 2;
const byte txPin = 3;
SoftwareSerial mySerial (rxPin, txPin);
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
unsigned long currentMillis;
unsigned long loopMillis;
unsigned long waitMillis;
int interval = 100;
int waitInterval = 0;
int redBrightness = 0;
int greenBrightness = 0;
int blueBrightness = 0;
bool wait = false;
bool goToRed = true;
bool goToOrange = false;
bool goToYellow = false;
bool goToGreen = false;
bool goToAqua = false;
bool goToPurple = false;
String hexValue;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
mySerial.begin(9600);
pixels.begin();
pixels.show();
}
void loop() {
if (mySerial.available() > 0) {
hexValue = mySerial.read();
Serial.println(hexValue);
if (hexValue != "shiftN" || hexValue != "shiftY") {
shiftMode = false;
// value is a hex
redBrightness = hexValue.substring(0, 2).toInt();
greenBrightness = hexValue.substring(2, 4).toInt();
greenBrightness = hexValue.substring(4, 6).toInt();
} else {
if (hexValue = "shiftY") {
shiftMode = true;
} else {
shiftMode = false;
}
}
}
pixels.show();
setColor(redBrightness, greenBrightness, blueBrightness);
}
void setColor(int red, int green, int blue) {
for (int i = 0; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, red, green, blue);
}
}
Thanks for the help, cheers!
Other links:
https://discourse.processing.org/t/nothing-gets-sent-to-arduino-from-processing/13654
https://arduino.stackexchange.com/questions/68233/nothing-gets-sent-to-arduino-from-processing
https://forum.arduino.cc/index.php?board=11.0
Assuming myPort is an output stream, it may be buffered. If so, try flushing it after writing:
myPort.flush();
check if hc-05 9600 baud or 38400 baud
For everyone wondering, here is updated code:
Arduino:
#include <SoftwareSerial.h>
#include <Adafruit_NeoPixel.h>
const int pin = 6;
const int numOfPixels = 30;
int r = 0;
int g = 0;
int b = 0;
Adafruit_NeoPixel pixels(numOfPixels, pin, NEO_GRB + NEO_KHZ800);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pixels.begin();
pixels.show();
pinMode(11, OUTPUT);
}
void loop() {
pixels.show();
// put your main code here, to run repeatedly:
if (Serial.available() > 0) {
Serial.println(String(Serial.read()));
r = Serial.parseInt();
g = Serial.parseInt();
b = Serial.parseInt();
setColor(r, g, b);
}
serialFlush();
}
void setColor(int red, int green, int blue) {
pixels.fill(pixels.Color(red, green, blue), 0, numOfPixels);
Serial.println("Red");
Serial.println(red);
Serial.println("Green");
Serial.println(green);
Serial.println("Blue");
Serial.println(blue);
}
void serialFlush() {
while (Serial.available() > 0) {
char t = Serial.read();
}
}
Processing:
import processing.serial.*;
import controlP5.*;
Serial myPort;
ControlP5 cp5;
int slider1 = 0;
int slider2 = 0;
int slider3 = 0;
void setup() {
size(800, 800);
cp5 = new ControlP5(this);
PFont roboto = createFont("Roboto-Bold.ttf", 1, true);
ControlFont font = new ControlFont(roboto, 28);
Controller Aslider1 = cp5.addSlider("slider1")
.setPosition(85, 100)
.setCaptionLabel("Red")
.setRange(0, 255)
.setWidth(191)
.setHeight(50);
cp5.getController("slider1").getValueLabel().setFont(font).align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
cp5.getController("slider1").getCaptionLabel().setFont(font).align(ControlP5.RIGHT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
Controller Aslider2 = cp5.addSlider("slider2")
.setPosition(301, 100)
.setCaptionLabel("Green")
.setRange(0, 255)
.setWidth(191)
.setHeight(50);
cp5.getController("slider2").getValueLabel().setFont(font).align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
cp5.getController("slider2").getCaptionLabel().setFont(font).align(ControlP5.RIGHT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
Controller Aslider3 = cp5.addSlider("slider3")
.setPosition(517, 100)
.setCaptionLabel("Blue")
.setRange(0, 255)
.setWidth(191)
.setHeight(50);
cp5.getController("slider3").getValueLabel().setFont(font).align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
cp5.getController("slider3").getCaptionLabel().setFont(font).align(ControlP5.RIGHT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
myPort = new Serial(this, "COM4", 9600);
}
void draw() {
background(slider1, slider2, slider3);
fill(255);
stroke(1);
rectMode(CENTER);
rect(width/2, 350, 200, 75);
fill(0);
textSize(32);
text("Send", width/2 - textWidth("Send") / 2, 350 + 10);
if (mouseX > width/2 - 100 && mouseX < width/2 + 100 && mouseY > 350 - 75/2 && mouseY < 350 + 75/2) {
if (mousePressed) {
fill(100);
stroke(1);
rectMode(CENTER);
rect(width/2, 350, 200, 75);
fill(0);
textSize(32);
text("Send", width/2 - textWidth("Send") / 2, 350 + 10);
} else {
fill(170);
stroke(1);
rectMode(CENTER);
rect(width/2, 350, 200, 75);
fill(0);
textSize(32);
text("Send", width/2 - textWidth("Send") / 2, 350 + 10);
}
}
}
void mouseReleased() {
if (mouseX > width/2 - 100 && mouseX < width/2 + 100 && mouseY > 350 - 75/2 && mouseY < 350 + 75/2) {
fill(100);
stroke(1);
rectMode(CENTER);
rect(width/2, 350, 200, 75);
fill(0);
textSize(32);
text("Send", width/2 - textWidth("Send") / 2, 350 + 10);
myPort.write(str(slider1) + " " + str(slider2) + " " + str(slider3));
println(str(slider1) + " " + str(slider2) + " " + str(slider3));
}
}
Then look at this link:
https://forum.arduino.cc/index.php?topic=634061.0
I'm trying to calculate the 8 (4+4) vertices of a view volume's plane : near and far.
I need this vertices to draw, in webGL, the view volume of a camera.
So far I managed to calculate them by using trigonometry from each perspective but somehow the result does not seem accurate when I draw the vertices.
I reached this equations for vertices so far:
y = sqrt(hypotenuse^2 - plane^2)
x = sqrt(hypotenuse^2 - plane^2)
z = plane (near or far)
Can anyone help? Thank you in advance.
you can just project a standard cube through an inverse projection matrix.
const m4 = twgl.m4;
const gl = document.querySelector("canvas").getContext("webgl");
const vs = `
attribute vec4 position;
uniform mat4 u_worldViewProjection;
void main() {
gl_Position = u_worldViewProjection * position;
}
`;
const fs = `
precision mediump float;
void main() {
gl_FragColor = vec4(1, 0, 0, 1);
}
`;
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);
const arrays = {
position: [
-1, 1, -1,
1, 1, -1,
1, -1, -1,
-1, -1, -1,
-1, 1, 1,
1, 1, 1,
1, -1, 1,
-1, -1, 1,
],
indices: [
0, 1, 1, 2, 2, 3, 3, 0,
4, 5, 5, 6, 6, 7, 7, 4,
0, 4, 1, 5, 2, 6, 3, 7,
],
};
const bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
function render(time) {
time *= 0.001;
twgl.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
let projectionToViewWith;
{
const fov = 30 * Math.PI / 180;
const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
const zNear = 0.5;
const zFar = 100;
projectionToViewWith = m4.perspective(fov, aspect, zNear, zFar);
}
let projectionToBeViewed;
{
const fov = 30 * Math.PI / 180;
const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
const zNear = 2;
const zFar = 10;
projectionToBeViewed = m4.perspective(fov, aspect, zNear, zFar);
}
const inverseProjectionToBeViewed = m4.inverse(projectionToBeViewed);
const radius = 20;
const eye = [Math.sin(time) * radius, 4, Math.cos(time) * radius];
const target = [0, 0, 0];
const up = [0, 1, 0];
const camera = m4.lookAt(eye, target, up);
const view = m4.inverse(camera);
const viewProjection = m4.multiply(projectionToViewWith, view);
const worldViewProjection = m4.multiply(
viewProjection,
inverseProjectionToBeViewed);
gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
twgl.setUniforms(programInfo, {
u_worldViewProjection: worldViewProjection,
});
twgl.drawBufferInfo(gl, bufferInfo, gl.LINES);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<canvas></canvas>
To get the points of the 8 corners you just have to do a reverse projection. The projection matrix takes the space of the frustum that is fovy tall, fovy * aspect wide, starting at -zNear and ending at -zFar and converting that space to -1 <-> +1 box after the perspective divide.
To go backward and compute the points of that box we just project a -1 to +1 box through the inverse projection matrix and do the perpective divide again (which is exactly what's happening in the example above, we're just doing it all in the GPU)
So, we pull it out of the GPU and do it in JavaScript
[
[-1, 1, -1],
[ 1, 1, -1],
[ 1, -1, -1],
[-1, -1, -1],
[-1, 1, 1],
[ 1, 1, 1],
[ 1, -1, 1],
[-1, -1, 1],
].forEach((point) => {
console.log(m4.transformPoint(inverseProjectionMatrix, point));
});
Here's an example.
const m4 = twgl.m4;
const gl = document.querySelector("canvas").getContext("webgl");
const vs = `
attribute vec4 position;
uniform mat4 u_worldViewProjection;
void main() {
gl_Position = u_worldViewProjection * position;
gl_PointSize = 10.;
}
`;
const fs = `
precision mediump float;
uniform vec4 u_color;
void main() {
gl_FragColor = u_color;
}
`;
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);
const positions = [
-1, 1, -1,
1, 1, -1,
1, -1, -1,
-1, -1, -1,
-1, 1, 1,
1, 1, 1,
1, -1, 1,
-1, -1, 1,
];
const arrays = {
position: positions,
indices: [
0, 1, 1, 2, 2, 3, 3, 0,
4, 5, 5, 6, 6, 7, 7, 4,
0, 4, 1, 5, 2, 6, 3, 7,
],
};
const bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
function render(time) {
time *= 0.001;
twgl.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
let projectionToViewWith;
{
const fov = 30 * Math.PI / 180;
const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
const zNear = 0.5;
const zFar = 100;
projectionToViewWith = m4.perspective(fov, aspect, zNear, zFar);
}
let projectionToBeViewed;
{
const fov = 30 * Math.PI / 180;
const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
const zNear = 2;
const zFar = 10;
projectionToBeViewed = m4.perspective(fov, aspect, zNear, zFar);
}
const inverseProjectionToBeViewed = m4.inverse(projectionToBeViewed);
const radius = 20;
const eye = [Math.sin(time) * radius, 4, Math.cos(time) * radius];
const target = [0, 0, 0];
const up = [0, 1, 0];
const camera = m4.lookAt(eye, target, up);
const view = m4.inverse(camera);
const viewProjection = m4.multiply(projectionToViewWith, view);
const worldViewProjection = m4.multiply(
viewProjection,
inverseProjectionToBeViewed);
gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
twgl.setUniforms(programInfo, {
u_worldViewProjection: worldViewProjection,
u_color: [1, 0, 0, 1],
});
twgl.drawBufferInfo(gl, bufferInfo, gl.LINES);
// just because I'm lazy let's draw each point one at a time
// note: since in our case the frustum is not moving we
// could have computed these at init time.
const positionLoc = programInfo.attribSetters.position.location;
gl.disableVertexAttribArray(positionLoc);
for (let i = 0; i < positions.length; i += 3) {
const point = positions.slice(i, i + 3);
const worldPosition = m4.transformPoint(
inverseProjectionToBeViewed, point);
gl.vertexAttrib3f(positionLoc, ...worldPosition);
twgl.setUniforms(programInfo, {
u_color: [0, 1, 0, 1],
u_worldViewProjection: viewProjection,
});
gl.drawArrays(gl.POINT, 0, 1);
}
requestAnimationFrame(render);
}
requestAnimationFrame(render);
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<canvas></canvas>
Mention in a comment you wanted to show the view frustum of a camera in one canvas in another canvas.
That's effectively what's happening above except the camera in canvasWhosFrustumWeWantToRender is not moving. Instead it's just sitting at the origin looking down the -Z axis with +Y up. To allow the frustum to move to show where it is relative to teh camera just need to add in the camera matrix
const m4 = twgl.m4;
const gl = document.querySelector("canvas").getContext("webgl");
const ext = gl.getExtension("OES_standard_derivatives");
const vs = `
attribute vec4 position;
uniform mat4 u_worldViewProjection;
varying vec3 v_position;
void main() {
gl_Position = u_worldViewProjection * position;
v_position = position.xyz; // for fake lighting
}
`;
const fs = `
#extension GL_OES_standard_derivatives : enable
precision mediump float;
varying vec3 v_position;
uniform vec4 u_color;
void main() {
vec3 fdx = dFdx(v_position);
vec3 fdy = dFdy(v_position);
vec3 n = normalize(cross(fdx,fdy));
float l = dot(n, normalize(vec3(1,2,-3))) * .5 + .5;
gl_FragColor = u_color;
gl_FragColor.rgb *= l;
}
`;
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);
const arrays = {
position: [
-1, 1, -1,
1, 1, -1,
1, -1, -1,
-1, -1, -1,
-1, 1, 1,
1, 1, 1,
1, -1, 1,
-1, -1, 1,
],
indices: [
0, 1, 1, 2, 2, 3, 3, 0,
4, 5, 5, 6, 6, 7, 7, 4,
0, 4, 1, 5, 2, 6, 3, 7,
],
};
const concat = twgl.primitives.concatVertices;
const reorient = twgl.primitives.reorientVertices;
const wireCubeBufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
const solidCubeBufferInfo = twgl.primitives.createCubeBufferInfo(gl, 2);
const cameraBufferInfo = twgl.createBufferInfoFromArrays(gl,
concat([
reorient(twgl.primitives.createCubeVertices(2),
m4.translation([0, 0, 1])),
reorient(twgl.primitives.createTruncatedConeVertices(0, 1, 2, 12, 1),
m4.rotationX(Math.PI * -.5)),
])
);
const black = [0, 0, 0, 1];
const blue = [0, 0, 1, 1];
function drawScene(viewProjection, clearColor) {
gl.clearColor(...clearColor);
gl.clear(gl.COLOR_BUFFER_BIT);
const numCubes = 10;
for (let i = 0; i < numCubes; ++i) {
const u = i / numCubes;
let mat = m4.rotationY(u * Math.PI * 2);
mat = m4.translate(mat, [0, 0, 10]);
mat = m4.scale(mat, [1, 1 + u * 23 % 1, 1]);
mat = m4.translate(mat, [0, .5, 0]);
mat = m4.multiply(viewProjection, mat);
drawModel(solidCubeBufferInfo, mat, [u, u * 3 % 1, u * 7 % 1,1]);
}
}
function drawModel(bufferInfo, worldViewProjection, color, mode) {
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
twgl.setUniforms(programInfo, {
u_worldViewProjection: worldViewProjection,
u_color: color,
});
twgl.drawBufferInfo(gl, bufferInfo, mode);
}
function render(time) {
time *= 0.001;
twgl.resizeCanvasToDisplaySize(gl.canvas);
const width = gl.canvas.width;
const height = gl.canvas.height;
const halfWidth = width / 2;
gl.viewport(0, 0, width, height);
gl.disable(gl.SCISSOR_TEST);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.enable(gl.DEPTH_TEST);
let projectionToViewWith; // the projection on the right
{
const fov = 60 * Math.PI / 180;
const aspect = gl.canvas.clientWidth / 2 / gl.canvas.clientHeight;
const zNear = 0.5;
const zFar = 100;
projectionToViewWith = m4.perspective(fov, aspect, zNear, zFar);
}
let projectionToBeViewed; // the projeciton on the left
{
const fov = 60 * Math.PI / 180;
const aspect = gl.canvas.clientWidth / 2 / gl.canvas.clientHeight;
const zNear = 1.5;
const zFar = 15;
projectionToBeViewed = m4.perspective(fov, aspect, zNear, zFar);
}
const inverseProjectionToBeViewed = m4.inverse(projectionToBeViewed);
let cameraViewingScene; // camera for right view
{
const t1 = 0;
const radius = 30;
const eye = [Math.sin(t1) * radius, 4, Math.cos(t1) * radius];
const target = [0, 0, 0];
const up = [0, 1, 0];
cameraViewingScene = m4.lookAt(eye, target, up);
}
let cameraInScene; // camera for left view
{
const t1 = time;
const t2 = time + .4;
const r1 = 10 + Math.sin(t1);
const r2 = 10 + Math.sin(t2) * 2;
const eye = [Math.sin(t1) * r1, 0 + Math.sin(t1) * 4, Math.cos(t1) * r1];
const target = [Math.sin(t2) * r2, 1 + Math.sin(t2), Math.cos(t2) * r2];
const up = [0, 1, 0];
cameraInScene = m4.lookAt(eye, target, up);
}
// there's only one shader program so just set it once
gl.useProgram(programInfo.program);
// draw only on left half of canvas
gl.enable(gl.SCISSOR_TEST);
gl.scissor(0, 0, halfWidth, height);
gl.viewport(0, 0, halfWidth, height);
// draw the scene on the left using the camera inside the scene
{
const view = m4.inverse(cameraInScene);
const viewProjection = m4.multiply(projectionToBeViewed, view);
drawScene(viewProjection, [.9, 1, .9, 1]);
}
// draw only on right half of canvas
gl.scissor(halfWidth, 0, halfWidth, height);
gl.viewport(halfWidth, 0, halfWidth, height);
// draw the same scene on the right using the camera outside the scene
{
const view = m4.inverse(cameraViewingScene);
const viewProjection = m4.multiply(projectionToViewWith, view);
drawScene(viewProjection, [.9, 1, 1, 1]);
// draw the in scene camera's frustum
{
const world = m4.multiply(cameraInScene, inverseProjectionToBeViewed);
const worldViewProjection = m4.multiply(viewProjection, world);
drawModel(wireCubeBufferInfo, worldViewProjection, black, gl.LINES);
}
// draw the in scene camera's camera model
{
const worldViewProjection = m4.multiply(viewProjection, cameraInScene);
drawModel(cameraBufferInfo, worldViewProjection, blue);
}
}
requestAnimationFrame(render);
}
requestAnimationFrame(render);
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<canvas></canvas>
I have two classes in one package one extends lcudi.Canvas and another extends lwuit.Form
I create two buttons on my Form
My purpose is displaying the canvas when one of the buttons is pressed.
In my mind this function should display the canvas .
setFullScreenMode(true);
but it doesn't.
This is the Canvas Class
[code]
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.rms.*;
import javax.microedition.media.*;
import javax.microedition.media.control.*;
import java.io.*;
import java.util.*;
import javax.microedition.rms.*;
public class MainCanvas extends Canvas implements Runnable {
HelloLWUITMidlet mid;
int screen_width;
int screen_height;
int mode;
int selected;
String current_time;
int[] time_numbers;
long current_time_milli;
long start_timestamp;
int selected_preset;
static String s;
Random generator;
final static int MODE_SETUP = 0;
final static int MODE_RUNNING = 1;
final static int MODE_RINGING = 2;
final static int MODE_PRESETS_TYPE = 3;
final static int MODE_PRESETS_MODE = 4;
public MainCanvas(HelloLWUITMidlet h) {
mid =h;
this.setFullScreenMode(true);
new Thread(this).start();
screen_width = this.getWidth();
screen_height = this.getHeight();
time_numbers = new int[4];
setCurrentTime();
initImages();
generator = new Random(System.currentTimeMillis());
mode = MODE_SETUP;
selected = 0;
}
Image back;
Image numbers;
Image font;
int numberFontWidths[];
int numberFontOffsets[];
int numberFontCodes[];
int fontData[] = new int[]
{
0, 0, 0, 0, 4,
0, 0, 4, 16, 3,
4, 0, 4, 16, 4,
8, 0, 10, 16, 10,
18, 0, 7, 16, 7,
25, 0, 9, 16, 9,
34, 0, 9, 16, 8,
43, 0, 2, 16, 2,
45, 0, 4, 16, 4,
49, 0, 4, 16, 4,
53, 0, 6, 16, 6,
59, 0, 11, 16, 10,
70, 0, 3, 16, 3,
73, 0, 5, 16, 5,
78, 0, 3, 16, 3,
81, 0, 5, 16, 4,
86, 0, 8, 16, 8,
94, 0, 4, 16, 4,
98, 0, 7, 16, 6,
105, 0, 7, 16, 7,
112, 0, 8, 16, 8,
120, 0, 7, 16, 6,
127, 0, 7, 16, 7,
134, 0, 6, 16, 6,
140, 0, 7, 16, 7,
147, 0, 7, 16, 7,
154, 0, 3, 16, 3,
157, 0, 3, 16, 3,
160, 0, 11, 16, 10,
171, 0, 11, 16, 10,
182, 0, 11, 16, 10,
193, 0, 6, 16, 6,
199, 0, 13, 16, 13,
212, 0, 8, 16, 8,
220, 0, 8, 16, 8,
228, 0, 8, 16, 7,
236, 0, 9, 16, 9,
245, 0, 6, 16, 6,
0, 16, 6, 16, 6,
6, 16, 9, 16, 9,
15, 16, 10, 16, 9,
25, 16, 4, 16, 3,
29, 16, 6, 16, 5,
35, 16, 8, 16, 8,
43, 16, 6, 16, 6,
49, 16, 11, 16, 11,
60, 16, 10, 16, 9,
70, 16, 10, 16, 9,
80, 16, 8, 16, 7,
88, 16, 10, 16, 9,
98, 16, 8, 16, 7,
106, 16, 7, 16, 7,
113, 16, 6, 16, 6,
119, 16, 9, 16, 9,
128, 16, 7, 16, 7,
135, 16, 12, 16, 11,
147, 16, 7, 16, 7,
154, 16, 7, 16, 6,
161, 16, 7, 16, 6,
168, 16, 4, 16, 4,
172, 16, 5, 16, 4,
177, 16, 4, 16, 4,
181, 16, 13, 16, 13,
194, 16, 6, 16, 6,
200, 16, 6, 16, 6,
206, 16, 8, 16, 7,
214, 16, 8, 16, 7,
222, 16, 6, 16, 6,
228, 16, 8, 16, 7,
236, 16, 7, 16, 7,
243, 16, 4, 16, 4,
247, 16, 8, 16, 7,
0, 32, 8, 16, 7,
8, 32, 3, 16, 3,
11, 32, 3, 16, 3,
14, 32, 7, 16, 6,
21, 32, 3, 16, 3,
24, 32, 11, 16, 11,
35, 32, 8, 16, 7,
43, 32, 7, 16, 7,
50, 32, 8, 16, 7,
58, 32, 8, 16, 7,
66, 32, 5, 16, 4,
71, 32, 5, 16, 5,
76, 32, 4, 16, 4,
80, 32, 7, 16, 7,
87, 32, 6, 16, 6,
93, 32, 10, 16, 9,
103, 32, 6, 16, 6,
109, 32, 6, 16, 6,
115, 32, 6, 16, 5,
121, 32, 6, 16, 6,
127, 32, 6, 16, 6,
133, 32, 6, 16, 6,
139, 32, 11, 16, 10
};
int[] fontCodes = new int[]
{
0x0020,
0x0021,
0x0022,
0x0023,
0x0024,
0x0025,
0x0026,
0x0027,
0x0028,
0x0029,
0x002a,
0x002b,
0x002c,
0x002d,
0x002e,
0x002f,
0x0030,
0x0031,
0x0032,
0x0033,
0x0034,
0x0035,
0x0036,
0x0037,
0x0038,
0x0039,
0x003a,
0x003b,
0x003c,
0x003d,
0x003e,
0x003f,
0x0040,
0x0041,
0x0042,
0x0043,
0x0044,
0x0045,
0x0046,
0x0047,
0x0048,
0x0049,
0x004a,
0x004b,
0x004c,
0x004d,
0x004e,
0x004f,
0x0050,
0x0051,
0x0052,
0x0053,
0x0054,
0x0055,
0x0056,
0x0057,
0x0058,
0x0059,
0x005a,
0x005b,
0x005c,
0x005d,
0x005e,
0x005f,
0x0060,
0x0061,
0x0062,
0x0063,
0x0064,
0x0065,
0x0066,
0x0067,
0x0068,
0x0069,
0x006a,
0x006b,
0x006c,
0x006d,
0x006e,
0x006f,
0x0070,
0x0071,
0x0072,
0x0073,
0x0074,
0x0075,
0x0076,
0x0077,
0x0078,
0x0079,
0x007a,
0x007b,
0x007c,
0x007d,
0x007e
};
int[] fontKerning = new int[]
{
70, 44, -1,
70, 46, -1,
76, 86, -1,
76, 89, -1,
80, 44, -2,
80, 46, -2,
84, 44, -1,
84, 45, -1,
84, 46, -1,
84, 97, -1,
84, 99, -1,
84, 101, -1,
84, 111, -1,
84, 115, -1,
86, 44, -1,
86, 46, -1,
87, 44, -1,
87, 46, -1,
89, 44, -2,
89, 45, -1,
89, 46, -2,
89, 58, -1,
89, 59, -1,
89, 97, -1,
89, 101, -1,
89, 111, -1,
114, 44, -1,
114, 46, -1
};
int[] fontCodeTable;
public void initImages() {
try{
// back = Image.createImage("/numbers.png");
numbers = Image.createImage("/numbers.png");
font = Image.createImage("/font.png");
numberFontWidths = new int[]
{
17,10,15,15,18,15,16,15,15,16,8
};
int offset = 0;
numberFontOffsets = new int[numberFontWidths.length];
for(int i=0;i<numberFontWidths.length;i++) {
numberFontOffsets[i] = offset;
offset+=numberFontWidths[i];
}
numberFontCodes = new int[256];
numberFontCodes[(int) "0".charAt(0)] = 0;
numberFontCodes[(int) "1".charAt(0)] = 1;
numberFontCodes[(int) "2".charAt(0)] = 2;
numberFontCodes[(int) "3".charAt(0)] = 3;
numberFontCodes[(int) "4".charAt(0)] = 4;
numberFontCodes[(int) "5".charAt(0)] = 5;
numberFontCodes[(int) "6".charAt(0)] = 6;
numberFontCodes[(int) "7".charAt(0)] = 7;
numberFontCodes[(int) "8".charAt(0)] = 8;
numberFontCodes[(int) "9".charAt(0)] = 9;
numberFontCodes[(int) ":".charAt(0)] = 10;
fontCodeTable = new int[256];
for(int i=0;i<fontCodes.length;i++)
fontCodeTable[fontCodes[i]] = i;
} catch(Exception e) {
}
}
public void setCurrentTime() {
current_time = "";
for(int i=0;i<4;i++) {
current_time = current_time + Integer.toString(time_numbers[i]);
if(i==1)
current_time = current_time + ":";
}
}
public void run() {
while(true) {
update();
Refresh();
this.repaint();
long nexttime = System.currentTimeMillis() +60;
// set your framerate here
while(System.currentTimeMillis() < nexttime)
Thread.yield();
}
}
int blinker;
public void update() {
switch(mode) {
case MODE_SETUP:
case MODE_PRESETS_TYPE:
case MODE_PRESETS_MODE:
blinker++;
break;
case MODE_RUNNING:
int left = (int) (current_time_milli - (System.currentTimeMillis() - start_timestamp));
if(left<=0) {
playMidi();
mode = MODE_RINGING;
}
int minutes = left / (60*1000);
int seconds = (left-minutes*60*1000)/1000;
String min_string = ""+minutes;
if(min_string.length()==1)min_string = "0"+min_string;
String sec_string = ""+seconds;
if(sec_string.length()==1)sec_string = "0"+sec_string;
current_time = min_string+":"+sec_string;
break;
case MODE_RINGING:
blinker++;
shake_x = (generator.nextInt()%5);
shake_y = (generator.nextInt()%5);
break;
}
}
public void keyPressed(int key) {
if(mode == MODE_SETUP) {
int number_pressed = -1;
if(key == KEY_NUM0)
number_pressed = 0;
if(key == KEY_NUM1)
number_pressed = 1;
if(key == KEY_NUM2)
number_pressed = 2;
if(key == KEY_NUM3)
number_pressed = 3;
if(key == KEY_NUM4)
number_pressed = 4;
if(key == KEY_NUM5)
number_pressed = 5;
if(key == KEY_NUM6 & selected != 2)
number_pressed = 6;
if(key == KEY_NUM7 & selected != 2)
number_pressed = 7;
if(key == KEY_NUM8 & selected != 2)
number_pressed = 8;
if(key == KEY_NUM9& selected != 2)
number_pressed = 9;
if(number_pressed>-1 & selected < 4) {
time_numbers[selected] = number_pressed;
selected++;
} else {
int action = getGameAction(key);
if(action == UP) {
if(selected<4) {
if(selected==2)
time_numbers[2] = (time_numbers[2]+1)%6;
else
time_numbers[selected] = (time_numbers[selected]+1)%10;
} else {
if(selected>4)
selected--;
else
selected=0;
}
}
if(action == DOWN) {
if(selected<4) {
int new_val = time_numbers[selected]-1;
if(selected==2) {
if(new_val==-1)
new_val=5;
} else {
if(new_val==-1)
new_val=9;
}
time_numbers[selected] = new_val;
} else {
selected++;
if(selected>6)
selected = 6;
}
}
if(action == FIRE) {
if(selected<4)
selected++;
else {
if(selected==4) {
start_timestamp = System.currentTimeMillis();
int minutes = ((time_numbers[0]*10) + time_numbers[1]);
int seconds = ((time_numbers[2]*10) + time_numbers[3])+1;
current_time_milli = (minutes * 60 * 1000) + (seconds * 1000);
mode = MODE_RUNNING;
}
if(selected==5) {
selected=0;
mode = MODE_PRESETS_TYPE;
}
if(selected==6) {
mid.notifyDestroyed();
}
}
}
if(action == LEFT & selected>0) {
selected--;
}
if(action == RIGHT & selected<6)
selected++;
}
} else if(mode==MODE_PRESETS_TYPE) {
int action = getGameAction(key);
if(action == UP && selected>0)
selected--;
if(action == DOWN && selected<2)
selected++;
if(action == FIRE) {
selected_preset = selected;
selected = 0;
mode = MODE_PRESETS_MODE;
}
} else if(mode==MODE_PRESETS_MODE)
{
int action = getGameAction(key);
if(action == UP && selected>0)
selected--;
if(action == DOWN && selected<1)
selected++;
if(action == FIRE) {
int[] presets = new int[]
{
0,3,0,0,
0,4,3,0,
0,5,3,0,
0,5,0,0,
0,6,5,0,
0,8,0,0,
};
int offset = selected * 12 + selected_preset * 4;
time_numbers[0]=presets[offset++];
time_numbers[1]=presets[offset++];
time_numbers[2]=presets[offset++];
time_numbers[3]=presets[offset++];
mode = MODE_SETUP;
selected = 4;
}
}
else {
int action = getGameAction(key);
if(action==FIRE)
{
mode = MODE_SETUP;
stopMidi();
}
}
if(mode != MODE_RUNNING)
setCurrentTime();
}
public void keyReleased(int key) {
}
int shake_x;
int shake_y;
public void paint(Graphics g) {
int color = 0xFFFF00;
if(mode == MODE_RINGING && (blinker%10>5))
color = 0xFF0000;
g.setColor(color);
g.fillRect( 0, 0,screen_width ,screen_height );
Graphics gg ;
color = 0x00FF00;
g.setColor(color);
g.fillRect(0,50,50,0);
color = 0x000FF;
g.drawString( s ,40,50, 0);
int x = (screen_width-128)>>1;
int y = (screen_height-128)>>1;
if(mode != MODE_PRESETS_TYPE && mode != MODE_PRESETS_MODE)
paintNumbersCentered(g);
switch(mode) {
case MODE_SETUP:
y = (screen_height>>1)+10;
if(selected!=4 | (blinker%20>10)) {
paintTextCentered(g,"START",y);
}
y+=15;
if(selected!=5 | (blinker%20>10)) {
paintTextCentered(g,"PRESETS",y);
}
y+=15;
if(selected!=6 | (blinker%20>10)) {
paintTextCentered(g,"EXIT",y);
}
break;
case MODE_PRESETS_TYPE:
y = (screen_height>>1)-10;
if(selected!=0 | (blinker%20>10)) {
paintTextCentered(g,"Supreme Runny",y);
}
y+=20;
if(selected!=1 | (blinker%20>10)) {
paintTextCentered(g,"Perfect Plasma",y);
}
y+=20;
if(selected!=2 | (blinker%20>10)) {
paintTextCentered(g,"Hard Boiled",y);
}
break;
case MODE_PRESETS_MODE:
y = (screen_height>>1)-15;
if(selected!=0 | (blinker%20>10)) {
paintTextCentered(g,"Eggs in cold water",y);
y+=13;
paintTextCentered(g,"Start when water is",y);
y+=13;
paintTextCentered(g,"boiling",y);
}
y = (screen_height>>1)+30;
if(selected!=1 | (blinker%20>10)) {
paintTextCentered(g,"Start when putting",y);
y+=13;
paintTextCentered(g,"eggs in boiling water",y);
}
break;
}
}
public void paintNumbersCentered(Graphics g) {
int width = 0;
for(int i=0;i<current_time.length();i++) {
int c = (int) current_time.charAt(i);
width+=numberFontWidths[numberFontCodes[c]];
}
int x = (screen_width - width) >>1;
int y = (screen_height >>1)-15;
for(int i=0;i<current_time.length();i++) {
int c = (int) current_time.charAt(i);
int code = numberFontCodes[c];
int char_w = numberFontWidths[code];
int char_off = numberFontOffsets[code];
int sel = selected;
if(sel>1)sel++;
if(sel!=i | (blinker%20>10)) {
g.setClip(x+shake_x,y+shake_y,char_w,20);
g.drawImage(numbers,x-char_off+shake_x,y+shake_y,0);
}
x+=char_w;
}
}
public void Refresh()
{
Date t = new java.util.Date(System.currentTimeMillis());
s = t.toString();
}
public void paintTextCentered(Graphics g,String text,int y) {
int width = 0;
int textlen = text.length();
for(int i=0;i<textlen;i++) {
int code = fontCodeTable[(int)text.charAt(i)];
int char_width = fontData[code*5+4];
width+=char_width;
}
int x = (screen_width-width)>>1;
int last_char = -1;
for(int i=0;i<textlen;i++) {
int this_char = (int)text.charAt(i);
int code = fontCodeTable[this_char];
int offset = code*5;
int sx = fontData[offset++];
int sy = fontData[offset++];
int sw = fontData[offset++];
int sh = fontData[offset++];
int aw = fontData[offset++];
if(i>0) {
int koff = 0;
int klen = fontKerning.length / 3;
for(int k=0;k<klen;k++) {
koff = k*3;
if(last_char==fontKerning[koff] && this_char==fontKerning[koff+1]) {
x+=fontKerning[koff+2];
break;
}
}
}
if(sw>0 && sh>0) {
g.setClip(x,y,sw,sh);
g.drawImage(font,x-sx,y-sy,0);
}
x+=aw;
last_char = (int)text.charAt(i);
}
}
Player player = null;
public void stopMidi() {
try{
if(player!=null) {
player.stop();
player.deallocate();
}
player = null;
System.gc();
} catch(Exception e) {
System.out.println(e.getMessage());
}
}
public void playMidi() {
try {
stopMidi();
player = Manager.createPlayer(this.getClass().getResourceAsStream("/ring.mid"),"audio/midi");
player.realize();
VolumeControl vc = (VolumeControl) player.getControl("VolumeControl");
vc.setLevel(100);
player.start();
} catch(Exception e) {
System.out.println(e.getMessage());
}
}
protected void hideNotify() {
}
protected void showNotify() {
}
}
[/code]
And that is the Form
[code]
import Pes.*;
//import Pes.MainCanvas;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import com.sun.lwuit.layouts.*;
import com.sun.lwuit.*;
import javax.microedition.lcdui.Canvas;
import com.sun.lwuit.events.*;
import com.sun.lwuit.plaf.*;
public class HelloLWUITMidlet extends MIDlet implements ActionListener {
HelloLWUITMidlet hh;
public void startApp() {
com.sun.lwuit.Display.init(this);
final com.sun.lwuit.Form f = new com.sun.lwuit.Form( " SOFTWARE SCREENS");
final MainCanvas m = new MainCanvas(hh);
f.getStyle().setBgColor(0X99CCFF);
BoxLayout boxlayout =new BoxLayout(BoxLayout.X_AXIS);
com.sun.lwuit.Command exitCommand = new com.sun.lwuit.Command("Exit");
f.addCommand(exitCommand);
f.addCommandListener(this);
final Button button = new Button(" GOALS ");
final Button button1 = new Button(" TIME SETTING");
Style btnstyle = button.getSelectedStyle() ;
Style btnstyle1 = button1.getSelectedStyle() ;
btnstyle.setBgColor(0X0000FF);
btnstyle.setFgColor(0XFFFFFF);
btnstyle1.setBgColor(0X0000FF);
btnstyle1.setFgColor(0XFFFFFF);
// button.getStyle().setBgColor(0X99CCFF);
button1.addActionListener(new ActionListener() {
private int c = 0;
public void actionPerformed(ActionEvent ae) {
c++;
// Display.init(m);
m.setFullScreenMode(true);
}
});
button.addActionListener(new ActionListener() {
private int c = 0;
public void actionPerformed(ActionEvent ae) {
c++;
m.setFullScreenMode(true);
}
});
f.addComponent(button1);
f.addComponent(button);
f.show();
}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {}
public void actionPerformed(ActionEvent ae) {
notifyDestroyed();
}
}
[/code]
Notice :- If you need the images and sounds included in my code to test my application you can download eggtime application from here
http://www.bambalam.se/eggtimer/
You are mixing lwuit and javax.microedition code together.
That is why you need to transfer control from lwuit Display to javax.microedition.Display control. For this you need to call
javax.microedition.lcdui.Display.getDisplay(hh).setCurrent(m);
after you call setFullScreenMode in your actionListener.