Witajcie, staram się w QT poprzez GML wyświetlić model OBJ w WebGL poprzez JavaScript. Problem polega na tym, że gdy w funkcji initializującej bufory zakomentuje uzywanie programu shadera to jeden obiekt przestaje być całkowicie wysowany, pomimo, że programy cieniujące uruchamiane są i tak w pętli rysującej.
Staram się narysować trójkąt 2D (shaderprogram2D), po czym czyszcze bufor głębi? i rysuję obiekt 3D (shaderProgram)
Przygotowywanie shaderów
function initShaders()
{
var vertexShader = getShader(gl,
"attribute highp vec3 aVertexNormal; \
attribute highp vec3 aVertexPosition; \
\
uniform highp mat4 uNormalMatrix; \
uniform mat4 uVMatrix; \
uniform mat4 uPMatrix; \
uniform mat4 uMMatrix; \
\
varying mediump vec4 vColor; \
varying highp vec3 vLighting; \
\
void main(void) { \
gl_Position = uPMatrix * uVMatrix * uMMatrix * vec4(aVertexPosition, 1.0); \
highp vec3 ambientLight = vec3(0.5, 0.5, 0.5); \
highp vec3 directionalLightColor = vec3(0.75, 0.75, 0.75); \
highp vec3 directionalVector = vec3(0.0, 0.8,2); \
highp vec4 transformedNormal = uNormalMatrix * vec4(aVertexNormal, 1.0); \
highp float directional = max(dot(transformedNormal.xyz, directionalVector), 0.0); \
vLighting = ambientLight + (directionalLightColor * directional); \
}", gl.VERTEX_SHADER);
var fragmentShader = getShader(gl,
"varying highp vec3 vLighting; \
\
uniform highp vec3 ambientColor; \
uniform highp vec3 difusseColor; \
uniform bool transparentObj; \
uniform sampler2D uSampler; \
\
void main(void) {\
gl_FragColor = (transparentObj) ? vec4(difusseColor * vLighting, 0.5) : vec4(difusseColor * vLighting, 1.0);
}", gl.FRAGMENT_SHADER);
var vertexShader2D = getShader(gl,
"attribute highp vec3 aVertexPosition; \
\
void main(void) { \
gl_Position = vec4(aVertexPosition,1.0);\
}", gl.VERTEX_SHADER);
var fragmentShader2D = getShader(gl,
" \
void main(void) {\
gl_FragColor = vec4(1,0,0,1);\
}", gl.FRAGMENT_SHADER);
shaderProgram = gl.createProgram();
// Attach the shader sources to the shader program
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
// Link the program
gl.linkProgram(shaderProgram);
// Check the linking status
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
console.log("Could not initialise shaders");
console.log(gl.getProgramInfoLog(shaderProgram));
}
shaderProgram2D = gl.createProgram();
// Attach the shader sources to the shader program
gl.attachShader(shaderProgram2D, vertexShader2D);
gl.attachShader(shaderProgram2D, fragmentShader2D);
// Link the program
gl.linkProgram(shaderProgram2D);
// Check the linking status
if (!gl.getProgramParameter(shaderProgram2D, gl.LINK_STATUS)) {
console.log("Could not initialise 2D shaders");
console.log(gl.getProgramInfoLog(shaderProgram2D));
}
vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
vMatrixUniform = gl.getUniformLocation(shaderProgram, "uVMatrix");
mMatrixUniform = gl.getUniformLocation(shaderProgram, "uMMatrix");
nUniform = gl.getUniformLocation(shaderProgram, "uNormalMatrix");
ambientColor = gl.getUniformLocation(shaderProgram, "ambientColor");
difusseColor = gl.getUniformLocation(shaderProgram, "difusseColor");
specularColor = gl.getUniformLocation(shaderProgram, "specularColor");
shininessValue = gl.getUniformLocation(shaderProgram, "shininessValue");
transparentObj = gl.getUniformLocation(shaderProgram, "transparentObj");
vertexPositionAttribute2D = gl.getAttribLocation(shaderProgram2D, "aVertexPosition");
}
Przygotowanie buferów
function initBuffers(vertices, normals, uvs)
{
Vertices = new Float32Array(vertices.length);
for(var i =0; i<vertices.length; i++)
{
Vertices[i] = vertices[i];
}
Normals = new Float32Array(normals.length);
for(var i =0; i<normals.length; i++)
{
Normals[i] = normals[i];
}
gl.useProgram(shaderProgram);
cubeVertexPositionBuffer = gl.createBuffer();
cubeVertexPositionBuffer.name = "cubeVertexPositionBuffer";
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
gl.bufferData(
gl.ARRAY_BUFFER,
Vertices,
gl.STATIC_DRAW);
gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
cubeVerticesNormalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesNormalBuffer);
gl.bufferData(
gl.ARRAY_BUFFER,
Normals,
gl.STATIC_DRAW);
gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
//gl.useProgram(shaderProgram2D);
cubeVertexPositionBuffer2D = gl.createBuffer();
cubeVertexPositionBuffer2D.name = "cubeVertexPositionBuffer2D";
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer2D);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([-1.0, -1.0, 0.0,
1.0, -1.0, 0.0,
0.0, 1.0, 0.0
]),
gl.STATIC_DRAW);
gl.vertexAttribPointer(vertexPositionAttribute2D, 3, gl.FLOAT, false, 0, 0);
}
Rysowanie
function paintGL(canvas) {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
var pixelRatio = canvas.devicePixelRatio;
var currentWidth = canvas.width * pixelRatio;
var currentHeight = canvas.height * pixelRatio;
if (currentWidth !== width || currentHeight !== height ) {
width = currentWidth;
height = currentHeight;
gl.viewport(0, 0, width, height);
mat4.perspective(pMatrix, degToRad(45), width / height, 0.1, 500.0);
gl.uniformMatrix4fv(pMatrixUniform, false, pMatrix);
}
gl.useProgram(shaderProgram2D);
gl.enableVertexAttribArray(vertexPositionAttribute2D);
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer2D);
gl.vertexAttribPointer(vertexPositionAttribute2D, 3, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 3);
gl.clear(gl.DEPTH_BUFFER_BIT);
///////////////////////////////////////////////////////////
gl.useProgram(shaderProgram);
gl.enableVertexAttribArray(vertexPositionAttribute);
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vertexNormalAttribute);
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesNormalBuffer);
gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
mat4.identity(vMatrix);
mat4.translate(vMatrix, vMatrix, [0.0,
0.2,
-5.0]);
gl.uniformMatrix4fv(vMatrixUniform, false, vMatrix);
mat4.identity(mMatrix);
mat4.rotate(mMatrix, mMatrix, degToRad(canvas.xRotAnim), [0, 1, 0]);
gl.uniformMatrix4fv(mMatrixUniform, false, mMatrix);
mat4.invert(nMatrix, mMatrix);//vMatrix
mat4.transpose(nMatrix, nMatrix);
gl.uniformMatrix4fv(nUniform, false, nMatrix);
for(var i = 0; i<MeshesStartIdx.length; i++)
{
gl.uniform1i(transparentObj, false);
if(i == 14)
gl.uniform1i(transparentObj, true);
gl.uniform3fv(ambientColor, Materials[i].ambient);
gl.uniform3fv(difusseColor, Materials[i].difusse);
gl.uniform3fv(specularColor, Materials[i].specular);
gl.uniform1f(shininessValue, Materials[i].shininess);
gl.drawArrays(gl.TRIANGLES, MeshesStartIdx[i], MeshesSize[i]);
}
}
Gdy zakomentuję //gl.useProgram(shaderProgram); w funkcji przygotowującej bufory, wtedy rysuje się tylko trójkąt 2D. Czy coś skopałem z kolejnością uruchaminia funkcji OGL? Zdaję sobie sprawę, że to forum głównie o C/C++ ale tutaj funkcje OpenGL są niemal identyczne więc nie powinno być to problemem aby wychwycić złą kolejność.
Pozdrawiam