update: 2012/09/20
reference:
1. OpenGL® Application Binary Interface for Linux
2. Getting Started with the OpenGL Shading Language (GLSL)
3. I touchs: Setting up Eclipse for OpenGL on Linux Mint
4. I touchs: OpenGL: Basic Setup
5. Graphics Shaders: Theory and Practice, 2/e (Hardcover)
6. CSCI 4229/5229: Computer Graphics
> Fall 2012 > Handouts > Introduction to OpenGL
A. 說明:
1. 目的: 建立一個可供練習 GLSL 的基本專案架構, 包含 OpenGL 的繪圖流程,
shader 的處理(編譯, 附加, 連結, 變數存取....)等.
2. 開發環境:
作業系統: Linux Mint (基於 Ubuntu 的另一個 Linux 版本)
整合開發環境(IDE): Eclipse
程式語言: C, GLSL
3. 其它:
a. 本篇文章是延續上一篇 Setting up Eclipse for OpenGL on Linux Mint 而來,
一開始, 我先將 Getting Started with the OpenGL Shading Language 的
source code 下載下來, 因為是 C++ 專案的原因, 修改了變數轉型的問題
(參考: OpenGL: Starting with the Shading Language-0), 接著編譯就出現了
錯誤訊息: 無法解析有關處理 shader 的函式.
$ glxinfo | grep -i opengl
備註: "shading language version string: 4.30 NVIDIA via Cg compiler"
看來不是使用原生的 GLSL compiler, 不過我們是用程式去 compiler shader, 所以應該不會是問題所在.
c. 最後, 改成建立 C 專案(而非C++), 並作一些調整, 就可以正常編譯並執行了.
----------------------------------------------------------------------------
B. 新增 Eclipse 專案
1. 啓動 Eclipse:
Select a workspace > /home/lanli/workspace (預設) > OK
2. 新增 C 專案:
step 1:
File -> New -> C Project (或: Shift+ Alt + N > C Project)
step 2:
Project name: GLSL_base
Project type > Executable: Empty Project
Toolchains: Cross GCC (或 Linux GCC 亦可)
> Finish
1. 滑鼠右鍵點選
> Project Explorer 下的專案名稱(此處為: GLSL_base)
> Properties
2. C/C++ Build > Settings
Cross GCC Linker > Libraries
利用 "+" 新增以下的 Libraries: glut, GL, GLU
> OK
C. 加入用來處理 shader 的檔案
1. 下載 glsl_lighting-1.tar.gz 解壓縮後, 將 opengl.h 與 shader.c 複製到
專案目錄下(在此為: /home/lanli/workspace/GLSL_base)
2. 在 Eclipse 中, 點選此專案, 按下 "F5" 鍵來 Refresh, 使剛加入的檔案
出現在專案目錄裡.
#ifndef __OPENGL_H__
#define __OPENGL_H__
#define LINUX
//#define APPLE
#ifdef LINUX
#define GL_GLEXT_PROTOTYPES
#include <GL/glut.h>
#else
#ifdef APPLE
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#include <GLUT/glut.h>
#else
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/glut.h>
#endif /* APPLE */
#endif /* LINUX */
#endif /* __OPENGL_H__ */
說明: 主要修改 Linux 的部分:
a. 要先定義: GL_GLEXT_PROTOTYPES
b. 只需引入: <GL/glut.h>
----------------------------------------------------------------------------
D. 新增公用函式
1. File -> New -> Source File
Source file: utility.c
Template: <Default C source template> 或 <None>
> Finish
2. 開啟 utility.c 檔案, 修改如下:
/*
* utility.c
*
* Created on: 2012/9/13
* Author: lanli
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "opengl.h"
// 用來檢查 OpenGL 可能發生的錯誤問題
void checkGLErrors(const char* caller);
/*********************************************/
void checkGLErrors(const char* caller)
{
unsigned int gle = glGetError();
if(gle != GL_NO_ERROR)
{
fprintf(stderr, "GL Error discovered from caller %s: ", caller);
switch (gle)
{
case GL_INVALID_ENUM:
fprintf(stderr, "Invalid enum.\n");
break;
case GL_INVALID_VALUE:
fprintf(stderr, "Invalid value.\n");
break;
case GL_INVALID_OPERATION:
fprintf(stderr, "Invalid Operation.\n");
break;
case GL_STACK_OVERFLOW:
fprintf(stderr, "Stack overflow.\n");
break;
case GL_STACK_UNDERFLOW:
fprintf(stderr, "Stack underflow.\n");
break;
case GL_OUT_OF_MEMORY:
fprintf(stderr, "Out of memory.\n");
break;
case GL_INVALID_FRAMEBUFFER_OPERATION:
fprintf(stderr, "Framebuffer object is not complete.\n");
break;
}
return;
}
else
{
fprintf(stderr, "NO Error from caller: %s \n", caller);
}
return;
}
----------------------------------------------------------------------------
E. 新增 "場景繪製" 相關函式
1. File -> New -> Source File
Source file: scene.c
Template: <Default C source template> 或 <None>
> Finish
2. 開啟 scene.c 檔案, 修改如下:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "opengl.h"
/* shader functions defined in shader.c */
extern void shaderAttachFromFile(GLuint, GLenum, const char *);
void sceneInit();
void sceneRender();
void sceneCycle();
/***********************************************************/
void sceneInit()
{
//GLint result;
/* create program object and attach shaders */
/* link the program and make sure that there were no errors */
/* get uniform locations */
/* set up lights */
/* create 2D/3D object */
/* call the glutIdleFunc */
/* setup camera */
//glLoadIdentity();
}
void sceneRender()
{
//glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* enable program and set uniform variables */
/* render the 2D/3D object */
glColor3f(0.2, 0.4, 0.6);
glutWireTeapot(3);
/* disable program */
/* render each light */
glutSwapBuffers();
//glFlush();
}
void sceneCycle()
{
// refresh the screen
glutPostRedisplay();
}
----------------------------------------------------------------------------
F. 新增 main 主函式
1. File -> New -> Source File
Source file: main.c
Template: <Default C source template> 或 <None>
> Finish
2. 開啟 main.c 檔案, 修改如下:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "opengl.h"
static const int WINDOW_X = 0;
static const int WINDOW_Y = 0;
static const int WINDOW_WIDTH = 320;
static const int WINDOW_HEIGHT = 320;
/* checkGLErrors functions defined in utility.c */
extern void checkGLErrors(const char* caller);
/* scene functions defined in scene.c */
extern void sceneInit(void);
extern void sceneRender(void);
extern void sceneCycle(void);
static int g_window;
void glInit();
void keyboard(unsigned char key, int x, int y);
int main(int argc, char* argv[])
{
/* initialize GLUT */
glutInit(&argc, argv);
//glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition(WINDOW_X, WINDOW_Y);
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
g_window = glutCreateWindow("OpenGL Shading Language");
/* initialize GL */
glInit();
/* initialize scene */
sceneInit();
/* setup callbacks */
glutDisplayFunc(sceneRender);
glutIdleFunc(sceneCycle);
glutKeyboardFunc(keyboard);
//glutReshapeFunc(resize);
//glutSpecialFunc(special);
//glutMouseFunc(mouse);
/* check GL Errors */
checkGLErrors("main");
/* start GLUT main loop */
glutMainLoop();
return 0;
}
void glInit()
{
/* setup initial GL settings */
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
/* set projection matrix */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-5, 5, -5, 5, 5, 15);
// or setPerspective
glMatrixMode(GL_MODELVIEW);
gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
}
// User Input Callbacks
void keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case 27: /* escape */
glutDestroyWindow(g_window);
exit(0);
break;
case 'q': case 'Q':
glutDestroyWindow(g_window);
exit(EXIT_SUCCESS);
break;
case 'r': case 'R':
fprintf(stderr, "call glutPostRedisplay() \n");
// refresh the screen
glutPostRedisplay();
break;
}
}
----------------------------------------------------------------------------
G. 編譯並執行
功能選單:
Project > Build Project
Run > Run
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。