void set_shader(Uint32 program, GPU_ShaderBlock* block) { if(program == 0) program = GPU_GetContextTarget()->context->default_textured_shader_program; GPU_ActivateShaderProgram(program, block); timeloc = GPU_GetUniformLocation(program, "time"); color_attr.location = GPU_GetAttributeLocation(program, "gpu_Color"); }
shader_program::shader_program(const std::string &vsrc, const std::string &fsrc) : program_object_(0) , vertex_object_(0) , fragment_object_(0) , block_() , attr_color_mod_(0) , attr_submerge_(0) , attr_effects_(0) , uni_overlay_(0) , overlay_image_() , refcount_(new unsigned(1)) { vertex_object_ = GPU_LoadShader(GPU_VERTEX_SHADER, vsrc.c_str()); if (!vertex_object_) { throw shader_error("Failed to compile vertex shader"); } fragment_object_ = GPU_LoadShader(GPU_FRAGMENT_SHADER, fsrc.c_str()); if (!fragment_object_) { throw shader_error("Failed to compile fragment shader"); } program_object_ = GPU_LinkShaders(vertex_object_, fragment_object_); if (!program_object_) { throw shader_error("Failed to link shader program"); } attr_color_mod_ = GPU_GetAttributeLocation(program_object_, "vert_color_mod"); attr_submerge_ = GPU_GetAttributeLocation(program_object_, "vert_submerge"); attr_effects_ = GPU_GetAttributeLocation(program_object_, "vert_effects"); uni_overlay_ = GPU_GetUniformLocation(program_object_, "overlay"); set_color_mod(0, 0, 0, 0); set_submerge(0); set_effects(0); }
int main(int argc, char* argv[]) { GPU_Target* screen; printRenderers(); screen = GPU_Init(800, 600, GPU_DEFAULT_INIT_FLAGS); if(screen == NULL) return -1; printCurrentRenderer(); { Uint32 startTime; long frameCount; Uint8 done; SDL_Event event; GPU_Image* image; Uint32 v, f, p; GPU_ShaderBlock block; int uloc; int timeloc; float dt; #define MAX_SPRITES 50 int numSprites; float x[MAX_SPRITES]; float y[MAX_SPRITES]; float velx[MAX_SPRITES]; float vely[MAX_SPRITES]; int i; image = GPU_LoadImage("data/test.bmp"); if(image == NULL) return -1; block = load_shaders(&v, &f, &p); uloc = GPU_GetUniformLocation(p, "tex"); GPU_SetUniformi(uloc, 0); timeloc = GPU_GetUniformLocation(p, "time"); dt = 0.010f; startTime = SDL_GetTicks(); frameCount = 0; numSprites = 1; for(i = 0; i < MAX_SPRITES; i++) { x[i] = rand()%screen->w; y[i] = rand()%screen->h; velx[i] = 10 + rand()%screen->w/10; vely[i] = 10 + rand()%screen->h/10; } done = 0; while(!done) { while(SDL_PollEvent(&event)) { if(event.type == SDL_QUIT) done = 1; else if(event.type == SDL_KEYDOWN) { if(event.key.keysym.sym == SDLK_ESCAPE) done = 1; else if(event.key.keysym.sym == SDLK_EQUALS || event.key.keysym.sym == SDLK_PLUS) { if(numSprites < MAX_SPRITES) numSprites++; } else if(event.key.keysym.sym == SDLK_MINUS) { if(numSprites > 0) numSprites--; } else if(event.key.keysym.sym == SDLK_SPACE) { if(GPU_IsDefaultShaderProgram(GPU_GetCurrentShaderProgram())) { GPU_ActivateShaderProgram(p, &block); uloc = GPU_GetUniformLocation(p, "tex"); GPU_SetUniformi(uloc, 0); timeloc = GPU_GetUniformLocation(p, "time"); } else GPU_ActivateShaderProgram(0, NULL); } } } for(i = 0; i < numSprites; i++) { x[i] += velx[i]*dt; y[i] += vely[i]*dt; if(x[i] < 0) { x[i] = 0; velx[i] = -velx[i]; } else if(x[i]> screen->w) { x[i] = screen->w; velx[i] = -velx[i]; } if(y[i] < 0) { y[i] = 0; vely[i] = -vely[i]; } else if(y[i]> screen->h) { y[i] = screen->h; vely[i] = -vely[i]; } } GPU_SetUniformf(timeloc, SDL_GetTicks()/1000.0f); GPU_Clear(screen); for(i = 0; i < numSprites; i++) { GPU_Blit(image, NULL, screen, x[i], y[i]); } GPU_Flip(screen); frameCount++; if(frameCount%500 == 0) printf("Average FPS: %.2f\n", 1000.0f*frameCount/(SDL_GetTicks() - startTime)); } printf("Average FPS: %.2f\n", 1000.0f*frameCount/(SDL_GetTicks() - startTime)); GPU_FreeImage(image); free_shaders(v, f, p); } GPU_Quit(); return 0; }
int do_attributes(GPU_Target* screen) { GPU_LogError("do_attributes()\n"); GPU_Image* image = GPU_LoadImage("data/small_test.png"); if(image == NULL) return -1; int return_value = 0; float dt = 0.010f; Uint32 startTime = SDL_GetTicks(); long frameCount = 0; int maxSprites = 50000; int numSprites = 101; // 2 pos floats per vertex, 2 texcoords, 4 color components int floats_per_vertex = 2 + 2 + 4; int floats_per_sprite = floats_per_vertex*4; float* sprite_values = (float*)malloc(sizeof(float)*maxSprites*floats_per_sprite); // Load attributes for the textured shader Uint32 program_object = 0; GPU_ActivateShaderProgram(program_object, NULL); // Disable the default shader's attributes (not a typical thing to do...) GPU_ShaderBlock block = {-1,-1,-1,GPU_GetUniformLocation(program_object, "gpu_ModelViewProjectionMatrix")}; GPU_ActivateShaderProgram(program_object, &block); GPU_Attribute attributes[3] = { GPU_MakeAttribute(GPU_GetAttributeLocation(program_object, "gpu_Vertex"), sprite_values, GPU_MakeAttributeFormat(2, GPU_TYPE_FLOAT, 0, floats_per_vertex*sizeof(float), 0)), GPU_MakeAttribute(GPU_GetAttributeLocation(program_object, "gpu_TexCoord"), sprite_values, GPU_MakeAttributeFormat(2, GPU_TYPE_FLOAT, 0, floats_per_vertex*sizeof(float), 2*sizeof(float))), GPU_MakeAttribute(GPU_GetAttributeLocation(program_object, "gpu_Color"), sprite_values, GPU_MakeAttributeFormat(4, GPU_TYPE_FLOAT, 0, floats_per_vertex*sizeof(float), 4*sizeof(float))) }; float* velx = (float*)malloc(sizeof(float)*maxSprites); float* vely = (float*)malloc(sizeof(float)*maxSprites); int i; int val_n = 0; for(i = 0; i < maxSprites; i++) { float x = rand()%screen->w; float y = rand()%screen->h; sprite_values[val_n++] = x - image->w/2; sprite_values[val_n++] = y - image->h/2; sprite_values[val_n++] = 0; sprite_values[val_n++] = 0; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = x + image->w/2; sprite_values[val_n++] = y - image->h/2; sprite_values[val_n++] = 1; sprite_values[val_n++] = 0; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = x + image->w/2; sprite_values[val_n++] = y + image->h/2; sprite_values[val_n++] = 1; sprite_values[val_n++] = 1; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = x - image->w/2; sprite_values[val_n++] = y + image->h/2; sprite_values[val_n++] = 0; sprite_values[val_n++] = 1; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = rand()%101/100.0f; sprite_values[val_n++] = rand()%101/100.0f; velx[i] = 10 + rand()%screen->w/10; vely[i] = 10 + rand()%screen->h/10; if(rand()%2) velx[i] = -velx[i]; if(rand()%2) vely[i] = -vely[i]; } Uint8 done = 0; SDL_Event event; while(!done) { while(SDL_PollEvent(&event)) { if(event.type == SDL_QUIT) done = 1; else if(event.type == SDL_KEYDOWN) { if(event.key.keysym.sym == SDLK_ESCAPE) done = 1; else if(event.key.keysym.sym == SDLK_SPACE) { done = 1; return_value = 1; } else if(event.key.keysym.sym == SDLK_EQUALS || event.key.keysym.sym == SDLK_PLUS) { if(numSprites < maxSprites) numSprites += 100; GPU_LogError("Sprites: %d\n", numSprites); frameCount = 0; startTime = SDL_GetTicks(); } else if(event.key.keysym.sym == SDLK_MINUS) { if(numSprites > 1) numSprites -= 100; if(numSprites < 1) numSprites = 1; GPU_LogError("Sprites: %d\n", numSprites); frameCount = 0; startTime = SDL_GetTicks(); } } } GPU_Clear(screen); for(i = 0; i < numSprites; i++) { val_n = floats_per_sprite*i; float x = sprite_values[val_n] + image->w/2; float y = sprite_values[val_n+1] + image->h/2; x += velx[i]*dt; y += vely[i]*dt; if(x < 0) { x = 0; velx[i] = -velx[i]; } else if(x > screen->w) { x = screen->w; velx[i] = -velx[i]; } if(y < 0) { y = 0; vely[i] = -vely[i]; } else if(y > screen->h) { y = screen->h; vely[i] = -vely[i]; } sprite_values[val_n] = x - image->w/2; sprite_values[val_n+1] = y - image->h/2; val_n += floats_per_vertex; sprite_values[val_n] = x + image->w/2; sprite_values[val_n+1] = y - image->h/2; val_n += floats_per_vertex; sprite_values[val_n] = x + image->w/2; sprite_values[val_n+1] = y + image->h/2; val_n += floats_per_vertex; sprite_values[val_n] = x - image->w/2; sprite_values[val_n+1] = y + image->h/2; } //float color[4] = {0.5f, 0, 0, 1.0f}; //GPU_SetAttributefv(attributes[2].location, 4, color); GPU_SetAttributeSource(numSprites*4, attributes[0]); GPU_SetAttributeSource(numSprites*4, attributes[1]); GPU_SetAttributeSource(numSprites*4, attributes[2]); GPU_BlitBatch(image, screen, numSprites, NULL, 0); GPU_Flip(screen); frameCount++; if(SDL_GetTicks() - startTime > 5000) { printf("Average FPS: %.2f\n", 1000.0f*frameCount/(SDL_GetTicks() - startTime)); frameCount = 0; startTime = SDL_GetTicks(); } } printf("Average FPS: %.2f\n", 1000.0f*frameCount/(SDL_GetTicks() - startTime)); free(sprite_values); free(velx); free(vely); GPU_FreeImage(image); // Reset the default shader's block GPU_ActivateShaderProgram(screen->context->default_textured_shader_program, NULL); return return_value; }
int main(int argc, char* argv[]) { GPU_Target* screen; GPU_SetDebugLevel(GPU_DEBUG_LEVEL_MAX); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); GPU_SetRequiredFeatures(GPU_FEATURE_BASIC_SHADERS); screen = GPU_InitRenderer(GPU_RENDERER_OPENGL_3, 800, 600, GPU_DEFAULT_INIT_FLAGS); if(screen == NULL) { GPU_LogError("Initialization Error: Could not create a renderer with proper feature support for this demo.\n"); return 1; } glewExperimental = GL_TRUE; // Force GLEW to get exported functions instead of checking via extension string if(glewInit() != GLEW_OK) { GPU_LogError("Initialization Error: Failed to initialize GLEW.\n"); return 2; } { GPU_Image* image; float dt; Uint32 startTime; long frameCount; int maxSprites = 50; int numSprites; float x[50]; float y[50]; float velx[50]; float vely[50]; int i; Uint8 done; SDL_Event event; image = GPU_LoadImage("data/test.bmp"); if (image == NULL) return 3; v = GPU_LoadShader(GPU_VERTEX_SHADER, "data/shaders/untextured-150.vert"); f = GPU_LoadShader(GPU_FRAGMENT_SHADER, "data/shaders/untextured-150.frag"); p = GPU_LinkShaders(v, f); GPU_Log("%s\n", GPU_GetShaderMessage()); glUseProgram(p); vertex_loc = GPU_GetAttributeLocation(p, "gpu_Vertex"); color_loc = GPU_GetAttributeLocation(p, "gpu_Color"); modelViewProjection_loc = GPU_GetUniformLocation(p, "gpu_ModelViewProjectionMatrix"); glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); dt = 0.010f; startTime = SDL_GetTicks(); frameCount = 0; numSprites = 1; for (i = 0; i < maxSprites; i++) { x[i] = rand() % screen->w; y[i] = rand() % screen->h; velx[i] = 10 + rand() % screen->w / 10; vely[i] = 10 + rand() % screen->h / 10; } done = 0; while (!done) { while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) done = 1; else if (event.type == SDL_KEYDOWN) { if (event.key.keysym.sym == SDLK_ESCAPE) done = 1; else if (event.key.keysym.sym == SDLK_EQUALS || event.key.keysym.sym == SDLK_PLUS) { if (numSprites < maxSprites) numSprites++; } else if (event.key.keysym.sym == SDLK_MINUS) { if (numSprites > 0) numSprites--; } } } for (i = 0; i < numSprites; i++) { x[i] += velx[i] * dt; y[i] += vely[i] * dt; if (x[i] < 0) { x[i] = 0; velx[i] = -velx[i]; } else if (x[i]> screen->w) { x[i] = screen->w; velx[i] = -velx[i]; } if (y[i] < 0) { y[i] = 0; vely[i] = -vely[i]; } else if (y[i]> screen->h) { y[i] = screen->h; vely[i] = -vely[i]; } } GPU_Clear(screen); draw_3d_stuff(screen); for (i = 0; i < numSprites; i++) { GPU_Blit(image, NULL, screen, x[i], y[i]); } draw_more_3d_stuff(screen); GPU_Flip(screen); frameCount++; if (frameCount % 500 == 0) printf("Average FPS: %.2f\n", 1000.0f*frameCount / (SDL_GetTicks() - startTime)); } printf("Average FPS: %.2f\n", 1000.0f*frameCount / (SDL_GetTicks() - startTime)); GPU_FreeImage(image); } GPU_Quit(); return 0; }
int do_attributes(GPU_Target* screen) { Uint32 startTime; long frameCount; Uint8 done; SDL_Event event; int return_value = 0; float dt = 0.010f; int max_vertices = 60000; int num_vertices = 303; float* velx = (float*)malloc(sizeof(float)*max_vertices/3); float* vely = (float*)malloc(sizeof(float)*max_vertices/3); int i; // 2 pos floats per vertex, 2 texcoords, 4 color components int floats_per_vertex = 2 + 2 + 4; float* vertex_values = (float*)malloc(sizeof(float)*max_vertices*floats_per_vertex); Uint32 program_object; GPU_Attribute attributes[3]; GPU_Image* image = GPU_LoadImage("data/small_test.png"); GPU_LogError("do_attributes()\n"); if(image == NULL) return -1; startTime = SDL_GetTicks(); frameCount = 0; fill_vertex_values(vertex_values, velx, vely, max_vertices, screen, image); // Load attributes for the textured shader program_object = 0; GPU_ActivateShaderProgram(program_object, NULL); // Disable the default shader's attributes (not a typical thing to do...) { GPU_ShaderBlock block = {-1,-1,-1,GPU_GetUniformLocation(program_object, "gpu_ModelViewProjectionMatrix")}; GPU_ActivateShaderProgram(program_object, &block); } attributes[0] = GPU_MakeAttribute(GPU_GetAttributeLocation(program_object, "gpu_Vertex"), vertex_values, GPU_MakeAttributeFormat(2, GPU_TYPE_FLOAT, 0, floats_per_vertex*sizeof(float), 0)); attributes[1] = GPU_MakeAttribute(GPU_GetAttributeLocation(program_object, "gpu_TexCoord"), vertex_values, GPU_MakeAttributeFormat(2, GPU_TYPE_FLOAT, 0, floats_per_vertex*sizeof(float), 2 * sizeof(float))); attributes[2] = GPU_MakeAttribute(GPU_GetAttributeLocation(program_object, "gpu_Color"), vertex_values, GPU_MakeAttributeFormat(4, GPU_TYPE_FLOAT, 0, floats_per_vertex*sizeof(float), 4 * sizeof(float))); done = 0; while(!done) { while(SDL_PollEvent(&event)) { if(event.type == SDL_QUIT) done = 1; else if(event.type == SDL_KEYDOWN) { if(event.key.keysym.sym == SDLK_ESCAPE) done = 1; else if(event.key.keysym.sym == SDLK_SPACE) { done = 1; return_value = 4; } else if(event.key.keysym.sym == SDLK_EQUALS || event.key.keysym.sym == SDLK_PLUS) { num_vertices += 300; if(num_vertices > max_vertices) num_vertices = max_vertices; GPU_LogError("Vertices: %d\n", num_vertices); frameCount = 0; startTime = SDL_GetTicks(); } else if(event.key.keysym.sym == SDLK_MINUS) { if(num_vertices > 3) num_vertices -= 300; if(num_vertices < 3) num_vertices = 3; GPU_LogError("Vertices: %d\n", num_vertices); frameCount = 0; startTime = SDL_GetTicks(); } } } GPU_Clear(screen); // FIXME: Can cause squishing when a vertex hits a wall... for(i = 0; i < num_vertices; i++) { int n = i/3; int val_n = floats_per_vertex*i; vertex_values[val_n] += velx[n]*dt; vertex_values[val_n+1] += vely[n]*dt; if(vertex_values[val_n] < 0) { vertex_values[val_n] = 0; velx[n] = -velx[n]; } else if(vertex_values[val_n] > screen->w) { vertex_values[val_n] = screen->w; velx[n] = -velx[n]; } if(vertex_values[val_n+1] < 0) { vertex_values[val_n+1] = 0; vely[n] = -vely[n]; } else if(vertex_values[val_n+1] > screen->h) { vertex_values[val_n+1] = screen->h; vely[n] = -vely[n]; } } GPU_SetAttributeSource(num_vertices, attributes[0]); GPU_SetAttributeSource(num_vertices, attributes[1]); GPU_SetAttributeSource(num_vertices, attributes[2]); GPU_TriangleBatch(image, screen, num_vertices, NULL, 0, NULL, GPU_NONE); GPU_Flip(screen); frameCount++; if(SDL_GetTicks() - startTime > 5000) { printf("Average FPS: %.2f\n", 1000.0f*frameCount/(SDL_GetTicks() - startTime)); frameCount = 0; startTime = SDL_GetTicks(); } } printf("Average FPS: %.2f\n", 1000.0f*frameCount/(SDL_GetTicks() - startTime)); free(vertex_values); free(velx); free(vely); GPU_FreeImage(image); // Reset the default shader's block GPU_ActivateShaderProgram(screen->context->default_textured_shader_program, NULL); return return_value; }