#define GF_EXPOSE_DRAW_DRIVER #define GF_EXPOSE_DRAW #define GF_EXPOSE_TEXTURE #include /* External library */ #include /* Interface */ #include /* Engine */ #include #include #include #include #include #include /* Standard */ #include #include GLfloat lightwht[] = {1.0, 1.0, 1.0, 1.0}; GLfloat lightgry[] = {0.6, 0.6, 0.6, 1.0}; GLfloat lightdim[] = {0.2, 0.2, 0.2, 1.0}; GLfloat lightblk[] = {0.0, 0.0, 0.0, 1.0}; gf_draw_driver_texture_t* gf_draw_driver_register_texture(gf_draw_t* draw, int width, int height, int* iwidth, int* iheight, unsigned char* data) { gf_draw_driver_texture_t* r = malloc(sizeof(*r)); int w = gf_math_nearest_2pow(width); int h = gf_math_nearest_2pow(height); int x, y; unsigned char* d = malloc(w * h * 4); *iwidth = w; *iheight = h; memset(d, 0, w * h * 4); for(y = 0; y < height; y++) { for(x = 0; x < width; x++) { int pos = (y * w + x) * 4; int ogpos = (y * width + x) * 4; memcpy(d + pos + 0, data + ogpos + 0, 4); } } glGenTextures(1, &r->id); glBindTexture(GL_TEXTURE_2D, r->id); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, d); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); #if 0 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); #endif glBindTexture(GL_TEXTURE_2D, 0); return r; } void gf_draw_driver_destroy_texture(gf_draw_driver_texture_t* t) { glDeleteTextures(1, &t->id); free(t); } gf_draw_driver_t* gf_draw_driver_create(gf_engine_t* engine, gf_draw_t* draw) { gf_draw_driver_t* draw_driver = malloc(sizeof(*draw_driver)); memset(draw_driver, 0, sizeof(*draw_driver)); draw_driver->engine = engine; gf_log_function(engine, "OpenGL renderer: %s", (char*)glGetString(GL_RENDERER)); glEnable(GL_BLEND); glEnable(GL_NORMALIZE); glEnable(GL_COLOR_MATERIAL); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glCullFace(GL_BACK); glShadeModel(GL_SMOOTH); glLightfv(GL_LIGHT0, GL_AMBIENT, lightgry); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightwht); glLightfv(GL_LIGHT0, GL_SPECULAR, lightwht); glClearColor(0, 0, 0, 1); return draw_driver; } int gf_draw_driver_has_extension(gf_draw_t* draw, const char* query) { int ret = gf_draw_platform_has_extension(draw, query); const char* ext = NULL; const char* ptr; const int len = strlen(query); if(ret != 0) return ret; ext = glGetString(GL_EXTENSIONS); ptr = strstr(ext, query); return ((ptr != NULL) && ((ptr[len] == ' ') || (ptr[len] == '\0'))); } void gf_draw_driver_reshape(gf_draw_t* draw) { glViewport(0, 0, (GLint)draw->width, (GLint)draw->height); glMatrixMode(GL_PROJECTION); gf_graphic_perspective(draw, 30, 1.0, 1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void gf_draw_driver_begin_texture_2d(gf_draw_t* draw, gf_texture_t* texture) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture->draw_driver_texture->id); } void gf_draw_driver_end_texture_2d(gf_draw_t* draw) { glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); } void gf_draw_driver_set_color(gf_draw_t* draw, gf_graphic_color_t color) { glColor4f(color.r / 255, color.g / 255, color.b / 255, color.a / 255); } void gf_draw_driver_destroy(gf_draw_driver_t* driver) { gf_log_function(driver->engine, "Destroyed drawing driver", ""); free(driver); } void gf_draw_driver_before(gf_draw_t* draw) { GLfloat lightpos[4]; GF_MATH_VECTOR_COPY(draw->light, lightpos); lightpos[3] = draw->light[3]; gf_draw_driver_reshape(draw); gf_graphic_set_camera(draw); glLightfv(GL_LIGHT0, GL_POSITION, lightpos); gf_graphic_clear(draw); } void gf_draw_driver_after(gf_draw_t* draw) { glFlush(); }