-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ARB_vertex_program / ARB_fragment_program example.
This is the old low-level shader API. This example is mainly just for reference. In practice you would rarely want to use this.
- Loading branch information
Showing
4 changed files
with
509 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
#include "../glbExamplesCommon.c" | ||
|
||
GLuint g_VertShader; | ||
GLuint g_FragShader; | ||
|
||
#define VERTEX_ATTRIB_POSITION 0 | ||
#define VERTEX_ATTRIB_COLOR 1 | ||
|
||
const void* vfs_map_file(const char* pFilePath, size_t* pFileSizeInBytes); | ||
|
||
static GLenum CreateShader(GLBexample* pExample, GLenum shaderTarget, const char* pShaderString, size_t shaderStringLength, GLuint* pShaderObject) | ||
{ | ||
GLuint shaderObject; | ||
GLint shaderErrorPos; | ||
|
||
/* Generate shader object. */ | ||
glGenProgramsARB(1, &shaderObject); | ||
glBindProgramARB(shaderTarget, shaderObject); | ||
|
||
/* Load and compile. */ | ||
glProgramStringARB(shaderTarget, GL_PROGRAM_FORMAT_ASCII_ARB, shaderStringLength, pShaderString); | ||
|
||
/* Check for any errors. */ | ||
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &shaderErrorPos); | ||
if (shaderErrorPos != -1) { | ||
printf("Error in %s shader at position %d: ", (shaderTarget == GL_VERTEX_PROGRAM_ARB) ? "vertex" : "fragment", shaderErrorPos); | ||
printf("%s\n", glGetString(GL_PROGRAM_ERROR_STRING_ARB)); | ||
return GL_INVALID_VALUE; | ||
} | ||
|
||
return GL_NO_ERROR; | ||
} | ||
|
||
static GLenum CreateShaders(GLBexample* pExample) | ||
{ | ||
GLenum result; | ||
const void* pVertShaderString; | ||
size_t vertShaderStringLen; | ||
const void* pFragShaderString; | ||
size_t fragShaderStringLen; | ||
|
||
pVertShaderString = vfs_map_file("VertexShader.txt", &vertShaderStringLen); | ||
if (pVertShaderString == NULL) { | ||
printf("Failed to load vertex shader.\n"); | ||
return GL_INVALID_VALUE; | ||
} | ||
|
||
pFragShaderString = vfs_map_file("FragmentShader.txt", &fragShaderStringLen); | ||
if (pVertShaderString == NULL) { | ||
printf("Failed to load fragment shader.\n"); | ||
return GL_INVALID_VALUE; | ||
} | ||
|
||
result = CreateShader(pExample, GL_VERTEX_PROGRAM_ARB, pVertShaderString, vertShaderStringLen, &g_VertShader); | ||
if (result != GL_NO_ERROR) { | ||
return result; | ||
} | ||
|
||
result = CreateShader(pExample, GL_FRAGMENT_PROGRAM_ARB, pFragShaderString, fragShaderStringLen, &g_FragShader); | ||
if (result != GL_NO_ERROR) { | ||
glDeleteProgramsARB(1, &g_VertShader); | ||
return result; | ||
} | ||
|
||
return GL_NO_ERROR; | ||
} | ||
|
||
GLenum onInit(GLBexample* pExample) | ||
{ | ||
GLenum result; | ||
|
||
/* We first need to check that we support ARB shaders. */ | ||
if (!glbIsExtensionSupported(&pExample->gl, "GL_ARB_vertex_program")) { | ||
printf("GL_ARB_vertex_program not supported.\n"); | ||
return GL_INVALID_OPERATION; | ||
} | ||
if (!glbIsExtensionSupported(&pExample->gl, "GL_ARB_fragment_program")) { | ||
printf("GL_ARB_fragment_program not supported.\n"); | ||
return GL_INVALID_OPERATION; | ||
} | ||
|
||
result = CreateShaders(pExample); | ||
if (result != GL_NO_ERROR) { | ||
return result; | ||
} | ||
|
||
/* Shaders have been created. Initialize some state. */ | ||
glEnable(GL_VERTEX_PROGRAM_ARB); | ||
glEnable(GL_FRAGMENT_PROGRAM_ARB); | ||
|
||
return GL_NO_ERROR; | ||
} | ||
|
||
void onDraw(GLBexample* pExample) | ||
{ | ||
glClearColor(0.2f, 0.5f, 0.8f, 0); | ||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | ||
|
||
/* We can now set the MVP matrix. In this example we always use the identity matrix, but in a real program you would make this a variable. */ | ||
glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 0, 1, 0, 0, 0); | ||
glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 1, 0, 1, 0, 0); | ||
glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 2, 0, 0, 1, 0); | ||
glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 3, 0, 0, 0, 1); | ||
|
||
glBegin(GL_TRIANGLES); | ||
{ | ||
glVertexAttrib3f(VERTEX_ATTRIB_COLOR, 1, 0, 0); | ||
glVertexAttrib2f(VERTEX_ATTRIB_POSITION, 0.0f, 0.5f); | ||
glVertexAttrib3f(VERTEX_ATTRIB_COLOR, 0, 1, 0); | ||
glVertexAttrib2f(VERTEX_ATTRIB_POSITION, -0.5f, -0.5f); | ||
glVertexAttrib3f(VERTEX_ATTRIB_COLOR, 0, 0, 1); | ||
glVertexAttrib2f(VERTEX_ATTRIB_POSITION, 0.5f, -0.5f); | ||
} | ||
glEnd(); | ||
} | ||
|
||
void onSize(GLBexample* pExample, GLsizei sizeX, GLsizei sizeY) | ||
{ | ||
pExample->gl.glViewport(0, 0, sizeX, sizeY); | ||
} | ||
|
||
int main(int argc, char** argv) | ||
{ | ||
GLenum result; | ||
GLBexampleconfig config; | ||
GLBexample example; | ||
|
||
glbZeroObject(&config); | ||
config.pGLBConfig = NULL; | ||
config.pUserData = NULL; | ||
config.onInit = onInit; | ||
config.onDraw = onDraw; | ||
config.onSize = onSize; | ||
|
||
result = glbExampleInit(&example, &config); | ||
if (result != GL_NO_ERROR) { | ||
printf("Failed to initialize example.\n"); | ||
return -1; | ||
} | ||
|
||
glbExampleRun(&example); | ||
|
||
/* Done. */ | ||
glbExampleUninit(&example); | ||
return 0; | ||
} | ||
|
||
|
||
static unsigned char g_vfsFileData[] = { | ||
0x21, 0x21, 0x41, 0x52, 0x42, 0x66, 0x70, 0x31, 0x2E, 0x30, 0x0A, 0x0A, 0x23, 0x20, 0x49, 0x6E, | ||
0x70, 0x75, 0x74, 0x73, 0x0A, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, 0x20, 0x69, 0x43, 0x6F, 0x6C, | ||
0x20, 0x3D, 0x20, 0x66, 0x72, 0x61, 0x67, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x74, 0x65, 0x78, 0x63, | ||
0x6F, 0x6F, 0x72, 0x64, 0x5B, 0x30, 0x5D, 0x3B, 0x0A, 0x0A, 0x23, 0x20, 0x4F, 0x75, 0x74, 0x70, | ||
0x75, 0x74, 0x73, 0x0A, 0x4F, 0x55, 0x54, 0x50, 0x55, 0x54, 0x20, 0x6F, 0x43, 0x6F, 0x6C, 0x20, | ||
0x3D, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x2E, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3B, 0x0A, | ||
0x0A, 0x4D, 0x4F, 0x56, 0x20, 0x6F, 0x43, 0x6F, 0x6C, 0x2C, 0x20, 0x69, 0x43, 0x6F, 0x6C, 0x3B, | ||
0x0A, 0x0A, 0x45, 0x4E, 0x44, 0x00, 0x00, 0x00, 0x21, 0x21, 0x41, 0x52, 0x42, 0x76, 0x70, 0x31, | ||
0x2E, 0x30, 0x0A, 0x0A, 0x23, 0x20, 0x49, 0x6E, 0x70, 0x75, 0x74, 0x73, 0x0A, 0x41, 0x54, 0x54, | ||
0x52, 0x49, 0x42, 0x20, 0x69, 0x50, 0x6F, 0x73, 0x20, 0x3D, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, | ||
0x78, 0x2E, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x5B, 0x30, 0x5D, 0x3B, 0x0A, 0x41, 0x54, 0x54, | ||
0x52, 0x49, 0x42, 0x20, 0x69, 0x43, 0x6F, 0x6C, 0x20, 0x3D, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, | ||
0x78, 0x2E, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x5B, 0x31, 0x5D, 0x3B, 0x0A, 0x0A, 0x23, 0x20, | ||
0x4F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x0A, 0x4F, 0x55, 0x54, 0x50, 0x55, 0x54, 0x20, 0x6F, | ||
0x50, 0x6F, 0x73, 0x20, 0x3D, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x2E, 0x70, 0x6F, 0x73, | ||
0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3B, 0x0A, 0x4F, 0x55, 0x54, 0x50, 0x55, 0x54, 0x20, 0x6F, 0x43, | ||
0x6F, 0x6C, 0x20, 0x3D, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x2E, 0x74, 0x65, 0x78, 0x63, | ||
0x6F, 0x6F, 0x72, 0x64, 0x5B, 0x30, 0x5D, 0x3B, 0x0A, 0x0A, 0x23, 0x20, 0x55, 0x6E, 0x69, 0x66, | ||
0x6F, 0x72, 0x6D, 0x73, 0x0A, 0x50, 0x41, 0x52, 0x41, 0x4D, 0x20, 0x6D, 0x76, 0x70, 0x5B, 0x34, | ||
0x5D, 0x20, 0x3D, 0x20, 0x7B, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x2E, 0x6C, 0x6F, | ||
0x63, 0x61, 0x6C, 0x5B, 0x30, 0x5D, 0x2C, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x2E, | ||
0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x5B, 0x31, 0x5D, 0x2C, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, | ||
0x6D, 0x2E, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x5B, 0x32, 0x5D, 0x2C, 0x20, 0x70, 0x72, 0x6F, 0x67, | ||
0x72, 0x61, 0x6D, 0x2E, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x5B, 0x33, 0x5D, 0x20, 0x7D, 0x3B, 0x0A, | ||
0x0A, 0x44, 0x50, 0x34, 0x20, 0x6F, 0x50, 0x6F, 0x73, 0x2E, 0x78, 0x2C, 0x20, 0x69, 0x50, 0x6F, | ||
0x73, 0x2C, 0x20, 0x6D, 0x76, 0x70, 0x5B, 0x30, 0x5D, 0x3B, 0x0D, 0x0A, 0x44, 0x50, 0x34, 0x20, | ||
0x6F, 0x50, 0x6F, 0x73, 0x2E, 0x79, 0x2C, 0x20, 0x69, 0x50, 0x6F, 0x73, 0x2C, 0x20, 0x6D, 0x76, | ||
0x70, 0x5B, 0x31, 0x5D, 0x3B, 0x0D, 0x0A, 0x44, 0x50, 0x34, 0x20, 0x6F, 0x50, 0x6F, 0x73, 0x2E, | ||
0x7A, 0x2C, 0x20, 0x69, 0x50, 0x6F, 0x73, 0x2C, 0x20, 0x6D, 0x76, 0x70, 0x5B, 0x32, 0x5D, 0x3B, | ||
0x0D, 0x0A, 0x44, 0x50, 0x34, 0x20, 0x6F, 0x50, 0x6F, 0x73, 0x2E, 0x77, 0x2C, 0x20, 0x69, 0x50, | ||
0x6F, 0x73, 0x2C, 0x20, 0x6D, 0x76, 0x70, 0x5B, 0x33, 0x5D, 0x3B, 0x0A, 0x0A, 0x4D, 0x4F, 0x56, | ||
0x20, 0x6F, 0x43, 0x6F, 0x6C, 0x2C, 0x20, 0x69, 0x43, 0x6F, 0x6C, 0x3B, 0x0A, 0x0A, 0x45, 0x4E, | ||
0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
}; | ||
|
||
typedef struct | ||
{ | ||
const char* pFilePath; | ||
size_t sizeInBytes; | ||
size_t dataOffsetInBytes; | ||
} vfs_file_data; | ||
|
||
static vfs_file_data g_vfsCentralDirectory[] = { | ||
{"FragmentShader.txt", 117, 0}, | ||
{"VertexShader.txt", 393, 120} | ||
}; | ||
|
||
static size_t vfs_find_file(const char* pFilePath) | ||
{ | ||
size_t iFile; | ||
|
||
if (pFilePath == NULL) { | ||
return (size_t)-1; | ||
} | ||
|
||
for (iFile = 0; iFile < sizeof(g_vfsCentralDirectory)/sizeof(g_vfsCentralDirectory[0]); iFile += 1) { | ||
int cmpresult = strcmp(g_vfsCentralDirectory[iFile].pFilePath, pFilePath); | ||
if (cmpresult == 0) { | ||
return iFile; | ||
} | ||
} | ||
|
||
return (size_t)-1; | ||
} | ||
|
||
const void* vfs_map_file(const char* pFilePath, size_t* pFileSizeInBytes) | ||
{ | ||
size_t iFile; | ||
|
||
if (pFileSizeInBytes != NULL) { | ||
*pFileSizeInBytes = 0; | ||
} | ||
|
||
iFile = vfs_find_file(pFilePath); | ||
if (iFile == (size_t)-1) { | ||
return NULL; | ||
} | ||
|
||
if (pFileSizeInBytes != NULL) { | ||
*pFileSizeInBytes = g_vfsCentralDirectory[iFile].sizeInBytes; | ||
} | ||
|
||
return &g_vfsFileData[g_vfsCentralDirectory[iFile].dataOffsetInBytes]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
!!ARBfp1.0 | ||
|
||
# Inputs | ||
ATTRIB iCol = fragment.texcoord[0]; | ||
|
||
# Outputs | ||
OUTPUT oCol = result.color; | ||
|
||
MOV oCol, iCol; | ||
|
||
END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
!!ARBvp1.0 | ||
|
||
# Inputs | ||
ATTRIB iPos = vertex.attrib[0]; | ||
ATTRIB iCol = vertex.attrib[1]; | ||
|
||
# Outputs | ||
OUTPUT oPos = result.position; | ||
OUTPUT oCol = result.texcoord[0]; | ||
|
||
# Uniforms | ||
PARAM mvp[4] = { program.local[0], program.local[1], program.local[2], program.local[3] }; | ||
|
||
DP4 oPos.x, iPos, mvp[0]; | ||
DP4 oPos.y, iPos, mvp[1]; | ||
DP4 oPos.z, iPos, mvp[2]; | ||
DP4 oPos.w, iPos, mvp[3]; | ||
|
||
MOV oCol, iCol; | ||
|
||
END |
Oops, something went wrong.