📄 gameswf_render_handler_ogl.cpp
字号:
glVertex2f(x0, y0); glVertex2f(x1, y0); glVertex2f(x1, y1); glVertex2f(x0, y1); glEnd(); } // Old unused code. Might get revived someday. #if 0 // See if we want to, and can, use multitexture // antialiasing. s_multitexture_antialias = false; if (m_enable_antialias) { int tex_units = 0; glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &tex_units); if (tex_units >= 2) { s_multitexture_antialias = true; } // Make sure we have an edge texture available. if (s_multitexture_antialias == true && s_edge_texture_id == 0) { // Very simple texture: 2 texels wide, 1 texel high. // Both texels are white; left texel is all clear, right texel is all opaque. unsigned char edge_data[8] = { 255, 255, 255, 0, 255, 255, 255, 255 }; ogl::active_texture(GL_TEXTURE1_ARB); glEnable(GL_TEXTURE_2D); glGenTextures(1, &s_edge_texture_id); glBindTexture(GL_TEXTURE_2D, s_edge_texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, edge_data); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // @@ should we use a 1D texture??? glDisable(GL_TEXTURE_2D); ogl::active_texture(GL_TEXTURE0_ARB); glDisable(GL_TEXTURE_2D); } } #endif // 0 } void end_display() // Clean up after rendering a frame. Client program is still // responsible for calling glSwapBuffers() or whatever. { glMatrixMode(GL_MODELVIEW); glPopMatrix(); } void set_matrix(const gameswf::matrix& m) // Set the current transform for mesh & line-strip rendering. { m_current_matrix = m; } void set_cxform(const gameswf::cxform& cx) // Set the current color transform for mesh & line-strip rendering. { m_current_cxform = cx; } static void apply_matrix(const gameswf::matrix& m) // multiply current matrix with opengl matrix { float mat[16]; memset(&mat[0], 0, sizeof(mat)); mat[0] = m.m_[0][0]; mat[1] = m.m_[1][0]; mat[4] = m.m_[0][1]; mat[5] = m.m_[1][1]; mat[10] = 1; mat[12] = m.m_[0][2]; mat[13] = m.m_[1][2]; mat[15] = 1; glMultMatrixf(mat); } static void apply_color(const gameswf::rgba& c) // Set the given color. { glColor4ub(c.m_r, c.m_g, c.m_b, c.m_a); } void fill_style_disable(int fill_side) // Don't fill on the {0 == left, 1 == right} side of a path. { assert(fill_side >= 0 && fill_side < 2); m_current_styles[fill_side].disable(); } void line_style_disable() // Don't draw a line on this path. { m_current_styles[LINE_STYLE].disable(); } void fill_style_color(int fill_side, gameswf::rgba color) // Set fill style for the left interior of the shape. If // enable is false, turn off fill for the left interior. { assert(fill_side >= 0 && fill_side < 2); m_current_styles[fill_side].set_color(m_current_cxform.transform(color)); } void line_style_color(gameswf::rgba color) // Set the line style of the shape. If enable is false, turn // off lines for following curve segments. { m_current_styles[LINE_STYLE].set_color(m_current_cxform.transform(color)); } void fill_style_bitmap(int fill_side, const gameswf::bitmap_info* bi, const gameswf::matrix& m, bitmap_wrap_mode wm) { assert(fill_side >= 0 && fill_side < 2); m_current_styles[fill_side].set_bitmap(bi, m, wm, m_current_cxform); } void line_style_width(float width) { // WK: what to do here??? } void draw_mesh_strip(const void* coords, int vertex_count) {#define NORMAL_RENDERING//#define MULTIPASS_ANTIALIASING#ifdef NORMAL_RENDERING // Set up current style. m_current_styles[LEFT_STYLE].apply(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); apply_matrix(m_current_matrix); // Send the tris to OpenGL glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_SHORT, sizeof(Sint16) * 2, coords); glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count); if (m_current_styles[LEFT_STYLE].needs_second_pass()) { m_current_styles[LEFT_STYLE].apply_second_pass(); glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count); m_current_styles[LEFT_STYLE].cleanup_second_pass(); } glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix();#endif // NORMAL_RENDERING#ifdef MULTIPASS_ANTIALIASING // So this approach basically works. This // implementation is not totally finished; two pass // materials (i.e. w/ additive color) aren't correct, // and there are some texture etc issues because I'm // just hosing state uncarefully here. It needs the // optimization of only filling the bounding box of // the shape. You must have destination alpha. // // It doesn't look quite perfect on my GF4. For one // thing, you kinda want to crank down the max curve // subdivision error, because suddenly you can see // sub-pixel shape much better. For another thing, // the antialiasing isn't quite perfect, to my eye. // It could be limited alpha precision, imperfections // GL_POLYGON_SMOOTH, and/or my imagination. glDisable(GL_TEXTURE_2D); glEnable(GL_POLYGON_SMOOTH); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); // GL_NICEST, GL_FASTEST, GL_DONT_CARE // Clear destination alpha. // // @@ TODO Instead of drawing this huge screen-filling // quad, we should take a bounding-box param from the // caller, and draw the box (after apply_matrix; // i.e. the box is in object space). The point being, // to only fill the part of the screen that the shape // is in. glBlendFunc(GL_ZERO, GL_SRC_COLOR); glColor4f(1, 1, 1, 0); glBegin(GL_QUADS); glVertex2f(0, 0); glVertex2f(100000, 0); glVertex2f(100000, 100000); glVertex2f(0, 100000); glEnd(); // Set mode for drawing alpha mask. glBlendFunc(GL_ONE, GL_ONE); // additive blending glColor4f(0, 0, 0, m_current_styles[LEFT_STYLE].m_color.m_a / 255.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); apply_matrix(m_current_matrix); // Send the tris to OpenGL. This produces an // antialiased alpha mask of the mesh shape, in the // destination alpha channel. glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_SHORT, sizeof(Sint16) * 2, coords); glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count); glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); // Set up desired fill style. m_current_styles[LEFT_STYLE].apply(); // Apply fill, modulated with alpha mask. // // @@ TODO see note above about filling bounding box only. glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); glBegin(GL_QUADS); glVertex2f(0, 0); glVertex2f(100000, 0); glVertex2f(100000, 100000); glVertex2f(0, 100000); glEnd();// xxxxx ??? Hm, is our mask still intact, or did we just erase it?// if (m_current_styles[LEFT_STYLE].needs_second_pass())// {// m_current_styles[LEFT_STYLE].apply_second_pass();// glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count);// m_current_styles[LEFT_STYLE].cleanup_second_pass();// } // @@ hm, there is perhaps more state that needs // fixing here, or setting elsewhere. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);#endif // MULTIPASS_ANTIALIASING } void draw_line_strip(const void* coords, int vertex_count) // Draw the line strip formed by the sequence of points. { // Set up current style. m_current_styles[LINE_STYLE].apply(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); apply_matrix(m_current_matrix); // Send the line-strip to OpenGL glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_SHORT, sizeof(Sint16) * 2, coords); glDrawArrays(GL_LINE_STRIP, 0, vertex_count); glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); } void draw_bitmap( const gameswf::matrix& m, const gameswf::bitmap_info* bi, const gameswf::rect& coords, const gameswf::rect& uv_coords, gameswf::rgba color) // Draw a rectangle textured with the given bitmap, with the // given color. Apply given transform; ignore any currently // set transforms. // // Intended for textured glyph rendering. { assert(bi); apply_color(color); gameswf::point a, b, c, d; m.transform(&a, gameswf::point(coords.m_x_min, coords.m_y_min)); m.transform(&b, gameswf::point(coords.m_x_max, coords.m_y_min)); m.transform(&c, gameswf::point(coords.m_x_min, coords.m_y_max)); d.m_x = b.m_x + c.m_x - a.m_x; d.m_y = b.m_y + c.m_y - a.m_y; glBindTexture(GL_TEXTURE_2D, bi->m_texture_id); glEnable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(uv_coords.m_x_min, uv_coords.m_y_min); glVertex2f(a.m_x, a.m_y); glTexCoord2f(uv_coords.m_x_max, uv_coords.m_y_min); glVertex2f(b.m_x, b.m_y); glTexCoord2f(uv_coords.m_x_min, uv_coords.m_y_max); glVertex2f(c.m_x, c.m_y); glTexCoord2f(uv_coords.m_x_max, uv_coords.m_y_max); glVertex2f(d.m_x, d.m_y); glEnd(); } void begin_submit_mask() { glEnable(GL_STENCIL_TEST); glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); glColorMask(0,0,0,0); // disable framebuffer writes glEnable(GL_STENCIL_TEST); // enable stencil buffer for "marking" the mask glStencilFunc(GL_ALWAYS, 1, 1); // always passes, 1 bit plane, 1 as mask glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); // we set the stencil buffer to 1 where we draw any polygon // keep if test fails, keep if test passes but buffer test fails // replace if test passes } void end_submit_mask() { glColorMask(1,1,1,1); // enable framebuffer writes glStencilFunc(GL_EQUAL, 1, 1); // we draw only where the stencil is 1 (where the mask was drawn) glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // don't change the stencil buffer } void disable_mask() { glDisable(GL_STENCIL_TEST); } }; // end struct render_handler_ogl// bitmap_info_ogl implementationvoid hardware_resample(int bytes_per_pixel, int src_width, int src_height, uint8* src_data, int dst_width, int dst_height)// Code from Alex Streit//// Sets the current texture to a resampled/expanded version of the// given image data.{ assert(bytes_per_pixel == 3 || bytes_per_pixel == 4); unsigned int in_format = bytes_per_pixel == 3 ? GL_RGB : GL_RGBA; unsigned int out_format = bytes_per_pixel == 3 ? GL_RGB : GL_RGBA; // alex: use the hardware to resample the image // issue: does not work when image > allocated window size! glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT); { char* temp = new char[dst_width * dst_height * bytes_per_pixel]; //memset(temp,255,w*h*3); glTexImage2D(GL_TEXTURE_2D, 0, in_format, dst_width, dst_height, 0, out_format, GL_UNSIGNED_BYTE, temp); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, src_width, src_height, out_format, GL_UNSIGNED_BYTE, src_data); glLoadIdentity(); glViewport(0, 0, dst_width, dst_height); glOrtho(0, dst_width, 0, dst_height, 0.9, 1.1); glColor3f(1, 1, 1); glNormal3f(0, 0, 1); glBegin(GL_QUADS); { glTexCoord2f(0, (float) src_height / dst_height); glVertex3f(0, 0, -1); glTexCoord2f( (float) src_width / dst_width, (float) src_height / dst_height); glVertex3f((float) dst_width, 0, -1); glTexCoord2f( (float) src_width / dst_width, 0); glVertex3f((float) dst_width, (float) dst_height, -1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -