194 lines
4.7 KiB
C++
194 lines
4.7 KiB
C++
#include <string>
|
|
#include <exception>
|
|
#include <stdexcept>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "gl_test.hpp"
|
|
#ifdef _WIN32
|
|
#include "wgl_test.hpp"
|
|
#else
|
|
#include "glx_test.hpp"
|
|
#endif
|
|
#include <GL/freeglut.h>
|
|
|
|
GLuint positionBufferObject;
|
|
GLuint program;
|
|
GLuint vao;
|
|
|
|
GLuint BuildShader(GLenum eShaderType, const std::string &shaderText)
|
|
{
|
|
GLuint shader = gl::CreateShader(eShaderType);
|
|
const char *strFileData = shaderText.c_str();
|
|
gl::ShaderSource(shader, 1, &strFileData, NULL);
|
|
|
|
gl::CompileShader(shader);
|
|
|
|
GLint status;
|
|
gl::GetShaderiv(shader, gl::COMPILE_STATUS, &status);
|
|
if (status == gl::FALSE_)
|
|
{
|
|
GLint infoLogLength;
|
|
gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &infoLogLength);
|
|
|
|
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
|
|
gl::GetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
|
|
|
|
const char *strShaderType = NULL;
|
|
switch(eShaderType)
|
|
{
|
|
case gl::VERTEX_SHADER: strShaderType = "vertex"; break;
|
|
// case gl::GEOMETRY_SHADER: strShaderType = "geometry"; break;
|
|
case gl::FRAGMENT_SHADER: strShaderType = "fragment"; break;
|
|
}
|
|
|
|
fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog);
|
|
delete[] strInfoLog;
|
|
|
|
throw std::runtime_error("Compile failure in shader.");
|
|
}
|
|
|
|
return shader;
|
|
}
|
|
|
|
|
|
void init()
|
|
{
|
|
gl::GenVertexArrays(1, &vao);
|
|
gl::BindVertexArray(vao);
|
|
|
|
const float vertexPositions[] = {
|
|
0.75f, 0.75f, 0.0f, 1.0f,
|
|
0.75f, -0.75f, 0.0f, 1.0f,
|
|
-0.75f, -0.75f, 0.0f, 1.0f,
|
|
};
|
|
|
|
gl::GenBuffers(1, &positionBufferObject);
|
|
gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
|
|
gl::BufferData(gl::ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, gl::STATIC_DRAW);
|
|
gl::BindBuffer(gl::ARRAY_BUFFER, 0);
|
|
|
|
const std::string vertexShader(
|
|
"#version 330\n"
|
|
"layout(location = 0) in vec4 position;\n"
|
|
"void main()\n"
|
|
"{\n"
|
|
" gl_Position = position;\n"
|
|
"}\n"
|
|
);
|
|
|
|
const std::string fragmentShader(
|
|
"#version 330\n"
|
|
"out vec4 outputColor;\n"
|
|
"void main()\n"
|
|
"{\n"
|
|
" outputColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n"
|
|
"}\n"
|
|
);
|
|
|
|
GLuint vertShader = BuildShader(gl::VERTEX_SHADER, vertexShader);
|
|
GLuint fragShader = BuildShader(gl::FRAGMENT_SHADER, fragmentShader);
|
|
|
|
program = gl::CreateProgram();
|
|
gl::AttachShader(program, vertShader);
|
|
gl::AttachShader(program, fragShader);
|
|
gl::LinkProgram(program);
|
|
|
|
GLint status;
|
|
gl::GetProgramiv (program, gl::LINK_STATUS, &status);
|
|
if (status == gl::FALSE_)
|
|
{
|
|
GLint infoLogLength;
|
|
gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &infoLogLength);
|
|
|
|
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
|
|
gl::GetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
|
|
fprintf(stderr, "Linker failure: %s\n", strInfoLog);
|
|
delete[] strInfoLog;
|
|
|
|
throw std::runtime_error("Shader could not be linked.");
|
|
}
|
|
}
|
|
|
|
//Called to update the display.
|
|
//You should call glutSwapBuffers after all of your rendering to display what you rendered.
|
|
//If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function.
|
|
void display()
|
|
{
|
|
gl::ClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
|
gl::Clear(gl::COLOR_BUFFER_BIT);
|
|
|
|
gl::UseProgram(program);
|
|
|
|
gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
|
|
gl::EnableVertexAttribArray(0);
|
|
gl::VertexAttribPointer(0, 4, gl::FLOAT, gl::FALSE_, 0, 0);
|
|
|
|
gl::DrawArrays(gl::TRIANGLES, 0, 3);
|
|
|
|
gl::DisableVertexAttribArray(0);
|
|
gl::UseProgram(0);
|
|
|
|
glutSwapBuffers();
|
|
}
|
|
|
|
//Called whenever the window is resized. The new window size is given, in pixels.
|
|
//This is an opportunity to call gl::Viewport or gl::Scissor to keep up with the change in size.
|
|
void reshape (int w, int h)
|
|
{
|
|
gl::Viewport(0, 0, (GLsizei) w, (GLsizei) h);
|
|
}
|
|
|
|
//Called whenever a key on the keyboard was pressed.
|
|
//The key is given by the ''key'' parameter, which is in ASCII.
|
|
//It's often a good idea to have the escape key (ASCII value 27) call glutLeaveMainLoop() to
|
|
//exit the program.
|
|
void keyboard(unsigned char key, int x, int y)
|
|
{
|
|
switch (key)
|
|
{
|
|
case 27:
|
|
glutLeaveMainLoop();
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
glutInit(&argc, argv);
|
|
|
|
int width = 500;
|
|
int height = 500;
|
|
unsigned int displayMode = GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL;
|
|
|
|
glutInitDisplayMode(displayMode);
|
|
glutInitContextVersion (3, 3);
|
|
glutInitContextProfile(GLUT_CORE_PROFILE);
|
|
glutInitWindowSize (width, height);
|
|
glutInitWindowPosition (300, 200);
|
|
glutCreateWindow (argv[0]);
|
|
|
|
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
|
|
|
|
gl::sys::CheckExtensions();
|
|
#ifdef _WIN32
|
|
wgl::sys::CheckExtensions(wglGetCurrentDC());
|
|
#endif
|
|
|
|
/*
|
|
if(gl::exts::var_EXT_texture_compression_s3tc)
|
|
printf("Yay!\n");
|
|
else
|
|
printf("Fooey.\n");
|
|
*/
|
|
init();
|
|
|
|
|
|
glutDisplayFunc(display);
|
|
glutReshapeFunc(reshape);
|
|
glutKeyboardFunc(keyboard);
|
|
glutMainLoop();
|
|
return 0;
|
|
}
|