Чтобы использовать текстуры в WebGL, их нужно для начала создать, а затем инициализировать. Делается это примерно так:
gl - объект типа WebGL Context
// Инициализация текстуры
function initTex(texture)
{
gl.bindTexture(gl.TEXTURE_2D,texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,texture.image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);
gl.bindTexture(gl.TEXTURE_2D, null);
}
// Создание текстуры
// Возвращает объект типа текстура
function createTex(image_name)
{
var image = new Image();
var texture = gl.createTexture();
image.src = image_name;
texture.image = image;
image.onload = function()
{
initTex(texture);
}
return texture;
}
// И собственно, как это потом выглядит в коде
texture[0] = createTex("pic/back_01.jpg");
Замечание!!!!
Вызов метода gl.createTexture(); обязательно должен производиться вне тела функции initTex();. Из-за такого в буферах начинали путаться текстуры, и общая картина смотрелась довольно забавно. Но одно дело забавно, а другое дело, что текстуры не на своих местах.
gl - объект типа WebGL Context
// Инициализация текстуры
function initTex(texture)
{
gl.bindTexture(gl.TEXTURE_2D,texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,texture.image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);
gl.bindTexture(gl.TEXTURE_2D, null);
}
// Создание текстуры
// Возвращает объект типа текстура
function createTex(image_name)
{
var image = new Image();
var texture = gl.createTexture();
image.src = image_name;
texture.image = image;
image.onload = function()
{
initTex(texture);
}
return texture;
}
// И собственно, как это потом выглядит в коде
texture[0] = createTex("pic/back_01.jpg");
Замечание!!!!
Вызов метода gl.createTexture(); обязательно должен производиться вне тела функции initTex();. Из-за такого в буферах начинали путаться текстуры, и общая картина смотрелась довольно забавно. Но одно дело забавно, а другое дело, что текстуры не на своих местах.
Google Chrome
С ним было много заморочек. Например:
При стандартных настройках безопасности у хрома нет возможности загрузки некоторых локальных ресурсов. По-этому, чтобы проверить работоспособность вашей программы на Хроме, разрабатывайте ее на сервере. В серьезных проектах это естественно будет так. Но вдруг вы просто решили потестить маленький примерчик, создали локальный html файл, и вдруг видите черный квадрат вместо текстуры. Это именно оно и есть.
Надеюсь, это кому-нибудь пригодится)))
Этот комментарий был удален автором.
ОтветитьУдалитьто есть всё же не удалось решить проблему без использования сервера ? у меня возникла проблема с Chrome и не знаю как её решить без установки всяких серверов, чтобы поюзать самый примитивный скрипт
Удалитьobj.initCanvas("example");
obj.initGl();
obj.initShaders("shader-fs","shader-vs");
//alert("1");
var a_TexCoord =obj.gl.getAttribLocation(obj.shaderProgram, 'a_TexCoord');
var a_Position=obj.gl.getAttribLocation(obj.shaderProgram,'a_Position');
var u_Sampler = obj.gl.getUniformLocation(obj.shaderProgram, 'u_Sampler');
obj.gl.clearColor(0.0,0.0,0.0,1.0);
obj.gl.clear(obj.gl.COLOR_BUFFER_BIT);
var n = initVertexBuffers(obj.gl);
if (n < 0) {
console.log('Failed to set the positions of the vertices');
}
//alert(initTextures(obj.gl, n));
if (!initTextures(obj.gl, n)) {
}
function initVertexBuffers(gl) {
Удалитьvar vertices = new Float32Array([
-0.5, 0.5, 0.0, 1.0,
-0.5, -0.5, 0.0, 0.0,
0.5, 0.5, 1.0, 1.0,
0.5, -0.5, 1.0, 0.0,
]);
var n = 4; // Число вершин
// Создать буферный объект
var vertexTexCoordBuffer = gl.createBuffer();
if (!vertexTexCoordBuffer) {
console.log('Failed to create the buffer object ');
return -1;
}
gl.bindBuffer(gl.ARRAY_BUFFER, vertexTexCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
var FSIZE=vertices.BYTES_PER_ELEMENT;
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE*4, 0);
gl.enableVertexAttribArray(a_Position);
gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, FSIZE*4, FSIZE*2);
gl.enableVertexAttribArray(a_TexCoord);
return n;
}
function initTextures(gl, n){
var texture = gl.createTexture(); // Создать объект текстуры
// Получить ссылку на u_Sampler
var image = new Image(); // Создать объект изображения
// Зарегистрировать обработчик, вызываемый послезагрузки изображения
image.onload = function(){
loadTexture(gl,n,texture,u_Sampler,image);
};
// Заставить браузер загрузить изображение
//image.crossOrigin = '*';
//image.crossOrigin = 'Anonymous';
image.src = 'C:/jo/sky.jpg';
return true;
}
function loadTexture(gl, n, texture, u_Sampler, image){
//alert(image);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); // Повернуть ось Y изображения
// Выбрать текстурный слот 0
gl.activeTexture(gl.TEXTURE0);
// Указать тип объекта текстуры
gl.bindTexture(gl.TEXTURE_2D, texture);
// Определить параметры текстуры
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
// Определить изображение текстуры
//alert(image);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,image);
// Определить указатель на текстурный слот 0
gl.uniform1i(u_Sampler, 0);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, n); // Нарисовать прямоугольник
}
собственно проблема возникает только вот здесь:
Удалитьgl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,image);
----
Image from origin 'file://' has been blocked from loading by Cross-Origin Resource Sharing policy: Invalid response. Origin 'null' is therefore not allowed access.
---
или ещё такая ошибка:
e11.html:125 Uncaught SecurityError: Failed to execute 'texImage2D' on 'WebGLRenderingContext': The cross-origin image at file:///C:/jo/sky.jpg may not be loaded.