游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3750|回复: 3

一个OpenGL的函数,哪位高人看看怎么在OGRE中实现~

[复制链接]

5

主题

11

帖子

11

积分

新手上路

Rank: 1

积分
11
发表于 2009-12-17 20:32:00 | 显示全部楼层 |阅读模式
void MeshShadows(unsigned char *lightmap, int lightmapSize, unsigned char shadowColor[3], float lightDir[3])
{
        // variable initialization
        int lightmapChunkSize = 128;
        if(lightmapSize < lightmapChunkSize) lightmapChunkSize = lightmapSize;
        float terrainDivisions = lightmapSize / lightmapChunkSize;
        int terrainChunkSize = Terrain.size() / terrainDivisions;

        unsigned char *chunk = new unsigned char[(lightmapChunkSize)*(lightmapChunkSize)*3];

        // create shadow texture
        GLuint shadowChunk;
        glGenTextures(1, &shadowChunk);
        glBindTexture(GL_TEXTURE_2D, shadowChunk);
        glEnable(GL_TEXTURE_2D);
        glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, lightmapChunkSize, lightmapChunkSize, 0);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

        int terrainCol = 0;
        int terrainRow = 0;
        float x0 = 0;
        float y0 = 0;
        float x1 = terrainChunkSize;
        float y1 = terrainChunkSize;

        for(terrainRow = 0; terrainRow < terrainDivisions; terrainRow++)
        {
                for(terrainCol = 0; terrainCol < terrainDivisions; terrainCol++)
                {
                     // setup orthogonal view
                     glViewport(0, 0, terrainChunkSize * Terrain.size(), terrainChunkSize * Terrain.size());
                     glMatrixMode(GL_PROJECTION);
                     glLoadIdentity();
                     glOrtho(0, terrainChunkSize, 0, terrainChunkSize, -10000, 10000);
                     glMatrixMode(GL_MODELVIEW);

                     // apply light's direction to modelview matrix
                     gluLookAt(lightDir[0], lightDir[1], lightDir[2], 0, 0, 0, 0, 1, 0);
  
                     // loop through all vertices in terrain and find min and max points with respect to screen space
                     float minX = 999999, maxX = -999999;
                     float minY = 999999, maxY = -999999;
                     double X, Y, Z;

                     // get pointer to terrain vertices
                     float *vertices = Terrain.vertices()->lock();
                        
                     for(int i = y0-1; i < y1+1; i++)
                     {
                         if(i < 0) continue;
                         for(int j = x0-1; j < x1+1; j++)
                         {
                              if(j < 0) continue;
                              int index = i * Terrain.size() + j;
                              
                              // get screen coordinates for current vertex
                              static GLint viewport[4];
                              static GLdouble modelview[16];
                              static GLdouble projection[16];
                              static GLfloat winX, winY, winZ;

                              glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
                              glGetDoublev( GL_PROJECTION_MATRIX, projection );
                              glGetIntegerv( GL_VIEWPORT, viewport );

                              gluProject(vertices[index*3+0], vertices[index*3+1], vertices[index*3+2], modelview, projection, viewport, &X, &Y, &Z);
                              
                              if(X < minX) minX = X;
                              if(X > maxX) maxX = X;
                              if(Y < minY) minY = Y;
                              if(Y > maxY) maxY = Y;
                         }
                     }
  
                     // clear min and max values
                     static float minX2, minY2, maxX2, maxY2;
                     minX2 = minX;
                     minY2 = minY;
                     maxX2 = maxX;
                     maxY2 = maxY;

                     // clear screen
                     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                     glViewport(0, 0, lightmapChunkSize, lightmapChunkSize);
                     
                     // orient viewport so that terrain chunk fits inside
                     glMatrixMode(GL_PROJECTION);
                     glLoadIdentity();
                     glOrtho(minX, maxX, minY, maxY, -10000, 10000);
                     glMatrixMode(GL_MODELVIEW);

                     // apply light's direction vector to model view transformation
                     glLoadIdentity();
                     gluLookAt(lightDir[0], lightDir[1], lightDir[2], 0, 0, 0, 0, 1, 0);

                     // disable writing to the color buffer
                     glColorMask(false, false, false, false);                  
                     
                     // render terrain
                     Terrain.render();

                     // enable writing to the color buffer
                     glColorMask(true, true, true, true);

                     // render scene meshes '''BLACK'''
                     RenderAllSceneMeshes();

                     // bind shadowChunk texture and copy frame buffer data
                     glBindTexture(GL_TEXTURE_2D, shadowChunk);
                     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, lightmapChunkSize, lightmapChunkSize);
                     glBindTexture(GL_TEXTURE_2D, 0);                  
  
                     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                     glViewport(0, 0, terrainChunkSize * Terrain.size(), terrainChunkSize * Terrain.size());
                    
                     glMatrixMode(GL_PROJECTION);
                     glLoadIdentity();
                     glOrtho(0, 0, terrainChunkSize, terrainChunkSize, -10000, 10000);
                     glMatrixMode(GL_MODELVIEW);
  
                     // rotate view so that xz plane becomes the xy plane
                     glLoadIdentity();
                     glRotatef(90, 1, 0, 0);

                     // reset max and min values
                     minX = minY = 999999;
                     maxX = maxY = -999999;

                     glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
                     glGetDoublev( GL_PROJECTION_MATRIX, projection );
                     glGetIntegerv( GL_VIEWPORT, viewport );

                     // project each corner onto the screen
                     // the corners are represented by the x0, y0, x1 and y1 values
                     gluProject(x0, y0, modelview, projection, viewport, &X, &Y, &Z);
                     if(X < minX) minX = X;
                     if(X > maxX) maxX = X;
                     if(Y < minY) minY = Y;
                     if(Y > maxY) maxY = Y;

                     gluProject(x1, y0, modelview, projection, viewport, &X, &Y, &Z);
                     if(X < minX) minX = X;
                     if(X > maxX) maxX = X;
                     if(Y < minY) minY = Y;
                     if(Y > maxY) maxY = Y;

                     gluProject(x1, y1, modelview, projection, viewport, &X, &Y, &Z);
                     if(X < minX) minX = X;
                     if(X > maxX) maxX = X;
                     if(Y < minY) minY = Y;
                     if(Y > maxY) maxY = Y;

                     gluProject(x0, y1, modelview, projection, viewport, &X, &Y, &Z);
                     if(X < minX) minX = X;
                     if(X > maxX) maxX = X;
                     if(Y < minY) minY = Y;
                     if(Y > maxY) maxY = Y;

                     // resize and re-orient the viewport
                     glViewport(0, 0, terrainChunkSize * Terrain.size(), terrainChunkSize * Terrain.size());
                    
                     glMatrixMode(GL_PROJECTION);
                     glLoadIdentity();
                     glOrtho(minX, minY, maxX, maxY, -10000, 10000);
                     glMatrixMode(GL_MODELVIEW);
   
                     // rotate view so that xz plane becomes the xy plane
                     glLoadIdentity();
                     glRotatef(90, 1, 0, 0);                     

                     // setup projective texturing
                     float PS[] = {1, 0, 0, 0};
                     float PT[] = {0, 1, 0, 0};
                     float PR[] = {0, 0, 1, 0};
                     float PQ[] = {0, 0, 0, 1};

                     glTexGenfv(GL_S, GL_EYE_PLANE, PS);
                     glTexGenfv(GL_T, GL_EYE_PLANE, PT);
                     glTexGenfv(GL_R, GL_EYE_PLANE, PR);
                     glTexGenfv(GL_Q, GL_EYE_PLANE, PQ);

                     glEnable(GL_TEXTURE_GEN_S);
                     glEnable(GL_TEXTURE_GEN_T);
                     glEnable(GL_TEXTURE_GEN_R);
                     glEnable(GL_TEXTURE_GEN_Q);
                     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
                     glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
                     glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
                     glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);

                     // setup texture matrix
                     glBindTexture(GL_TEXTURE_2D, shadowChunk);

                     glMatrixMode(GL_TEXTURE);
                     glLoadIdentity();
                     glTranslatef(0.5, 0.5, 0);
                     glScalef(0.5, 0.5, 1);
                     glOrtho(minX2, maxX2, minY2, maxY2, -10000, 10000);
                     gluLookAt(lightDir[0], lightDir[1], lightDir[2], 0, 0, 0, 0, 1, 0);
                     glMatrixMode(GL_MODELVIEW);
  
                     // render the terrain
                     Terrain.render();

                     glBindTexture(GL_TEXTURE_2D, shadowChunk);
                     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, lightmapChunkSize, lightmapChunkSize);

                     // disable projective texturing
                     glDisable(GL_TEXTURE_GEN_S);
                     glDisable(GL_TEXTURE_GEN_T);
                     glDisable(GL_TEXTURE_GEN_R);
                     glDisable(GL_TEXTURE_GEN_Q);

                     // reset texture matrix
                     glMatrixMode(GL_TEXTURE);
                     glLoadIdentity();
                     glMatrixMode(GL_MODELVIEW);

                     // get shadow texture data
                     glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);

                     for(int a = 0; a < lightmapChunkSize; a++)
                     {
                          for(int b = 0; b < lightmapChunkSize; b++)
                          {
                               int a2 = a + lightmapChunkSize * terrainRow;
                               int b2 = b + lightmapChunkSize * terrainCol;

                               lightmap[(a2 * lightmapSize + b2) * 3 + 0] = pixels[(a * lightmapChunkSize + b) * 3 + 0];
                               lightmap[(a2 * lightmapSize + b2) * 3 + 1] = pixels[(a * lightmapChunkSize + b) * 3 + 1];
                               lightmap[(a2 * lightmapSize + b2) * 3 + 2] = pixels[(a * lightmapChunkSize + b) * 3 + 2];
                          }
                     }
                 }
             }

             // increment which section on the terrain we are looking at
             x0 += terrainChunkSize;
             x1 += terrainChunkSize;
         }

         x0 = 0;
         x1 = terrainChunkSize;

         y0 += terrainChunkSize;
         y1 += terrainChunkSize;
     }

     // free memory
     glDeleteTextures(1, &shadowTexture);
     delete [] pixels;
}

5

主题

11

帖子

11

积分

新手上路

Rank: 1

积分
11
 楼主| 发表于 2009-12-17 20:32:00 | 显示全部楼层

Re:一个OpenGL的函数,哪位高人看看怎么在OGRE中实现~

谁能给讲一下大概实现的过程啊

5

主题

11

帖子

11

积分

新手上路

Rank: 1

积分
11
 楼主| 发表于 2009-12-17 20:32:00 | 显示全部楼层

Re:一个OpenGL的函数,哪位高人看看怎么在OGRE中实现~

谢谢楼

2

主题

15

帖子

19

积分

新手上路

Rank: 1

积分
19
发表于 2010-5-10 17:05:00 | 显示全部楼层

Re: 一个OpenGL的函数,哪位高人看看怎么在OGRE中实现~

看这个函数做什么了,如果是用glbegin(), glend()之类画点线面的,我知道可以使用ManualObject类似的来绘制,其他的函数我也想知道在ogre中的怎么实现的,貌似要好好研究ogre 源码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-9 17:52

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表