LRESULT CALLBACK WinProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { LONG lRet = 0; PAINTSTRUCT ps; switch (uMsg) { case WM_SIZE: // If the window is resized if(!g_bFullScreen) // Do this only if we are NOT in full screen { SizeOpenGLScreen(LOWORD(lParam),HIWORD(lParam));// LoWord=Width, HiWord=Height GetClientRect(hWnd, &g_rRect); // Get the window rectangle } break; case WM_PAINT: // If we need to repaint the scene BeginPaint(hWnd, &ps); // Init the paint struct EndPaint(hWnd, &ps); // EndPaint, Clean up break; case WM_LBUTTONDOWN: // If we hit the left mouse button // Change the rendering mode to lines or triangles depending on it's current status g_bRenderMode = !g_bRenderMode; // Change the rendering mode to and from lines or triangles if(g_bRenderMode) { // Render the triangles in fill mode glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } else { // Render the triangles in wire frame mode glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } break; case WM_RBUTTONDOWN: // If the right mouse button was clicked. g_bLighting = !g_bLighting; // Turn lighting ON/OFF if(g_bLighting) // If lighting is ON { glEnable(GL_LIGHTING); // Enable OpenGL lighting } else { glDisable(GL_LIGHTING); // Disable OpenGL lighting } break; case WM_KEYDOWN: // If we hit a key switch (wParam) // Check which key we hit { case VK_ESCAPE: // If we hit ESCAPE PostQuitMessage(0); // Tell windows we want to quit break; case VK_ADD: // If we hit '+' g_MaxSubdivisions += 1; // Increase the current max subdivisions // Make sure we don't go over 10 subdivisions, otherwise it will get crazy if(g_MaxSubdivisions > 10) g_MaxSubdivisions = 10; // Destroy the octree and debug lines and create a new one with the new info RecreateOctree(); break; case VK_SUBTRACT: // If we hit '-' g_MaxSubdivisions -= 1; // Decrease the current max subdivisions // Make sure we don't go below zero subdivisions if(g_MaxSubdivisions < 0) g_MaxSubdivisions = 0; // Destroy the octree and debug lines and create a new one with the new info RecreateOctree(); break; case VK_F5: // If we hit F5 g_MaxTriangles += 20; // Increase the max triangle count by 20 // Make sure we don't go above 2000 if(g_MaxTriangles > 2000) g_MaxTriangles = 2000; // Destroy the octree and debug lines and create a new one with the new info RecreateOctree(); break; case VK_F6: // If we hit F6 g_MaxTriangles -= 20; // Decrease the max triangle count by 20 // Make sure we don't go below 0 (0 would produce as many nodes as triangles) if(g_MaxTriangles < 0) g_MaxTriangles = 0; // Destroy the octree and debug lines and create a new one with the new info RecreateOctree(); break; } break; case WM_CLOSE: // If the window is closed PostQuitMessage(0); // Tell windows we want to quit break; default: // Return by default lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); break; } return lRet; // Return by default }
void VoxelTerrain::UpdateTerrain(){ glBindBuffer(GL_ARRAY_BUFFER,0); RecreateOctree(); glDisable(GL_ALPHA_TEST); if (order!=0){ glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); }else{ glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); } switch(brush.blend){ case 0: glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); // alpha break; case 1: glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); // alpha break; case 2: glBlendFunc(GL_DST_COLOR,GL_ZERO); // multiply break; case 3: glBlendFunc(GL_SRC_ALPHA,GL_ONE); // additive and alpha break; } float ambient_red,ambient_green,ambient_blue; // fx flag 1 - full bright ***todo*** disable all lights? if (brush.fx & 1){ if(Global::fx1!=true){ Global::fx1=true; glDisableClientState(GL_NORMAL_ARRAY); } ambient_red =1.0; ambient_green=1.0; ambient_blue =1.0; }else{ if(Global::fx1!=false){ Global::fx1=false; glEnableClientState(GL_NORMAL_ARRAY); } ambient_red =Global::ambient_red; ambient_green=Global::ambient_green; ambient_blue =Global::ambient_blue; } // fx flag 2 - vertex colours /*if(brush.fx&2){ glEnable(GL_COLOR_MATERIAL); }else{ glDisable(GL_COLOR_MATERIAL); }*/ if(Global::fx2!=false){ Global::fx2=false; glDisableClientState(GL_COLOR_ARRAY); glDisable(GL_COLOR_MATERIAL); } // fx flag 4 - flatshaded if(brush.fx&4){ glShadeModel(GL_FLAT); }else{ glShadeModel(GL_SMOOTH); } // fx flag 8 - disable fog if(brush.fx&8){ if(Global::fog_enabled==true){ // only disable if fog enabled in camera update glDisable(GL_FOG); } } // fx flag 16 - disable backface culling if(brush.fx&16){ glDisable(GL_CULL_FACE); }else{ glEnable(GL_CULL_FACE); } // light + material color float ambient[]={ambient_red,ambient_green,ambient_blue}; glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient); float mat_ambient[]={brush.red,brush.green,brush.blue,brush.alpha}; float mat_diffuse[]={brush.red,brush.green,brush.blue,brush.alpha}; float mat_specular[]={brush.shine,brush.shine,brush.shine,brush.shine}; float mat_shininess[]={100.0}; // upto 128 glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,mat_ambient); glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,mat_diffuse); glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,mat_specular); glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,mat_shininess); // textures int tex_count=0; if(ShaderMat!=NULL){ ShaderMat->TurnOn(mat, 0, &vertices); } tex_count=brush.no_texs; int DisableCubeSphereMapping=0; for(int ix=0;ix<tex_count;ix++){ if(brush.tex[ix]){ // Main brush texture takes precedent over surface brush texture unsigned int texture=0; int tex_flags=0,tex_blend=0; float tex_u_scale=1.0,tex_v_scale=1.0,tex_u_pos=0.0,tex_v_pos=0.0,tex_ang=0.0; int tex_cube_mode=0; texture=brush.cache_frame[ix]; tex_flags=brush.tex[ix]->flags; tex_blend=brush.tex[ix]->blend; //tex_coords=brush.tex[ix]->coords; tex_u_scale=brush.tex[ix]->u_scale; tex_v_scale=brush.tex[ix]->v_scale; tex_u_pos=brush.tex[ix]->u_pos; tex_v_pos=brush.tex[ix]->v_pos; tex_ang=brush.tex[ix]->angle; tex_cube_mode=brush.tex[ix]->cube_mode; //frame=brush.tex_frame; glActiveTexture(GL_TEXTURE0+ix); glClientActiveTexture(GL_TEXTURE0+ix); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,texture); // call before glTexParameteri // masked texture flag if(tex_flags&4){ glEnable(GL_ALPHA_TEST); }else{ glDisable(GL_ALPHA_TEST); } // mipmapping texture flag if(tex_flags&8){ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); }else{ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); } // clamp u flag if(tex_flags&16){ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); }else{ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); } // clamp v flag if(tex_flags&32){ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); }else{ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); } // ***!ES*** // spherical environment map texture flag if(tex_flags&64){ glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); DisableCubeSphereMapping=1; }/*else{ glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); }*/ // cubic environment map texture flag if(tex_flags&128){ glEnable(GL_TEXTURE_CUBE_MAP); glBindTexture(GL_TEXTURE_CUBE_MAP,texture); // call before glTexParameteri glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_WRAP_R,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_GEN_R); //glEnable(GL_TEXTURE_GEN_Q) if(tex_cube_mode==1){ glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_REFLECTION_MAP); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_REFLECTION_MAP); glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_REFLECTION_MAP); } if(tex_cube_mode==2){ glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_NORMAL_MAP); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_NORMAL_MAP); glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_NORMAL_MAP); } DisableCubeSphereMapping=1; }else if (DisableCubeSphereMapping!=0){ glDisable(GL_TEXTURE_CUBE_MAP); // only disable tex gen s and t if sphere mapping isn't using them if((tex_flags & 64)==0){ glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); } glDisable(GL_TEXTURE_GEN_R); //glDisable(GL_TEXTURE_GEN_Q) } switch(tex_blend){ case 0: glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); break; case 1: glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL); break; case 2: glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); //case 2 glTexEnvf(GL_TEXTURE_ENV,GL_COMBINE_RGB_EXT,GL_MODULATE); break; case 3: glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_ADD); break; case 4: glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_DOT3_RGB_EXT); break; case 5: glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV,GL_RGB_SCALE,2.0); break; default: glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2,GL_FLOAT,32,&vertices[6]); // reset texture matrix glMatrixMode(GL_TEXTURE); glLoadIdentity(); if(tex_u_pos!=0.0 || tex_v_pos!=0.0){ glTranslatef(tex_u_pos,tex_v_pos,0.0); } if(tex_ang!=0.0){ glRotatef(tex_ang,0.0,0.0,1.0); } if(tex_u_scale!=1.0 || tex_v_scale!=1.0){ glScalef(tex_u_scale,tex_v_scale,1.0); } // ***!ES*** // if spheremap flag=true then flip tex if(tex_flags&64){ glScalef(1.0,-1.0,-1.0); } // if cubemap flag=true then manipulate texture matrix so that cubemap is displayed properly if(tex_flags&128){ glScalef(1.0,-1.0,-1.0); // get current modelview matrix (set in last camera update) float mod_mat[16]; glGetFloatv(GL_MODELVIEW_MATRIX,&mod_mat[0]); // get rotational inverse of current modelview matrix Matrix new_mat; new_mat.LoadIdentity(); new_mat.grid[0][0] = mod_mat[0]; new_mat.grid[1][0] = mod_mat[1]; new_mat.grid[2][0] = mod_mat[2]; new_mat.grid[0][1] = mod_mat[4]; new_mat.grid[1][1] = mod_mat[5]; new_mat.grid[2][1] = mod_mat[6]; new_mat.grid[0][2] = mod_mat[8]; new_mat.grid[1][2] = mod_mat[9]; new_mat.grid[2][2] = mod_mat[10]; glMultMatrixf(&new_mat.grid[0][0]); } } } // draw tris glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf(&mat.grid[0][0]); glVertexPointer(3,GL_FLOAT,32,&vertices[0]); glNormalPointer(GL_FLOAT,32,&vertices[3]); glDrawArrays(GL_TRIANGLES, 0, triangleindex*3); glPopMatrix(); // disable all texture layers for(int ix=0;ix<tex_count;ix++){ glActiveTexture(GL_TEXTURE0+ix); glClientActiveTexture(GL_TEXTURE0+ix); // reset texture matrix glMatrixMode(GL_TEXTURE); glLoadIdentity(); glDisable(GL_TEXTURE_2D); // ***!ES*** if (DisableCubeSphereMapping!=0){ glDisable(GL_TEXTURE_CUBE_MAP); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); DisableCubeSphereMapping=0; } } glDisableClientState(GL_TEXTURE_COORD_ARRAY); if (brush.fx&8 && Global::fog_enabled==true){ glEnable(GL_FOG); } if(ShaderMat!=NULL){ ShaderMat->TurnOff(); } }