aboutsummaryrefslogtreecommitdiff
path: root/tests/gl_subdata.cpp
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-11-23 13:57:35 +0100
committerAlon Zakai <alonzakai@gmail.com>2012-11-23 13:57:35 +0100
commit7142526a3f3318f648cedf1f6ea7b5150a6001a9 (patch)
tree33fb7903bc6e040e8636cb2491035572ca6b02d4 /tests/gl_subdata.cpp
parent0d663f0cc9a52c2fcd1a5c50271718d80846cf0d (diff)
fix glBufferSubData
Diffstat (limited to 'tests/gl_subdata.cpp')
-rw-r--r--tests/gl_subdata.cpp141
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;
+}
+
+