2012-07-02 15 views
5

मैं एक घन पर 6 अलग-अलग बनावट का उपयोग करना चाहता था, प्रति तरफ, लेकिन गलती नहीं मिल पाती। यहां मेरा वर्तमान कोड है:वेबजीएल में एकाधिक बनावट का उपयोग कैसे करें?

var texturen = new Array(); 
function initTexture(sFilename,texturen) 
{ 
    var anz = texturen.length; 
    texturen[anz] = gl.createTexture(); 
    texturen[anz].image = new Image(); 
    texturen[anz].image.onload = function()  
    { 
    gl.bindTexture(gl.TEXTURE_2D, texturen[anz]); 
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); 
    gl.texImage2D 
    (gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texturen[anz].image); 
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 
    gl.bindTexture(gl.TEXTURE_2D, null); 
    } 
    texturen[anz].image.src = sFilename; 
} 


var mvMatrix = mat4.create(); 
var mvMatrixStack = []; 
var pMatrix = mat4.create(); 

function mvPushMatrix() { 
    var copy = mat4.create(); 
    mat4.set(mvMatrix, copy); 
    mvMatrixStack.push(copy); 
} 

function mvPopMatrix() { 
    if (mvMatrixStack.length == 0) { 
     throw "Invalid popMatrix!"; 
    } 
    mvMatrix = mvMatrixStack.pop(); 
} 


function setMatrixUniforms() { 
    gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix); 
    gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix); 
} 


function degToRad(degrees) { 
    return degrees * Math.PI/180; 
} 

var cubeVertexPositionBuffer; 
var cubeVertexTextureCoordBuffer; 
var cubeVertexIndexBuffer; 
var cubeVertexPositionBuffer1; 
var cubeVertexTextureCoordBuffer1; 
var cubeVertexIndexBuffer1; 


function initBuffers() { 
    cubeVertexPositionBuffer = gl.createBuffer(); 
    gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); 
    vertices = [ 
     // Front face 
     -1.0, -1.0, 1.0, 
     1.0, -1.0, 1.0, 
     1.0, 1.0, 1.0, 
     -1.0, 1.0, 1.0, 

     // Back face 
     -1.0, -1.0, -1.0, 
     -1.0, 1.0, -1.0, 
     1.0, 1.0, -1.0, 
     1.0, -1.0, -1.0, 

     // Top face 
     -1.0, 1.0, -1.0, 
     -1.0, 1.0, 1.0, 
     1.0, 1.0, 1.0, 
     1.0, 1.0, -1.0, 
    ]; 
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); 
    cubeVertexPositionBuffer.itemSize = 3; 
    cubeVertexPositionBuffer.numItems = 12; 

cubeVertexPositionBuffer1 = gl.createBuffer(); 
    gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer1); 
    vertices = [ 
     // Bottom face 
     -1.0, -1.0, -1.0, 
     1.0, -1.0, -1.0, 
     1.0, -1.0, 1.0, 
     -1.0, -1.0, 1.0, 

     // Right face 
     1.0, -1.0, -1.0, 
     1.0, 1.0, -1.0, 
     1.0, 1.0, 1.0, 
     1.0, -1.0, 1.0, 

     // Left face 
     -1.0, -1.0, -1.0, 
     -1.0, -1.0, 1.0, 
     -1.0, 1.0, 1.0, 
     -1.0, 1.0, -1.0, 
    ]; 
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); 
    cubeVertexPositionBuffer1.itemSize = 3; 
    cubeVertexPositionBuffer1.numItems = 12; 


    cubeVertexTextureCoordBuffer = gl.createBuffer(); 
    gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); 
    var textureCoords = [ 
     // Front face 
     0.0, 0.0, 
     1.0, 0.0, 
     1.0, 1.0, 
     0.0, 1.0, 

     // Back face 
     1.0, 0.0, 
     1.0, 1.0, 
     0.0, 1.0, 
     0.0, 0.0, 

     // Top face 
     0.0, 1.0, 
     0.0, 0.0, 
     1.0, 0.0, 
     1.0, 1.0, 
    ]; 
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW); 
    cubeVertexTextureCoordBuffer.itemSize = 2; 
    cubeVertexTextureCoordBuffer.numItems = 12; 



cubeVertexTextureCoordBuffer1 = gl.createBuffer(); 
    gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer1); 
    var textureCoords = [ 
    // Bottom face 
     1.0, 1.0, 
     0.0, 1.0, 
     0.0, 0.0, 
     1.0, 0.0, 

     // Right face 
     1.0, 0.0, 
     1.0, 1.0, 
     0.0, 1.0, 
     0.0, 0.0, 

     // Left face 
     0.0, 0.0, 
     1.0, 0.0, 
     1.0, 1.0, 
     0.0, 1.0, 
    ]; 
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW); 
    cubeVertexTextureCoordBuffer1.itemSize = 2; 
    cubeVertexTextureCoordBuffer1.numItems = 12; 

cubeVertexIndexBuffer = gl.createBuffer(); 
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); 
    var cubeVertexIndices = [ 
     0, 1, 2,  0, 2, 3, // Front face 
     4, 5, 6,  4, 6, 7, // Back face 
     8, 9, 10,  8, 10, 11, // Top face 
    ]; 
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); 
    cubeVertexIndexBuffer.itemSize = 1; 
    cubeVertexIndexBuffer.numItems = 18; 

cubeVertexIndexBuffer1 = gl.createBuffer(); 
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer1); 
    var cubeVertexIndices = [ 
     12, 13, 14, 12, 14, 15, // Bottom face 
     16, 17, 18, 16, 18, 19, // Right face 
     20, 21, 22, 20, 22, 23 // Left face 
    ]; 
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); 
    cubeVertexIndexBuffer1.itemSize = 1; 
    cubeVertexIndexBuffer1.numItems = 18; 



} 


var xRot = 0; 
var yRot = 0; 
var zRot = 0; 

function drawScene() { 
    gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); 
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 

    mat4.perspective(45, gl.viewportWidth/gl.viewportHeight, 0.1, 100.0, pMatrix); 

    mat4.identity(mvMatrix); 

    mat4.translate(mvMatrix, [0.0, 0.0, -5.0]); 

    mat4.rotate(mvMatrix, degToRad(xRot), [1, 0, 0]); 
    mat4.rotate(mvMatrix, degToRad(yRot), [0, 1, 0]); 
    mat4.rotate(mvMatrix, degToRad(zRot), [0, 0, 0]); 
    setMatrixUniforms(); 

gl.activeTexture(gl.TEXTURE0); 
gl.bindTexture(gl.TEXTURE_2D, texturen[0]); 
gl.vertexAttribPointer 
(textureCoordAttribute, cubeVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0); 
    gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); 
    gl.vertexAttribPointer 
    (shaderProgram.vertexPositionAttribute,cubeVertexPositionBuffer.itemSize, 
    gl.FLOAT, false, 0, 0); 

    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); 

    gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0); 


gl.activeTexture(gl.TEXTURE1); 
gl.bindTexture(gl.TEXTURE_2D, texturen[1]); 
gl.vertexAttribPointer 
(textureCoordAttribute, cubeVertexTextureCoordBuffer1.itemSize, gl.FLOAT, false, 0, 0); 
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer1); 
gl.vertexAttribPointer 
(shaderProgram.vertexPositionAttribute,cubeVertexPositionBuffer1.itemSize, 
    gl.FLOAT, false, 0, 0); 


    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer1); 

    gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer1.numItems, gl.UNSIGNED_SHORT, 0); 


} 

मैंने इसे दो भागों में विभाजित किया, 2 अलग-अलग चित्रों के साथ परीक्षण करने की कोशिश की। और वास्तव में cubeVertexIndexBuffers क्या हैं?

उत्तर

14

सबसे पहले, संक्षिप्त उत्तर: निम्नलिखित कोड के साथ अपने कोड की अंतिम 10 पंक्तियों को बदलें और मुझे लगता है कि इसे काम करना चाहिए।

gl.activeTexture(gl.TEXTURE0); 
gl.bindTexture(gl.TEXTURE_2D, texturen[1]); 
gl.vertexAttribPointer(textureCoordAttribute, cubeVertexTextureCoordBuffer1.itemSize, gl.FLOAT, false, 0, 0); 
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer1); 
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,cubeVertexPositionBuffer1.itemSize, gl.FLOAT, false, 0, 0); 

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); 
gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0); 

महत्वपूर्ण परिवर्तन कर रहे हैं:

  • activeTexture अभी भी TEXTURE0 है
  • (आप केवल एक समय यहां कम एक संरचना का उपयोग कर रहे) cubeVertexIndexBuffer1 के बजाय cubeVertexIndexBuffer का उपयोग करना है, जो बाहर के- निहित रेंज इंडस्ट्रीज

सूचकांक वास्तव में उपयोग किए जाने के बारे में बेहतर स्पष्टीकरण के लिए मैं आपको 0 पर संदर्भित करूंगाक्योंकि मैं यहां सब कुछ दोहराना नहीं चाहता हूं।

अब, अधिक सामान्य उत्तर पर।

विभिन्न चेहरों पर विभिन्न बनावटों का उपयोग करने के मुद्दे को संभालने के दो बुनियादी तरीके हैं। पहली और सरल विधि यह है कि आप वही कर रहे हैं जो आप यहां कर रहे हैं: ऑब्जेक्ट को टुकड़ों में प्रस्तुत करें, प्रत्येक टुकड़े के लिए एक अलग बनावट को बाध्य करें। यद्यपि प्रभाव को पूरा करने के लिए कड़ाई से सबसे प्रभावी तरीका नहीं है, फिर भी यह उच्च प्रदर्शन अनुप्रयोगों जैसे इसे गेम के रूप में संभालने का सबसे आम तरीका है क्योंकि यह बहुत लचीलापन प्रदान करता है, खासकर जब आपकी सामग्री एक साधारण फैलाव बनावट से अधिक जटिल होती है ।

एक आसान तरीका है कि आप इस तरह के मामले के लिए अपने जैसे कोड के प्रदर्शन में सुधार कर सकते हैं। शिखर/सूचकांक को अलग-अलग बफर प्रति-बनावट में विभाजित नहीं किया जाना चाहिए। इसके बजाय आप इतना की तरह अलग अलग ऑफसेट के साथ एक एकल बफर में उन सब को मिलाकर उन्हें प्रस्तुत करना सकता है:

// On Init 
var vertBuffer = gl.createBuffer(); 
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer); 
var vertices = [ 
    // Vertex values for all 6 faces 
]; 
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); 

var indexBuffer = gl.createBuffer(); 
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); 
var indices = [ 
    // Index values for all 6 faces 
]; 
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); 

// On Draw 
// Setup the shader and uniforms and all that jazz 

gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer); 
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); 
gl.vertexAttribPointer(// Blah blah blah...); 

// Draw face 0 
gl.bindTexture(gl.TEXTURE_2D, texture[0]); 
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); 

// Draw face 1 
gl.bindTexture(gl.TEXTURE_2D, texture[1]); 
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 12); 

// Draw face 2 
gl.bindTexture(gl.TEXTURE_2D, texture[2]); 
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 24); 

// .. And so on to face 5 
// Draw face 2 
gl.bindTexture(gl.TEXTURE_2D, texture[5]); 
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 60); 

यहाँ क्या हो रहा है कि drawElements की प्रत्येक कॉल केवल 2 त्रिकोण (6 कोने, कॉल का दूसरा पैरामीटर खींचता है), लेकिन प्रत्येक कॉल इंडेक्स बफर में ऑफसेट हो जाती है ताकि यह एक अलग चेहरे पर शुरू हो। (कॉल का चौथा पैरामीटर, जो बाइट ऑफसेट इंगित करता है। प्रत्येक इंडेक्स एक यूंट 16 है, इसलिए प्रति इंडेक्स 2 बाइट्स। 12 == "इंडेक्स पर शुरू करें [6]") इस तरह सभी बाध्यकारी और सेटअप केवल एक बार होता है, और प्रत्येक ड्रॉ कॉल को केवल उस स्थिति को बदलना होता है जो वास्तव में आवश्यक है (बनावट)।

इसे संभालने का दूसरा तरीका, जो तेज़ लेकिन सामान्यीकृत करना कठिन है, शेडर वर्दी में बनावट की एक सरणी बांधना और शेडर के भीतर सरणी में इंडेक्स में एक और वर्टेक्स विशेषता का उपयोग करना है। मैं इस दृष्टिकोण के लिए कोड का विस्तार नहीं कर रहा हूं लेकिन वेबगेल शेडर उपयोग के साथ सहज होने के बाद इसे स्थापित करना अपेक्षाकृत आसान होना चाहिए। यदि आपके पास इस विशिष्ट दृष्टिकोण के बारे में और प्रश्न हैं तो एक अलग SO प्रश्न में पूछना सर्वोत्तम होगा ताकि इसे अधिभारित न किया जा सके।

+0

मैंने आपके द्वारा लिखे गए सब कुछ में प्रवेश किया, लेकिन यह अभी भी काम नहीं करता है:/क्या मैं आपको कोड फिर से भेज सकता हूं? :) – Applecow

+0

[नया प्रश्न] (http://stackoverflow.com/questions/11306460/how-to-use-multiple-textures-on-a-cube-in-webgl) – Applecow

+0

@ टोजी मैं जानना चाहता हूं आपने "बनावट की सरणी" पर संकेत दिया - http: // stackoverflow पर देखें।एक नए प्रश्न के लिए कॉम/प्रश्न/1 9 5 9 2850/कैसे-टू-बाइंड-ए-एरे-ऑफ-टेक्सचर-टू-ए-वेबग्ल-शेडर-वर्दी, कृपया। धन्यवाद – virtualnobi

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^