Done this code a few times and never had this problem before. I know I am overlooking something simple but been messing with the code for 3 days and can't seem to make it work?
Feels to me like the shader is not loading the source code and i am getting no errors?
All ideas welcome!
Code: Select all
#include <iostream>
#include <bcm_host.h>
#include <EGL/egl.h>
#include <GLES2/gl2.h>
int main(int argc, char *argv[]) {
///////////////
// BCM SETUP //
///////////////
EGL_DISPMANX_WINDOW_T nativewindow;
uint32_t display_width;
uint32_t display_height;
//get the bcm setup
bcm_host_init();
//the variables
DISPMANX_ELEMENT_HANDLE_T dispman_element;
DISPMANX_DISPLAY_HANDLE_T dispman_display;
DISPMANX_UPDATE_HANDLE_T dispman_update;
DISPMANX_TRANSFORM_T dispman_trans;
VC_RECT_T dst_rect;
VC_RECT_T src_rect;
//create an EGL window surface, passing context width/height
int success = graphics_get_display_size(0 /* LCD */,
&display_width, &display_height);
if ( success < 0 )
{
return 1;
}
//You can hardcode the resolution here:
//display_width = 640;
//display_height = 480;
dst_rect.x = 0;
dst_rect.y = 0;
dst_rect.width = display_width;
dst_rect.height = display_height;
src_rect.x = 0;
src_rect.y = 0;
src_rect.width = display_width << 16;
src_rect.height = display_height << 16;
dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
dispman_update = vc_dispmanx_update_start( 0 );
dispman_element = vc_dispmanx_element_add ( dispman_update,
dispman_display, 0/*layer*/, &dst_rect, 0/*src*/,
&src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/,
0/*clamp*/, dispman_trans/*transform*/);
nativewindow.element = dispman_element;
nativewindow.width = display_width;
nativewindow.height = display_height;
vc_dispmanx_update_submit_sync( dispman_update );
///////////////
// EGL SETUP //
///////////////
EGLDisplay eglDisplay;
EGLSurface eglSurface;
EGLContext eglContext;
eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if(eglDisplay == EGL_NO_DISPLAY) {
return 2;
}
//initialise EGL
if(eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE) {
return 3;
}
//Create an EGL config for what we want
EGLConfig config;
EGLint numConfigs;
EGLint configs[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE
};
//Choose the config to use
if(eglChooseConfig(eglDisplay, configs, &config, 1, &numConfigs) == EGL_FALSE) {
return 4;
}
//tell EGL we are using OpenVG / OpenGL ES / OpenGL
//IMPORTANT THIS MUST BE DONE BEFORE CREATING THE CONTEXT!
if(eglBindAPI(EGL_OPENGL_ES_API) != EGL_TRUE) {
return 5;
}
//Now lets create the rendering context
eglContext = eglCreateContext(eglDisplay, config, EGL_NO_CONTEXT, NULL);
if(eglContext == EGL_NO_CONTEXT) {
return 6;
}
//Create the window surface
eglSurface = eglCreateWindowSurface(eglDisplay, config, &nativewindow, NULL);
if(eglSurface == EGL_NO_CONTEXT) {
return 7;
}
//make context current
if(eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE) {
return 8;
}
////////////////////
// CREATE SHADERS //
////////////////////
//create the shader objects
GLuint VShader = glCreateShader(GL_VERTEX_SHADER);
GLuint FShader = glCreateShader(GL_FRAGMENT_SHADER);
//our shader code later we will load this from a file
const GLchar *VCode = {"attribute vec2 position;void main() {gl_Positon = position;}"};
const GLchar *FCode = {"void main() {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}"};
//load shader source code
glShaderSource(VShader, 1, &VCode, NULL);
glShaderSource(FShader, 1, &FCode, NULL);
//debug print shader code to see it loaded?
GLchar *VSource = NULL;
GLchar *FSource = NULL;
glGetShaderSource(VShader, 1024, NULL, VSource);
glGetShaderSource(FShader, 1024, NULL, FSource);
std::cout << VSource << std::endl;
std::cout << FSource << std::endl;
//compile the shaders
glCompileShader(VShader);
glCompileShader(FShader);
//check for errors in both shaders
GLint status;
GLint logSize;
GLchar *log = NULL;
GLint size;
glGetShaderiv(VShader, GL_COMPILE_STATUS, &status);
if(status == GL_FALSE) {
std::cout << "Vertex Shader ERROR!" << std::endl;
glGetShaderiv(VShader, GL_INFO_LOG_LENGTH, &logSize);
std::cout << logSize << std::endl;
glGetShaderInfoLog(VShader, logSize, &size, log);
if(logSize > 1) {
std::cout << log << std::endl;
}
}
glGetShaderiv(FShader, GL_COMPILE_STATUS, &status);
if(status == GL_FALSE) {
std::cout << "Fragment Shader ERROR!" << std::endl;
glGetShaderiv(FShader, GL_INFO_LOG_LENGTH, &logSize);
log = new char[logSize];
glGetShaderInfoLog(FShader, logSize, &size, log);
if(logSize > 1) {
std::cout << log << std::endl;
}
}
//create shader program
GLuint program = glCreateProgram();
//attach the shaders
glAttachShader(program, VShader);
glAttachShader(program, FShader);
//now link the program
glLinkProgram(program);
//check program linked correctly
GLint proLog = 0;
glGetProgramiv(program, GL_LINK_STATUS, &proLog);
if(proLog == GL_FALSE) {
std::cout << "Error linking shader program!" << std::endl;
GLint logLen = 0;
GLchar *logInfo = NULL;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLen);
glGetProgramInfoLog(program, logLen, &logLen, logInfo);
if(logLen > 0) {
std::cout << logInfo << std::endl;
}
}
//set the program to be used
glUseProgram(program);
//finished with shades so now we can delete
glDeleteShader(VShader);
glDeleteShader(FShader);
///////////////////
// TRIANGLE DATA //
///////////////////
//the vertex data
GLfloat triangle[] = {-0.5, -0.5, 0.0, 0.5, 0.5, -0.5};
//create a buffer to store the data in GPU memory
GLuint triBuffer;
glGenBuffers(1, &triBuffer);
//tell GL which buffer we would like to work with?
glBindBuffer(GL_ARRAY_BUFFER, triBuffer);
//assign the data to the buffer
glBufferData(GL_ARRAY_BUFFER, 6*sizeof(GLfloat), triangle, GL_STATIC_DRAW);
//bind the attribute in vertex shader to index 0
glBindAttribLocation(program, 0, "position");
//tell GL how the data is stored?
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, triangle);
//tell GL which attrib we would like to use
glEnableVertexAttribArray(0);
////////////////////
// DRAWING & LOOP //
////////////////////
//Program loop
int count = 0;
//set the clear color
glClearColor(0.5, 0.5, 0.5, 1.0);
//assuming a vsync of 60hz here
while(count < 600) {
//clear the screen
glClear(GL_COLOR_BUFFER_BIT);
//lets draw our triangle
glDrawArrays(GL_TRIANGLES, 0, 3);
//swap the buffers
eglSwapBuffers(eglDisplay, eglSurface);
//Increment timer thinking 60hz refresh here
count++;
}
//////////////
// CLEAN UP //
//////////////
eglDestroySurface(eglDisplay, eglSurface);
eglDestroyContext(eglDisplay, eglContext);
eglTerminate(eglDisplay);
return 0;
}