#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();
}