support for float textures
This commit is contained in:
Родитель
5c5b784417
Коммит
096822bc57
|
@ -118,6 +118,8 @@ var LibraryGL = {
|
|||
GL.anisotropicExt = Module.ctx.getExtension('EXT_texture_filter_anisotropic') ||
|
||||
Module.ctx.getExtension('MOZ_EXT_texture_filter_anisotropic') ||
|
||||
Module.ctx.getExtension('WEBKIT_EXT_texture_filter_anisotropic');
|
||||
|
||||
GL.floatExt = Module.ctx.getExtension('OES_texture_float');
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -339,12 +341,28 @@ var LibraryGL = {
|
|||
case 0x8034 /* GL_UNSIGNED_SHORT_5_5_5_1 */:
|
||||
sizePerPixel = 2;
|
||||
break;
|
||||
case 0x1406 /* GL_FLOAT */:
|
||||
assert(GL.floatExt, 'Must have OES_texture_float to use float textures');
|
||||
switch (format) {
|
||||
case 0x1907 /* GL_RGB */:
|
||||
sizePerPixel = 3*4;
|
||||
break;
|
||||
case 0x1908 /* GL_RGBA */:
|
||||
sizePerPixel = 4*4;
|
||||
break;
|
||||
default:
|
||||
throw 'Invalid format (' + format + ') passed to glTexImage2D';
|
||||
}
|
||||
internalformat = Module.ctx.RGBA; // XXX
|
||||
break;
|
||||
default:
|
||||
throw 'Invalid type (' + type + ') passed to glTexImage2D';
|
||||
}
|
||||
var bytes = GL.computeImageSize(width, height, sizePerPixel, GL.unpackAlignment);
|
||||
if (type == 0x1401 /* GL_UNSIGNED_BYTE */) {
|
||||
pixels = {{{ makeHEAPView('U8', 'pixels', 'pixels+bytes') }}};
|
||||
} else if (type == 0x1406 /* GL_FLOAT */) {
|
||||
pixels = {{{ makeHEAPView('F32', 'pixels', 'pixels+bytes') }}};
|
||||
} else {
|
||||
pixels = {{{ makeHEAPView('U16', 'pixels', 'pixels+bytes') }}};
|
||||
}
|
||||
|
@ -382,12 +400,27 @@ var LibraryGL = {
|
|||
case 0x8034 /* GL_UNSIGNED_SHORT_5_5_5_1 */:
|
||||
sizePerPixel = 2;
|
||||
break;
|
||||
case 0x1406 /* GL_FLOAT */:
|
||||
assert(GL.floatExt, 'Must have OES_texture_float to use float textures');
|
||||
switch (format) {
|
||||
case 0x1907 /* GL_RGB */:
|
||||
sizePerPixel = 3*4;
|
||||
break;
|
||||
case 0x1908 /* GL_RGBA */:
|
||||
sizePerPixel = 4*4;
|
||||
break;
|
||||
default:
|
||||
throw 'Invalid format (' + format + ') passed to glTexSubImage2D';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw 'Invalid type (' + type + ') passed to glTexSubImage2D';
|
||||
}
|
||||
var bytes = GL.computeImageSize(width, height, sizePerPixel, GL.unpackAlignment);
|
||||
if (type == 0x1401 /* GL_UNSIGNED_BYTE */) {
|
||||
pixels = {{{ makeHEAPView('U8', 'pixels', 'pixels+bytes') }}};
|
||||
} else if (type == 0x1406 /* GL_FLOAT */) {
|
||||
pixels = {{{ makeHEAPView('F32', 'pixels', 'pixels+bytes') }}};
|
||||
} else {
|
||||
pixels = {{{ makeHEAPView('U16', 'pixels', 'pixels+bytes') }}};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
#define GL_GLEXT_PROTOTYPES
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
extern "C" {
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glut.h>
|
||||
}
|
||||
static const char vertex_shader[] =
|
||||
"#ifdef GL_ES\n"
|
||||
"precision highp float;\n"
|
||||
"#endif\n"
|
||||
"attribute float indices;\n"
|
||||
"uniform sampler2D nodeInfo;\n"
|
||||
"varying vec4 color;"
|
||||
"\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" float s = (indices + 0.5) / 512.; \n"
|
||||
" vec4 v = texture2D(nodeInfo, vec2( s, 0.5));\n"
|
||||
" gl_Position = vec4(v.x, v.y, 0.5, 1.);\n"
|
||||
" gl_PointSize = v.z;\n"
|
||||
" color = vec4(0.5 + v.w/2., 0.5 + 0.5 * v.w/2., 0.5, 1);\n"
|
||||
"}\n";
|
||||
static const char fragment_shader[] =
|
||||
"#ifdef GL_ES\n"
|
||||
"precision highp float;\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"varying vec4 color;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" float dst = distance(vec2(0.5, 0.5), gl_PointCoord); \n"
|
||||
" gl_FragColor = color;\n"
|
||||
" if ( dst > 0.3) {"
|
||||
" gl_FragColor = vec4(0., 0., 0.5, 0.2);\n"
|
||||
"}\n"
|
||||
"if ( dst > 0.5) discard;\n"
|
||||
"}";
|
||||
struct NodeInfo { //structure that we want to transmit to our shaders
|
||||
float x;
|
||||
float y;
|
||||
float s;
|
||||
float c;
|
||||
};
|
||||
GLuint nodeTexture; //texture id used to bind
|
||||
GLuint nodeSamplerLocation; //shader sampler address
|
||||
GLuint indicesAttributeLocation; //shader attribute address
|
||||
GLuint indicesVBO; //Vertex Buffer Object Id;
|
||||
const int nbNodes = 512;
|
||||
NodeInfo * data = new NodeInfo[nbNodes]; //our data that will be transmitted using float texture.
|
||||
double alpha = 0; //use to make a simple funny effect;
|
||||
static void updateFloatTexture() {
|
||||
int count = 0;
|
||||
for (float x=0; x < nbNodes; ++x ) {
|
||||
data[count].x = 0.2*pow(cos(alpha), 3) + (sin(alpha)*3. + 3.5) * x/nbNodes * cos(alpha + x/nbNodes * 16. * M_PI);
|
||||
data[count].y = 0.2*pow(sin(alpha), 3) + (sin(alpha)*3. + 3.5) * x/nbNodes * sin(alpha + x/nbNodes * 16. * M_PI);
|
||||
data[count].s = (16. + 16. * cos(alpha + x/nbNodes * 32. * M_PI)) + 8.;// * fmod(x/nbNodes + alpha, 1.) + 5.;
|
||||
data[count].c = 0.5 + 0.5 * sin(alpha + x/nbNodes * 32. * M_PI);
|
||||
++count;
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, nodeTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, nbNodes, 1, 0, GL_RGBA, GL_FLOAT, data);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glBindTexture(GL_TEXTURE_2D, NULL);
|
||||
alpha -= 0.001;
|
||||
}
|
||||
static void glut_draw_callback(void) {
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glClearColor(1., 1., 1., 0.);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
updateFloatTexture(); //we change the texture each time to create the effect (it is just for the test)
|
||||
glBindTexture(GL_TEXTURE_2D, nodeTexture);
|
||||
glUniform1i(nodeSamplerLocation, GL_TEXTURE0);
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, indicesVBO);
|
||||
glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
|
||||
glDrawArrays(GL_POINTS, 0, nbNodes);
|
||||
glutSwapBuffers();
|
||||
}
|
||||
GLuint createShader(const char source[], int type) {
|
||||
char msg[512];
|
||||
GLuint shader = glCreateShader(type);
|
||||
glShaderSource(shader, 1, (const GLchar**)(&source), NULL);
|
||||
glCompileShader(shader);
|
||||
glGetShaderInfoLog(shader, sizeof msg, NULL, msg);
|
||||
std::cout << "Shader info: " << msg << std::endl;
|
||||
return shader;
|
||||
}
|
||||
static void gl_init(void) {
|
||||
GLuint program = glCreateProgram();
|
||||
glAttachShader(program, createShader(vertex_shader , GL_VERTEX_SHADER));
|
||||
glAttachShader(program, createShader(fragment_shader, GL_FRAGMENT_SHADER));
|
||||
glLinkProgram(program);
|
||||
char msg[512];
|
||||
glGetProgramInfoLog(program, sizeof msg, NULL, msg);
|
||||
std::cout << "info: " << msg << std::endl;
|
||||
glUseProgram(program);
|
||||
std::vector<float> elements(nbNodes);
|
||||
int count = 0;
|
||||
for (float x=0; x < nbNodes; ++x ) {
|
||||
elements[count] = count;
|
||||
++count;
|
||||
}
|
||||
/*Create one texture to store all the needed information */
|
||||
glGenTextures(1, &nodeTexture);
|
||||
/* Store the vertices in a vertex buffer object (VBO) */
|
||||
glGenBuffers(1, &indicesVBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, indicesVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, elements.size() * sizeof(uint), &elements[0], GL_STATIC_DRAW);
|
||||
/* Get the locations of the uniforms so we can access them */
|
||||
nodeSamplerLocation = glGetUniformLocation(program, "nodeInfo");
|
||||
glBindAttribLocation(program, 0, "indices");
|
||||
//Enable glPoint size in shader, always enable in Open Gl ES 2.
|
||||
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
glEnable(GL_POINT_SPRITE);
|
||||
}
|
||||
int main(int argc, char *argv[]) {
|
||||
glutInit(&argc, argv);
|
||||
glutInitWindowSize(640, 480);
|
||||
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
|
||||
glutCreateWindow("Simple FLOAT Texture Test");
|
||||
/* Set up glut callback functions */
|
||||
glutDisplayFunc(glut_draw_callback );
|
||||
gl_init();
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 20 KiB |
|
@ -7941,6 +7941,9 @@ elif 'browser' in str(sys.argv):
|
|||
def test_tex_nonbyte(self):
|
||||
self.btest('tex_nonbyte.c', reference='tex_nonbyte.png')
|
||||
|
||||
def test_float_tex(self):
|
||||
self.btest('float_tex.cpp', reference='float_tex.png')
|
||||
|
||||
def test_pre_run_deps(self):
|
||||
# Adding a dependency in preRun will delay run
|
||||
open(os.path.join(self.get_dir(), 'pre.js'), 'w').write('''
|
||||
|
|
Загрузка…
Ссылка в новой задаче