PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Shader für OpenGL - Beispielprogramm???


Einfachkrank
2004-09-20, 19:57:10
Hi,

ich interessiere mich dafür mal mit Shader zu experimentieren. Gewöhnlicherweiße programmiere ich in Visual C++ 6.0 Standard mit OpenGL. Habe allerdings keinen Plan, wie ich die unter OpenGL einstelle oder lade oder wie auch immer herbeizaubern kann :). Dazu wollt ich wissen, ob jemand en gutes Beispielprogramm hat das darstellt, wie irgendwas mit und ohne Shader aussieht um mal Vor- und Nachteil besser zu verstehen etc.

MFG Einfachkrank

Coda
2004-09-20, 19:59:28
ARB_fragment_program/ARB_vertex_program oder GLSL
Google hilft :)

Einfachkrank
2004-09-20, 20:13:32
Ist das jetzt ungefähr wie bei DirectX der Unterschied zwischen Vertex- und Pixelshadern?

Coda
2004-09-20, 20:18:09
Ich weiß nicht genau was du meinst, aber es ist ungefähr das gleiche, ja.

marco42
2004-09-20, 20:58:32
Ist das jetzt ungefähr wie bei DirectX der Unterschied zwischen Vertex- und Pixelshadern?

vertex_program/fragment_program ist eine low level shading language. ein fragment_program ist dass was unter direct3d ein pixel_shader ist. dass sind allerdings alles nur extensions. GLSL ist eine high level shading language, vergleichbar zu Cg oder HLSL, mit dem unterschied, dass sie im treiber liegt und direct auf die hardware angepasst werden kann. deswegen braucht es hier auch kein SM X.X. unter OpenGL 2 ist es im core, ansonsten ist es als extension verfuegbar. ein gutes buch darueber ist "the opengl shading language" von andy rust (orange book).

Corrail
2004-09-20, 22:23:05
Du könntest dir meinen Artikel bei Nehe über GLSL durchlesen
http://nehe.gamedev.net/data/articles/article.asp?article=21

Kommentare sind erwünscht ;)

Dann hätte ich für GLSL noch diese Seite zum anbieten:
http://www.clockworkcoders.com/oglsl/tutorials.html

Asmodeus
2004-09-21, 10:18:21
Um auch einfach mal etwas mit Shadern und Effekten herumzuspielen ist z.B. auch der ShaderDesigner ganz sinnvoll. Dort kannst Du einfache Shadereffekte in GLSL programmieren und ausprobieren, ohne gleich die ganze Implementationsarbeit bei Deinem eigenen Programm machen zu müssen.

Shader Designer (http://www.typhoonlabs.com/)

Gruss, Carsten.

mrdigital
2004-09-21, 10:22:58
Ich hab heute Nacht nur den Anfang des Artikels gelesen, aber das was ich bislang gelesen hab war echt super! Hast du noch mehr Artikel geschrieben?

Corrail
2004-09-21, 20:36:19
Ich hab heute Nacht nur den Anfang des Artikels gelesen, aber das was ich bislang gelesen hab war echt super! Hast du noch mehr Artikel geschrieben?

Danke für den positiven Feedback! ;)
Bis jetzt nur einen über Bump Mapping mit OpenGL Texture Environments (http://nehe.gamedev.net/data/articles/article.asp?article=20). Ich überlege aber eh noch einen Artikel zu schreiben, Advanced Bump Mapping oder sowas in die richtung.

Einfachkrank
2004-12-09, 15:27:46
*denthreadrauskram*

So, lang ist's her. Ich hab mal angefangen mich näher damit zu beschäftigen und stoße schon auf kleine Probleme. Zum einem weiß ich nicht wie ich mit der Extension GL_ARB_shading_language_100 umgehn soll. Also was für defines ich brauche und welche Funktionen... wie zum Beispiel bei GL_ARB_multitexture:

// ...
#define GL_TEXTURE28_ARB 0x84DC
#define GL_TEXTURE29_ARB 0x84DD
#define GL_TEXTURE30_ARB 0x84DE
#define GL_TEXTURE31_ARB 0x84DF

typedef GLvoid (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture);
typedef GLvoid (APIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture);
typedef GLvoid (APIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum texture, GLdouble s);
typedef GLvoid (APIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum texture, const GLdouble
// ...

Weiteren hab ich folgendes Problem - beim Aufruf der Funktion

glShaderSourceARB(my_vertex_shader, 1, &my_vertex_shader_source, NULL);

Der Compiler spuckt dann aus, dass der dritte Parameter in der Funktion "const char**" sein soll und nicht "char **" und ich raff das net...

Habt ihr da en paar Lösungen für mich?

MFG Einfachkrank

Corrail
2004-12-09, 15:37:00
Also die Extension GL_ARB_shading_language_100 zeigt dir nur, dass die OpenGL Shading Language unterstützt wird. Folgendes wäre vielleicht noch praktisch:
#define SHADING_LANGUAGE_VERSION_ARB 0x8B8C
Damit kannst du dann mit glGetString(SHADING_LANGUAGE_VERSION_ARB) die unterstützte GLSL Version angezeigt bekommen.

@Compilerfehler: Was ist my_vertex_shader_source bei dir? Wie hast du glShaderSourceARB definiert?

Asmodeus
2004-12-10, 10:57:21
Ich fand die Sache auch etwas tricky, bevor glShaderSourceARB() bei mir so richtig lief. Ich habe es etwa so gemacht:



char * VertexBuffer = NULL;
char * FragmentBuffer = NULL;

int Length;

GLhandleARB ProgramObject,VertexShaderObject,FragmentShaderObject;

// jetzt werden die ASCII-Shaderprogramme in die Buffer übertragen:

if((VertexBuffer = GetBuffer(VertexShader)) == NULL)
return false;

if((FragmentBuffer = GetBuffer(FragmentShader)) == NULL)
return false;

ProgramObject = glCreateProgramObjectARB();

VertexShaderObject = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
FragmentShaderObject = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);

Length = (int) strlen((const char *) VertexBuffer);
glShaderSourceARB(VertexShaderObject,1,(const char**) &VertexBuffer,&Length);

Length = (int) strlen((const char *) FragmentBuffer);
glShaderSourceARB(FragmentShaderObject,1,(const char**) &FragmentBuffer,&Length);

delete[] VertexBuffer;
delete[] FragmentBuffer;



Gruss, Carsten.

Einfachkrank
2004-12-10, 15:41:43
Servus, also die Compilerfehlermeldung hab ich auch wegbekommen in dem ich einfach konvertiert habe in 'const char **'. Das Programm läuft jetzt, nur es passiert nichts. Meine Kugel bleibt einfach weiß. Hier noch mal kompletter Code:

// shadertest.cpp

# include "shadertest.h"
# include "extension.h"

// -------------------------------------------------------------------------------

char *shader_src;
char *fragment_src;

GLenum program;
GLenum vertex_shader;
GLenum fragment_shader;

float rotX = 1.0f;
float rotY = 1.0f;
float rotZ = 1.0f;
float rotA = 0.0f;


# define VERTEX_SHADER "shader1.vs"
# define FRAGMENT_SHADER "shader1.fs"
# define SCR_WIDTH 800
# define SCR_HEIGHT 600

// -------------------------------------------------------------------------------
// -------------------------------------------------------------------------------
char *GetShaderSrc(char *src)
{
FILE *file;
char buffer[1000];
char *str = NULL;
int idx = 0;

file = fopen(src, "r");
if(!file) return NULL;

do
{
fread(&buffer[idx], 1, sizeof(char), file);
idx++;
}
while(buffer[idx] != EOF);

if(idx > 1)
{
str = new char[idx];
strcpy(str, buffer);
return str;
}

return 0;
}

// -------------------------------------------------------------------------------
// -------------------------------------------------------------------------------
void Render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

gluLookAt(0.0f,0.0f,1.0f, 0.0f,0.0f,0.0f, 0.0f,1.0f,0.0f);

glRotatef(rotA, rotX, rotY, rotZ);

rotA += 0.1f;

glutSolidSphere(0.2f, 15, 15);

glutSwapBuffers();
}

// -------------------------------------------------------------------------------
void GLUTCALLBACK Loop(void)
{
Render();
}

// -------------------------------------------------------------------------------
bool InitProg(void)
{
// ************** init extensions **************
if(!InitExtensions()) return false;

// ************** setup opengl standard stuff **************
glClearColor(0.0f, 0.0f, 0.15f, 1.0f);
glEnable(GL_DEPTH_TEST);
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluPerspective(45.0f, (float)SCR_WIDTH/(float)SCR_HEIGHT, 0.1f, 50.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

gluLookAt(0.0f,0.0f,1.0f, 0.0f,0.0f,0.0f, 0.0f,1.0f,0.0f);

// ************** initialize shader work **************
shader_src = GetShaderSrc(VERTEX_SHADER);
fragment_src = GetShaderSrc(FRAGMENT_SHADER);
if((!shader_src) || (!fragment_src)) return false;

program = glCreateProgramObjectARB();
vertex_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
fragment_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);

glShaderSourceARB(vertex_shader, 1, (const char **)&shader_src, NULL);
glShaderSourceARB(fragment_shader, 1, (const char **)&fragment_src, NULL);

glCompileShaderARB(vertex_shader);
glCompileShaderARB(fragment_shader);

glAttachObjectARB(program, vertex_shader);
glAttachObjectARB(program, fragment_shader);

glLinkProgramARB(program);

glUseProgramObjectARB(program);

return true;
}

// -------------------------------------------------------------------------------
// -------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinst, LPSTR lpcmdline, int nshowcmd)
{
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition(50, 50);
glutInitWindowSize(SCR_WIDTH, SCR_HEIGHT);
glutCreateWindow("shader_testprog");

if(!InitProg()) return 0;

glutDisplayFunc(Loop);
glutIdleFunc(Loop);

glutMainLoop();

if(shader_src) delete shader_src;
if(fragment_src) delete fragment_src;
// quit() ???

return 0;
}

// -------------------------------------------------------------------------------
// -------------------------------------------------------------------------------

Und hier die Shaderdateien:

// shader1.vs
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

// shader1.fs
void main()
{
gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
}

Asmodeus
2004-12-10, 15:59:51
Servus, also die Compilerfehlermeldung hab ich auch wegbekommen in dem ich einfach konvertiert habe in 'const char **'. Das Programm läuft jetzt, nur es passiert nichts. Meine Kugel bleibt einfach weiß. Hier noch mal kompletter Code:

...
glShaderSourceARB(vertex_shader, 1, (const char **)&shader_src, NULL);
glShaderSourceARB(fragment_shader, 1, (const char **)&fragment_src, NULL);
...



Der letzte Parameter bei glShaderSourceARB() übergibt doch die Länge des übergebenen Char-Feldes, ich glaube, dort NULL anzugeben ist der Fehler.

Sinnvoll ist es außerdem, sich beim Kompilieren und Linken das InfoLog ausgeben zu lassen, um auf weitere Fehler aufmerksam gemacht zu werden.

Gruss, Carsten.

Einfachkrank
2004-12-10, 16:33:39
Haha, nee Update. Anscheinend hat meine Funktion zum Einlesen der Quelltexte für Shader nicht richtig funktioniert... Hab sie komplett neu geschrieben und nun funktioniert alles bestens. Trotzdem danke!

mein erster Shader *freu* :)