3D programming with Klimt

以OpenGL 來講, 最有名大概就是MESA LIBRARY;
而OpenGL ES則是Vincent 3D LIBRARY了, 但這套似乎主要支援wince的環境,
如果要在linux上run, 應該還要下一翻苦工. 所以我選用了可以在linux上compile的 klimt 3D Library
雖然這套宣稱不是OpenGL ES library, 但是OpenGL ES大部份的function都可以使用
而這套library 的EGL 是建構在SDL 上的, 所以在執行之前, 需先在平台上準備好你的X和SDL


#Cross compiling SDL for arm...
 1. version:
        arm-linux-gcc v3.4.3
        SDL:SDL-1.2.13( http://www.libsdl.org/ )
        
 2. assuming installed path is /home/jacob/test
 3. configure:
        ./configure --build=i686 --host=arm-linux --prefix=/home/jacob/test --enable-static --enable-joystick=no --enable-cdrom=no --enable-alsa=no --disable-alsatest  --enable-esd=no --disable-esdtest --enable-pulseaudio=no --enable-arts=no --enable-nas=no  --enable-diskaudio=no --enable-mintaudio=no --enable-nasm=no --enable-altivec=no --enable-ipod=no --enable-video-dga=no --enable-video-photon=no --enable-video-carbon=no --enable-video-cocoa=no --enable-video-ps2gs=no --enable-video-svga=no --enable-video-xbios=no --enable-video-gem=no --enable-directx=no --enable-rpath; make; make install
        
 4. result:
     jacob@jacob-laptop:~/test/lib$ ls libSDL*
     libSDL-1.2.so.0  libSDL-1.2.so.0.11.2  libSDL.a  libSDL.la  libSDLmain.a  libSDL.so
               


SDL 目前安裝在/home/jacob/test裡, 下一步則是cross compiling klimt 3d library了,
不知道是不是gcc version的問題, 我必須做一些修改, 才能順利compiling


#decompressing the klimt 3d library
#Cross compiling klimt library for arm...
a. modify klimt-src-0.6.2/klimt/build/LinuxX11/Makefile:
      CXXFLAGS = -g -Wall -pipe -O3 -fPIC -funroll-all-loops -D_LINUX
      CXXFLAGS += -I/home/jacob/test/include -D_GNU_SOURCE=1 -D_REENTRANT # -D_USE_OLDRASTERIZER_    
      LFLAGS  = -shared -Wl,-soname,libKlimt.so.0 -L/home/jacob/test/lib -lSDL -lpthread
      LIBS     = -L/home/jacob/test/lib -Wl  -lSDL -lpthread -lm

b. modify klimt-src-0.6.2/klimt/src/Base/klVec3.h: 
   Line 127:
   
   //#ifdef GCC_295X
	friend const klVec3T operator+ (const klVec3T& left, const klVec3T& right);
	friend const klVec3T operator- (const klVec3T& left, const klVec3T& right);
   //#else
   //	friend const klVec3T operator+<> (const klVec3T& left, const klVec3T& right);
   //	friend const klVec3T operator-<> (const klVec3T& left, const klVec3T& right);
   //#endif // GCC_2.95.X

c. modify klimt-src-0.6.2/klimt/src/Base/klVec4.h:
   Line 137:
     //#ifdef GCC_295X
        friend const klVec4T operator+ (const klVec4T& left, const klVec4T& right);
        friend const klVec4T operator- (const klVec4T& left, const klVec4T& right);
     //#else
     //   friend const klVec4T operator+<> (const klVec4T& left, const klVec4T& right);
     //   friend const klVec4T operator-<> (const klVec4T& left, const klVec4T& right);
     //#endif // GCC_2.95.X

d. modify klimt-src-0.6.2/klimt/src/Base/klFloat_fixed.h:
    Line 164:
        klFloat_fixed& operator*=(double nV)    {  v = MATHBASE::multiply(v, MATHBASE::fixedFromDouble(nV));  return *this;  }
        klFloat_fixed& operator/=(double nV)    {  v = MATHBASE::divide(v, MATHBASE::fixedFromDouble(nV));  return *this;  }

e. cd klimt-src-0.6.2/klimt/build/LinuxX11/
      make CXX=arm-linux-g++
     
f. ls klimt-src-0.6.2/klimt/bin/:
   libKlimt.so  libKlimt.so.0  libKlimt.so.0.5  libKlimt.so.0.5.0
   
g. cp libKlimt.so  libKlimt.so.0  libKlimt.so.0.5  libKlimt.so.0.5.0 to /home/jacob/test/lib

h. cd klimt-src-0.6.2/klimt/test/simple_linux_x11
   modify Makefile:   
      CXXFLAGS = -g -Wall -pipe -O3 -fPIC -funroll-all-loops
      CXXFLAGS += -D_LINUX -I/home/jacob/test/include/SDL -I../../klimt/include
      LDFLAGS  = -L/home/jacob/test/lib -lKlimt -lSDL -lpthread

   modify simple.cpp
     1. comment "#include "glut.h" "
     2. Line 116:
          glutSolidCube -> klutSolidCube
          
   make CXX=arm-linux-g++        
          
i. copy  /home/jacob/test/lib to the specify direction in the target 


如此, 把剛剛編出來的klimt 和sdl library放到target上, 就可以跑一些OpenGL ES的程式啦~~

接下來, 來試試一些OpenGL ES的基本功能, 先試試畫線, 三角形以及方形,
令我訝異的是, 我無法畫點, 真不是哪裡出了錯:
My Makefile:


##
# Makefile for Unix
#
CXX      = arm-linux-g++
CXXFLAGS = -g -Wall -pipe -O3 -fPIC -funroll-all-loops
CXXFLAGS += -I/home/jacob/target/opengl/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT  -I../../klimt/include
LDFLAGS  = -lKlimt -L/home/jacob/target/opengl/lib  -lSDL -lpthread -L../../bin
LIBS     = -lKlimt -L/home/jacob/target/opengl/lib -Wl  -lSDL -lpthread -lm

TARGET = ./sample
OBJS = sample.o load_bmp.o

$(TARGET): $(OBJS)
	$(CXX) -o $(TARGET) $(LIBS) $(OBJS)

%.o: %.cpp
	$(CXX) $(CXXFLAGS) -c $< -o $@

demo: demo.o
	$(CXX) -o demo $(LIBS) demo.o
clean:
	rm -f $(OBJS) *.o sample

Source Code:


#include stdio.h
#include stdlib.h
#include stdio.h
#include string.h
#include math.h

#include SDL.h

#include "gl/gl.h"
#include "gl/glu.h"

#include "sample.h"

#define FixedFromFloat(x)   (GLfixed)( x * (1<<16))

void render()
{ 
    int i=0;
    GLfixed x,y,z;
    GLfloat sizes[2]; 
    GLfloat step;

    glClearColorx( 0, 0, 0, 1 );
    glColor3x( FixedFromFloat(1.0f), FixedFromFloat(1.0f), FixedFromFloat(1.0f) );          //draw green points
    glShadeModel(GL_FLAT);
 
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    
    glPolygonMode(GL_BACK,GL_LINE);
    glPolygonMode(GL_FRONT,GL_LINE);
    
    glViewport(0, 0, 640, 480);
	
    while(i<100){

        /* Gl_POINTS failed, I dont know why. It draws nothing */
        glBegin(GL_POINTS);               
            x =  FixedFromFloat(0.5f);
            y =  FixedFromFloat(0.9f);                                        
            glVertex3x( x, y, 0);
            glVertex3x( x, y+500, 0);               
        glEnd();
        
        /* Draws an oblique line in the X-Y+ region. */
        /* It is the same as  glVertex3f( -0.5f, 0.5f, 0.3f) 
           in the floating system. */
        glBegin(GL_LINES);               
            x =  -FixedFromFloat(0.5f);  //  (1<<16)*0.5
            y =  FixedFromFloat(0.5f);
            z =  FixedFromFloat(0.3f); 
            glVertex3x( 0, 0, 0);
            glVertex3x( x, y, z);
        glEnd();
        
        /* Draws an oblique LINE_STRIP in the X-Y- region. */
        glBegin(GL_LINE_STRIP);
            x =  -FixedFromFloat(0.5f);  
            y =  -FixedFromFloat(0.5f);
            z =  FixedFromFloat(0.3f);             
            glVertex3x( 0, 0, 0);
            glVertex3x( x, y, z);
            
            x =  -FixedFromFloat(0.33f);
            glVertex3x( x, y, z);
        glEnd();
        
        /* Draws triangles in the X+Y- region */
        glBegin(GL_TRIANGLES);
            x =  FixedFromFloat(0.0f); 
            y =  -FixedFromFloat(0.0f);
            z =  FixedFromFloat(0.0f);             
            glVertex3x( x, y, z);
            glVertex3x( x+FixedFromFloat(0.1f), y-FixedFromFloat(0.2f), z);
            glVertex3x( x+FixedFromFloat(0.2f), y, z);
        glEnd();      
        
        /* Draws triangle strip in the X+Y- region */
        glBegin(GL_TRIANGLE_STRIP);
            x =  FixedFromFloat(0.2f); 
            y =  -FixedFromFloat(0.2f);
            z =  FixedFromFloat(0.0f);             
            glVertex3x( x, y, z);
            glVertex3x( x+FixedFromFloat(0.1f), y-FixedFromFloat(0.2f), z);
            glVertex3x( x+FixedFromFloat(0.2f), y, z);
            glVertex3x( x+FixedFromFloat(0.3f), y-FixedFromFloat(0.2f), z);
        glEnd();     

        /* Draws triangle strip in the X+Y+ region */
        glBegin(GL_TRIANGLE_FAN);
            x =  FixedFromFloat(0.4f); 
            y =  FixedFromFloat(0.4f);
            z =  FixedFromFloat(0.0f);             
           
            glVertex3x( x, y, z);
            glVertex3x( x+FixedFromFloat(0.2f), y+FixedFromFloat(0.2f), z);
            glVertex3x( x+FixedFromFloat(0.4f), y-FixedFromFloat(0.1f), z);
            glVertex3x( x+FixedFromFloat(0.3f), y-FixedFromFloat(0.2f), z);
        glEnd();      
    
    
        /* Draws a rectangle in the X-Y+ region*/
        glBegin(GL_QUADS);
            x =  -FixedFromFloat(0.4f); 
            y =  FixedFromFloat(0.2f);

            glVertex3x( x, y, 0);
            glVertex3x( x, y-FixedFromFloat(0.2f), 0);
            glVertex3x( x-FixedFromFloat(0.2f), y-FixedFromFloat(0.2f), 0);
            glVertex3x( x-FixedFromFloat(0.2f), y, 0);
        glEnd();  
        
        //other types: GL_QUAD_STRIP, GL_POLYGON
        
        EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
        EGLDisplay display = eglGetCurrentDisplay();    
        eglSwapBuffers(display, surface);
        i++;
    }
}

int main(int argc, char *argv[])
{
    SDL_Surface *screen;
    SDL_Init(SDL_INIT_VIDEO);

    //create egl interface    
    screen=SDL_SetVideoMode(640,480,16,SDL_HWSURFACE|SDL_DOUBLEBUF);
    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    EGLint major, minor;

    eglInitialize(display, &major, &minor);
    
    EGLSurface sfc = eglCreateWindowSurface(display, 0, screen, 0);
    EGLContext ctx = eglCreateContext(display, 0, screen, 0);
    eglMakeCurrent(display, sfc, sfc, ctx);
    
    render();
    
    SDL_Quit();
	return 0;
}


以下是畫出來的結果:



而三角椎旋轉, 漸層色彩以及load background都正常





但是blend 功能實在是令人無法接受啊, 下圖我是想讓1個小黃色quard 和紅色的quard混合在一起


而且這套library居然不支持alpha, lighting和 frog的效果也十分不怎麼樣
不過物件texture的功能可以正常運行, 但如預期的, 只要物件一貼圖速度馬上慢了下來
一個場景應該不能畫太多elements

你可能感兴趣的:(3D programming with Klimt)