Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <GL/glew.h>
- #include <GL/glfw.h>
- #include <iostream>
- #include <cmath>
- #include <cstdio>
- using namespace std;
- GLuint mainProgram;
- const float PIE = 3.1416;
- struct Vtx {
- GLfloat vx, vy, vz; //velocity
- GLfloat startTime; //start time
- GLuint color; //color
- };
- enum {ATTRIB_VEL, ATTRIB_STARTTIME, ATTRIB_COLOR}; //enumerate certain constants in this, get assigned to unique addresses
- //assumes everything is uint (starts at 0,1,2,3...); no more datatype
- //but if you assign it, papalitan accordingly (try put =15; at the end of ATTRIB_COLOR and hover over each one)
- const size_t nParticles = 600; //instead of declare as int, have size_t instead
- const float maxVelocity = 2, minVelocity =1;
- const float accelX = 0, accelY = 1, accelZ = 0; //fountain paakyat, sa taas gumagalaw
- const float timeSpeed = 0.01f; //delta time, how fast is time
- const float particleLifetime = 4.00f; //lifetime of particle awwwwwwww. disappears after 4 sec
- const float elev = PIE/2.5; //angle of elevation
- Vtx particles[nParticles]; //declare array of structs
- bool loadShaderSource(GLuint shader, const char *filePath)
- {
- FILE *f = fopen(filePath, "r");
- if ( !f ) {
- std::cerr << "ERROR: shader source not found: " << filePath << '\n';
- return false;
- }
- fseek(f, 0, SEEK_END);
- const size_t sz = ftell(f)+1;
- GLchar *buffer = new GLchar[sz];
- fseek(f, 0, SEEK_SET);
- fread(buffer, 1, sz, f);
- fclose(f);
- buffer[sz-1]=0;
- glShaderSource(shader, 1, (const GLchar **) &buffer, NULL);
- delete [] buffer;
- if ( glGetError() != GL_NO_ERROR ) {
- std::cerr << "ERROR: Unable to load shader\n";
- return false;
- }
- glCompileShader(shader);
- //check for loading errors
- GLint logLength;
- glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
- if (logLength > 0) {
- GLchar *log = (GLchar *)malloc(logLength);
- glGetShaderInfoLog(shader, logLength, &logLength, log);
- std::cout << "Shader compile log:\n" << log << endl;
- free(log);
- }
- //hahanapin source, compare, lalagay sa shader na variable tas icocompile
- return true;
- }
- float fRand()
- {
- return (float)rand()/RAND_MAX;
- }
- //create certain velocity that's random
- void setParticle(Vtx &particle)
- {//may pumapasok na struct sa set particle na yun tapos we can edit the particle
- float vel = fRand() * (maxVelocity - minVelocity) + minVelocity;
- float azimuth = fRand() * 2 * PIE; //assign specific angle of firing?
- particle.vx = vel * cos(azimuth)*cos(elev);
- particle.vy = vel * sin(elev);
- particle.vz = vel * sin(azimuth) * cos(elev);
- particle.color = 0xFF000000 | rand() << 16 | rand(); //opaque fountain since first 2 letters FF alpha
- //pipe rand on 16th bit, only last 6 digits affected
- }
- void setupShaders()
- {
- //declare shaders
- GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER),
- vtxShader = glCreateShader(GL_VERTEX_SHADER);
- //load shaders
- loadShaderSource(fragShader, "fountain.fsh");
- loadShaderSource(vtxShader, "fountain.vsh");
- //declare shaders first, then load shaders
- //inside loading, open file and create shader inof. after, check for loading errors. then compile, then check for link errors.
- mainProgram = glCreateProgram();
- //attach shader to main prog
- glAttachShader(mainProgram, fragShader);
- glAttachShader(mainProgram, vtxShader);
- //whatever att is in vertex shader, hahanapin sa loob ng program. magbbind
- //ok lang diff color as long as all bound
- //binds vtxShader attributes
- glBindAttribLocation(mainProgram, ATTRIB_VEL, "initialVelocity"); //see fountain.vsh for initialVelocity
- glBindAttribLocation(mainProgram, ATTRIB_STARTTIME, "startTime"); //see fountain.vsh
- glBindAttribLocation(mainProgram, ATTRIB_COLOR, "color"); //see fountain.vsh
- //link prog na
- glLinkProgram(mainProgram);
- //check for link errors - checks program, not shader. may error checking for shaders
- //and error checking for program
- GLint logLength;
- glGetProgramiv(mainProgram, GL_INFO_LOG_LENGTH, &logLength);
- if (logLength > 0) {
- GLchar *log = (GLchar *)malloc(logLength);
- glGetProgramInfoLog(mainProgram, logLength, &logLength, log);
- std::cout << "Program compile log:\n" << log << endl;
- free(log);
- }
- }
- void setupVertices()
- {
- glEnableVertexAttribArray(ATTRIB_VEL);
- glEnableVertexAttribArray(ATTRIB_STARTTIME);
- glEnableVertexAttribArray(ATTRIB_COLOR);
- glVertexAttribPointer(ATTRIB_VEL, 3, GL_FLOAT, GL_FALSE, sizeof(Vtx), &(particles[0].vx)); //3: kasi may vx vy vz
- //sizeofVtx: stride. parang hop. ano yung next hop para malaman ko im on the next/right(?) stride
- //attrib = attrib from vtxshader. instead of glvtxpointer (?) use this
- glVertexAttribPointer(ATTRIB_STARTTIME, 1, GL_FLOAT, GL_FALSE, sizeof(Vtx), &(particles[0].startTime)); //1 var lang //change pointer. after vx vy vz is start
- //time. point to starttime para start throw value there
- glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vtx), &(particles[0].vx)); //3: kasi may vx vy vz
- //ubyte: hex vars //size 4 kasi abgr
- for (size_t i = 0; i < nParticles; ++i) {
- particles[i].startTime = fRand() * particleLifetime; //randomizes lifetime
- setParticle(particles[i]);
- }
- }
- int main() {
- if ( !glfwInit() ) {
- std::cerr << "Unable to initialize OpenGL!\n";
- return -1;
- }
- if ( !glfwOpenWindow(640,640, //width and height of the screen
- 8,8,8,8, //Red, Green, Blue and Alpha bits
- 0,0, //Depth and Stencil bits
- GLFW_WINDOW)) {
- std::cerr << "Unable to create OpenGL window.\n";
- glfwTerminate();
- return -1;
- }
- if ( glewInit() != GLEW_OK ) {
- std::cerr << "Unable to hook OpenGL extensions!\n";
- return -1;
- }
- setupShaders();
- setupVertices();
- glEnable(GL_PROGRAM_POINT_SIZE);
- glEnable(GL_DEPTH_TEST);
- glUseProgram(mainProgram);
- //establish constants valid for 1 frame only
- GLuint UNIF_T = glGetUniformLocation(mainProgram, "t"),
- UNIF_ACCEL = glGetUniformLocation(mainProgram, "accel"),
- UNIF_LIFETIME = glGetUniformLocation(mainProgram, "lifetime");
- glfwSetWindowTitle("GLFW Simple Example");
- // Ensure we can capture the escape key being pressed below
- glfwEnable( GLFW_STICKY_KEYS );
- // Enable vertical sync (on cards that support it)
- glfwSwapInterval( 1 );
- float t = particleLifetime;
- glUniform1f(UNIF_T, t); //1f = 1dimensional
- glUniform3f(UNIF_ACCEL, accelX, accelY, accelZ); //acceleration has 3 d
- glUniform1f(UNIF_LIFETIME, particleLifetime);
- //what we did: declare const for uniforms, then make uniforms go to vtxshader
- glClearColor(0,0,0,0);
- do {
- int width, height;
- // Get window size (may be different than the requested size)
- //we do this every frame to accommodate window resizing.
- glfwGetWindowSize( &width, &height );
- glViewport( 0, 0, width, height );
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- t += timeSpeed;
- glUniform1f(UNIF_T, t);
- //go through all part again in array
- for (size_t i = 0; i < nParticles; ++i)
- {
- if (t-particles[i].startTime >= particleLifetime)
- {
- particles[i].startTime = t;
- setParticle(particles[i]);
- }
- }
- glDrawArrays(GL_POINTS, 0, nParticles);
- //VERY IMPORTANT: displays the buffer to the screen
- glfwSwapBuffers();
- } while ( glfwGetKey(GLFW_KEY_ESC) != GLFW_PRESS &&
- glfwGetWindowParam(GLFW_OPENED) );
- glfwTerminate();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement