#include <GL/glew.h> #include <GL/freeglut.h> #include <iostream> #include <sstream> const unsigned int meshSize = 16; GLuint posVertexBuffer; GLuint indexVertexBuffer; int mouseOldX, mouseOldY; int mouseButtons = 0; float rotateX = 20.0f, rotateY = 0.0f; float translateX = 0.0f, translateY = 0.0f, translateZ = -2.0f; void Init(); void Display(); void Resize(int w, int h); void mouse(int button, int state, int x, int y); void motion(int x, int y); void CreateVBO(GLuint * vbo, int size) { glGenBuffers(1, vbo); glBindBuffer(GL_ARRAY_BUFFER, *vbo); glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } void CreateMeshIndexBuffer(GLuint * id, int w, int h) { int size = ((w * 2) + 2) * (h-1) * sizeof(GLuint); glGenBuffers(1, id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *id); glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, 0, GL_STATIC_DRAW); GLuint * indices = (GLuint *)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); if (!indices) { return; } //std::stringstream ss; for (int y = 0; y < h-1; ++y) { for (int x = 0; x < w; ++x) { *indices++ = y * w + x; //ss << y * w + x << ","; *indices++ = (y+1)*w + x; //ss << (y+1)*w + x << ","; } *indices++ = (y+1)*w+(w-1); //ss << (y+1)*w + (w-1) << ","; *indices++ = (y+1)*w; //ss << (y+1)*w << ","; } //std::cout << ss.str() << std::endl; glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } void CreateMeshPositionVBO(GLuint * id, int w, int h) { CreateVBO(id, w * h * 4 * sizeof(float)); glBindBuffer(GL_ARRAY_BUFFER, *id); float * pos = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); if (!pos) { return; } for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { float u = x / (float)(w-1); float v = y / (float)(h-1); *pos++ = u*2.0f-1.0f; *pos++ = 0.0f; *pos++ = v*2.0f-1.0f; *pos++ = 1.0f; } } glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); } int main(int argc, char ** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize(1024, 800); glutCreateWindow("CUDA VBO"); GLenum res = glewInit(); if (res != GLEW_OK) { std::cout << glewGetErrorString(res) << std::endl; } Init(); glutDisplayFunc(Display); glutReshapeFunc(Resize); glutMouseFunc(mouse); glutMotionFunc(motion); glutMainLoop(); return EXIT_SUCCESS; } void Init() { glClearColor(0.0, 0.0, 0.0, 1.0); CreateMeshPositionVBO(&posVertexBuffer, meshSize, meshSize); CreateMeshIndexBuffer(&indexVertexBuffer, meshSize, meshSize); } void Display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(translateX, translateY, translateZ); glRotatef(rotateX, 1.0, 0.0, 0.0); glRotatef(rotateY, 0.0, 1.0, 0.0); glBindBuffer(GL_ARRAY_BUFFER, posVertexBuffer); glVertexPointer(4, GL_FLOAT, 0, 0); glEnableClientState(GL_VERTEX_ARRAY); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVertexBuffer); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDrawElements(GL_TRIANGLE_STRIP, ((meshSize * 2) + 2) * (meshSize - 1), GL_UNSIGNED_INT, 0); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDisableClientState(GL_VERTEX_ARRAY); glutSwapBuffers(); } void mouse(int button, int state, int x, int y) { if (state == GLUT_DOWN) { mouseButtons |= 1 << button; } else if (state == GLUT_UP) { mouseButtons = 0; } mouseOldX = x; mouseOldY = y; glutPostRedisplay(); } void motion(int x, int y) { float dx, dy; dx = (float)(x - mouseOldX); dy = (float)(y - mouseOldY); if (mouseButtons == 1) { rotateX += dy * 0.2f; rotateY += dx * 0.2f; } else if (mouseButtons == 2) { translateX += dx * 0.01f; translateY -= dy * 0.01f; } else if (mouseButtons == 4) { translateZ += dy * 0.01f; } mouseOldX = x; mouseOldY = y; glutPostRedisplay(); } void Resize(int w, int h) { if (0 == h) h = 1; glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, w/h, 0.1, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); }