emscripten/tests/gl/sdl_ogl.c

191 строка
6.5 KiB
C
Исходник Обычный вид История

2010-12-22 09:41:24 +03:00
/*******************************************************************
* *
* Using SDL With OpenGL *
* *
* Tutorial by Kyle Foley (sdw) *
* *
* http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL *
* *
*******************************************************************/
/*
Combined with opengl.org tutorial #2,
http://www.opengl.org/wiki/Tutorial2:_VAOs,_VBOs,_Vertex_and_Fragment_Shaders_%28C_/_SDL%29
*/
#include "SDL/SDL.h"
#include "SDL/SDL_opengl.h"
#include <stdio.h>
char* filetobuf(char *file)
{
FILE *fptr;
long length;
char *buf;
fptr = fopen(file, "r"); /* Open file for reading */
if (!fptr) /* Return NULL on failure */
return NULL;
fseek(fptr, 0, SEEK_END); /* Seek to the end of the file */
length = ftell(fptr); /* Find out how many bytes into the file we are */
buf = (char*)malloc(length+1); /* Allocate a buffer for the entire length of the file and a null terminator */
fseek(fptr, 0, SEEK_SET); /* Go back to the beginning of the file */
fread(buf, length, 1, fptr); /* Read the contents of the file in to the buffer */
fclose(fptr); /* Close the file */
buf[length] = 0; /* Null terminator */
return buf; /* Return the buffer */
}
void drawscene()
{
int i; /* Simple iterator */
GLuint vao, vbo[2]; /* Create handles for our Vertex Array Object and two Vertex Buffer Objects */
/* We're going to create a simple diamond made from lines */
const GLfloat diamond[4][2] = {
{ 0.0, 1.0 }, /* Top point */
{ 1.0, 0.0 }, /* Right point */
{ 0.0, -1.0 }, /* Bottom point */
{ -1.0, 0.0 } }; /* Left point */
const GLfloat colors[4][3] = {
{ 1.0, 0.0, 0.0 }, /* Red */
{ 0.0, 1.0, 0.0 }, /* Green */
{ 0.0, 0.0, 1.0 }, /* Blue */
{ 1.0, 1.0, 1.0 } }; /* White */
/* These pointers will receive the contents of our shader source code files */
GLchar *vertexsource, *fragmentsource;
/* These are handles used to reference the shaders */
GLuint vertexshader, fragmentshader;
/* This is a handle to the shader program */
GLuint shaderprogram;
/* Allocate and assign a Vertex Array Object to our handle */
glGenVertexArrays(1, &vao);
/* Bind our Vertex Array Object as the current used object */
glBindVertexArray(vao);
/* Allocate and assign two Vertex Buffer Objects to our handle */
glGenBuffers(2, vbo);
/* Bind our first VBO as being the active buffer and storing vertex attributes (coordinates) */
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
/* Copy the vertex data from diamond to our buffer */
/* 8 * sizeof(GLfloat) is the size of the diamond array, since it contains 8 GLfloat values */
glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), diamond, GL_STATIC_DRAW);
/* Specify that our coordinate data is going into attribute index 0, and contains two floats per vertex */
glVertexAttribPointer((GLuint)0, 2, GL_FLOAT, GL_FALSE, 0, 0);
/* Enable attribute index 0 as being used */
glEnableVertexAttribArray(0);
/* Bind our second VBO as being the active buffer and storing vertex attributes (colors) */
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
/* Copy the color data from colors to our buffer */
/* 12 * sizeof(GLfloat) is the size of the colors array, since it contains 12 GLfloat values */
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), colors, GL_STATIC_DRAW);
/* Specify that our color data is going into attribute index 1, and contains three floats per vertex */
glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, 0);
/* Enable attribute index 1 as being used */
glEnableVertexAttribArray(1);
/* Read our shaders into the appropriate buffers */
vertexsource = filetobuf("tutorial2.vert");
fragmentsource = filetobuf("tutorial2.frag");
/* Assign our handles a "name" to new shader objects */
vertexshader = glCreateShader(GL_VERTEX_SHADER);
fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);
/* Associate the source code buffers with each handle */
glShaderSource(vertexshader, 1, (const GLchar**)&vertexsource, 0);
glShaderSource(fragmentshader, 1, (const GLchar**)&fragmentsource, 0);
/* Compile our shader objects */
glCompileShader(vertexshader);
glCompileShader(fragmentshader);
/* Assign our program handle a "name" */
shaderprogram = glCreateProgram();
/* Attach our shaders to our program */
glAttachShader(shaderprogram, vertexshader);
glAttachShader(shaderprogram, fragmentshader);
/* Bind attribute index 0 (coordinates) to in_Position and attribute index 1 (color) to in_Color */
glBindAttribLocation(shaderprogram, 0, "in_Position");
glBindAttribLocation(shaderprogram, 1, "in_Color");
/* Link our program, and set it as being actively used */
glLinkProgram(shaderprogram);
glUseProgram(shaderprogram);
/* Loop our display increasing the number of shown vertexes each time.
* Start with 2 vertexes (a line) and increase to 3 (a triangle) and 4 (a diamond) */
for (i=4; i <= 4; i++)
{
/* Make our background black */
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
/* Invoke glDrawArrays telling that our data is a line loop and we want to draw 2-4 vertexes */
glDrawArrays(GL_LINE_LOOP, 0, i);
/* Swap our buffers to make our changes visible */
SDL_GL_SwapBuffers();
/* Sleep for 2 seconds */
SDL_Delay(2000);
}
/* Cleanup all the things we bound and allocated */
glUseProgram(0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDetachShader(shaderprogram, vertexshader);
glDetachShader(shaderprogram, fragmentshader);
glDeleteProgram(shaderprogram);
glDeleteShader(vertexshader);
glDeleteShader(fragmentshader);
glDeleteBuffers(2, vbo);
glDeleteVertexArrays(1, &vao);
free(vertexsource);
free(fragmentsource);
}
int main(int argc, char *argv[])
{
SDL_Surface *screen;
// Slightly different SDL initialization
if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {
printf("Unable to initialize SDL: %s\n", SDL_GetError());
return 1;
}
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*
screen = SDL_SetVideoMode( 512, 384, 32, SDL_OPENGL); // *changed*
if ( !screen ) {
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}
drawscene();
SDL_Quit();
return 0;
}