diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-11-23 13:57:35 +0100 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-11-23 13:57:35 +0100 |
commit | 7142526a3f3318f648cedf1f6ea7b5150a6001a9 (patch) | |
tree | 33fb7903bc6e040e8636cb2491035572ca6b02d4 /tests/gl_subdata.cpp | |
parent | 0d663f0cc9a52c2fcd1a5c50271718d80846cf0d (diff) |
fix glBufferSubData
Diffstat (limited to 'tests/gl_subdata.cpp')
-rw-r--r-- | tests/gl_subdata.cpp | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/tests/gl_subdata.cpp b/tests/gl_subdata.cpp new file mode 100644 index 00000000..d159b2b2 --- /dev/null +++ b/tests/gl_subdata.cpp @@ -0,0 +1,141 @@ +#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[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); + float zeroes[nbNodes]; + memset(zeroes, 0, sizeof(zeroes)); + glBufferData(GL_ARRAY_BUFFER, elements.size() * sizeof(float), zeroes, GL_STATIC_DRAW); + for (int x = 0; x < nbNodes; x++) { + glBufferSubData(GL_ARRAY_BUFFER, x * sizeof(float), elements.size() * sizeof(float), &elements[x]); + } + /* 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; +} + + |