First, I want to thank all the posters and repliers who have helped me get this far. A apologize for the length of the post, but I want to provide as much information as possible. If this is the wrong place for the post, please identify the correct forum. Thanks.
I am writing code to run on an embedded device. (i.MX6 via Phytec SOC). The supported graphics recipes are for EGL and GLESv2. Using the many posts from this and similar forums, I now have a program that can change the cleared display to a solid color (albeit with an unwanted cursor blinking). However, when I try to follow instructions to display a bitmap via a texture, no display change occurs. I’m hoping for guidance.
My “display” is the HDMI cable, which runs to a projector. When I boot, 4 Linux penguins are displayed, followed by the login prompt (which appears on my console also). When I log in, no updates occur on the display. I run two program, the code for which is below.
The first uses a regular window surface and “clears” the display to coral pink:
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <GLES/egl.h>
#include <GLES2/gl2.h>
#include <EGL/eglplatform.h>
#include "mat4x4.hpp"
#include "CoretronicsProjector.h"
#include "DebugLogOutputThread.h"
#include "Log.h"
#include "Image.h"
//The name of the video interface to use on the target is card0-HDMI-A-1 (/sys/class/drm)
int retval = 0;
const char * printableError()
{
EGLint error = eglGetError();
if (error == EGL_SUCCESS) return "No error";
if (error == EGL_BAD_DISPLAY) return "Bad display";
if (error == EGL_NOT_INITIALIZED) return "Not initialized";
if (error == EGL_BAD_CONFIG) return "Bad configuration";
if (error == EGL_BAD_NATIVE_WINDOW) return "Bad native window";
if (error == EGL_BAD_ATTRIBUTE) return "Bad attribute";
if (error == EGL_BAD_ALLOC) return "Bad alloc";
if (error == EGL_BAD_MATCH) return "Bad match";
if (error == EGL_BAD_SURFACE) return "Bad surface";
if (error == EGL_BAD_CONTEXT) return "Bad context";
if (error == EGL_BAD_ACCESS) return "Bad access";
if (error == EGL_BAD_NATIVE_PIXMAP) return "Bad native pixmap";
if (error == EGL_BAD_NATIVE_WINDOW) return "Bad native window";
if (error == EGL_BAD_CURRENT_SURFACE) return "Bad current surface";
if (error == EGL_CONTEXT_LOST) return "Context lost";
if (error == EGL_BAD_PARAMETER) return "Bad parameter";
return "Something else";
}
cv::Mat GetCroppedMat(int originx, int originy, int width, int height)
{
Image *testImage = new Image("/home/root/DuctWorkBlackWithText.png");
cv::Mat *bitmap = testImage->GetImagePtr();
std::cout << "Original bitmap = " << bitmap->cols << " x " << bitmap->rows << std::endl;
cv::Rect myROI(originx, originy, width, height);
return (*bitmap)(myROI);
}
int main(int argc, char *argv[])
{
cv::Mat croppedImage = GetCroppedMat(0, 0, 1024, 768);
//Setup to output to HDMI (default display)
int fbnum = 0;
EGLNativeDisplayType nativeDisplay = fbGetDisplayByIndex(fbnum);
EGLNativeWindowType nativeWindow = fbCreateWindow(nativeDisplay, 0, 0, 0, 0);
//Initialize display
EGLint major;
EGLint minor;
EGLDisplay display = eglGetDisplay(nativeDisplay);
if (display == EGL_NO_DISPLAY)
{
std::cout << "eglGetDisplay: " << printableError() << std::endl;
}
if (eglInitialize(display, &major, &minor))
{
std::cout << "eglInitialize returned true"<<std::endl;
}
else
{
std::cout << "eglInitialize: " << printableError() << std::endl;
}
eglBindAPI(EGL_OPENGL_ES_API);
std::cout << "eglBindAPI: " << printableError() << std::endl;
//Configure the display
EGLint num_config;
EGLint configAttrib[] =
{
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_NONE
};
EGLConfig config;
eglChooseConfig(display, configAttrib, &config, 1, &num_config);
std::cout << "eglChooseConfig: " << printableError() << std::endl;
//Get the display context
EGLint context_attrib[] =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attrib);
std::cout << "eglCreateContext: " << printableError() << std::endl;
//Get the surface
EGLSurface surface = eglCreateWindowSurface(display, config, nativeWindow, NULL);
if (surface == EGL_NO_SURFACE)
{
std::cout << "eglCreatePbufferSurface: " << printableError() << std::endl;
}
//Make the surface current
eglMakeCurrent(display, surface, surface, context);
std::cout << "eglMakeCurrent: " << printableError() << std::endl;
glClearColor((float)0xf8/0xff, (float)0x83/0xff, (float)0x79/0xff, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(display, surface);
std::cout << "eglSwapBuffers: " << printableError() << std::endl;
sleep(10);
eglTerminate(display);
return retval;
}
The output for this program is:
Original bitmap = 2560 x 1600
eglInitialize returned true
eglBindAPI: No error
eglChooseConfig: No error
eglCreateContext: No error
eglMakeCurrent: No error
eglSwapBuffers: No error
As I said, this program works.
The second is my attempt to display a bitmap via textures. It appears to do nothing, although it reports that all of the calls succeed:
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <GLES/egl.h>
#include <GLES2/gl2.h>
#include <EGL/eglplatform.h>
#include "mat4x4.hpp"
#include "CoretronicsProjector.h"
#include "DebugLogOutputThread.h"
#include "Log.h"
#include "Image.h"
//The name of the video interface to use on the target is card0-HDMI-A-1 (/sys/class/drm)
int retval = 0;
const char * printableError()
{
EGLint error = eglGetError();
if (error == EGL_SUCCESS) return "No error";
if (error == EGL_BAD_DISPLAY) return "Bad display";
if (error == EGL_NOT_INITIALIZED) return "Not initialized";
if (error == EGL_BAD_CONFIG) return "Bad configuration";
if (error == EGL_BAD_NATIVE_WINDOW) return "Bad native window";
if (error == EGL_BAD_ATTRIBUTE) return "Bad attribute";
if (error == EGL_BAD_ALLOC) return "Bad alloc";
if (error == EGL_BAD_MATCH) return "Bad match";
if (error == EGL_BAD_SURFACE) return "Bad surface";
if (error == EGL_BAD_CONTEXT) return "Bad context";
if (error == EGL_BAD_ACCESS) return "Bad access";
if (error == EGL_BAD_NATIVE_PIXMAP) return "Bad native pixmap";
if (error == EGL_BAD_NATIVE_WINDOW) return "Bad native window";
if (error == EGL_BAD_CURRENT_SURFACE) return "Bad current surface";
if (error == EGL_CONTEXT_LOST) return "Context lost";
if (error == EGL_BAD_PARAMETER) return "Bad parameter";
return "Something else";
}
cv::Mat GetCroppedMat(int originx, int originy, int width, int height)
{
Image *testImage = new Image("/home/root/DuctWorkBlackWithText.png");
cv::Mat *bitmap = testImage->GetImagePtr();
std::cout << "Original bitmap = " << bitmap->cols << " x " << bitmap->rows << std::endl;
cv::Rect myROI(originx, originy, width, height);
return (*bitmap)(myROI);
}
int main(int argc, char *argv[])
{
cv::Mat croppedImage = GetCroppedMat(0, 0, 1024, 768);
//Setup to output to HDMI (default display)
int fbnum = 0;
EGLNativeDisplayType nativeDisplay = fbGetDisplayByIndex(fbnum);
EGLNativeWindowType nativeWindow = fbCreateWindow(nativeDisplay, 0, 0, 0, 0);
//Initialize display
EGLint major;
EGLint minor;
EGLDisplay display = eglGetDisplay(nativeDisplay);
std::cout << "eglGetDisplay: " << printableError() << std::endl;
eglInitialize(display, &major, &minor);
std::cout << "eglInitialize: " << printableError() << std::endl;
eglBindAPI(EGL_OPENGL_ES_API);
std::cout << "eglBindAPI: " << printableError() << std::endl;
//Configure the display
EGLint num_config;
EGLint configPbufferAttrib[] =
{
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_BIND_TO_TEXTURE_RGB, EGL_PBUFFER_BIT,
EGL_NONE
};
EGLConfig config;
eglChooseConfig(display, configPbufferAttrib, &config, 1, &num_config);
std::cout << "eglChooseConfig: " << printableError() << std::endl;
//Get the display context
EGLint context_attrib[] =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attrib);
std::cout << "eglCreateContext: " << printableError() << std::endl;
//Get the surface (Pbuffer)
EGLint surfaceAttribs[] =
{
EGL_WIDTH, 1024,
EGL_HEIGHT, 1024,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,
EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
EGL_NONE
};
EGLSurface surface = eglCreatePbufferSurface(display, config, surfaceAttribs);
std::cout << "eglCreatePbufferSurface: " << printableError() << std::endl;
//Make the surface current
eglMakeCurrent(display, surface, surface, context);
std::cout << "eglMakeCurrent: " << printableError() << std::endl;
glClearColor((float)0x88/0xff, (float)0x83/0xff, (float)0x79/0xff, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
//TODO change from BGR to RGB
//Make a texture and bind to it
GLuint texture;
glGenTextures(1, &texture);
std::cout << "New texture = " << texture << std::endl;
glBindTexture(GL_TEXTURE_2D, texture);
if (glGetError() != GL_NO_ERROR)
{
std::cout << "glBindTexture generated error = " << (int)glGetError() << std::endl;
retval = -1;
}
//Attach input data to texture?
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, croppedImage.data);
if (glGetError() != GL_NO_ERROR)
{
std::cout << "glTexImage2D generated error = " << (int)glGetError() << std::endl;
retval = -1;
}
GLsizei width = croppedImage.cols;
GLsizei height = croppedImage.rows;
std::cout << "Width/height = " << width << ", " << height << std::endl;
//3rd and 4th parameters are offset into buffer. Use this for movement updates
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, croppedImage.data);
if (glGetError() != GL_NO_ERROR)
{
std::cout << "glTexSubImage2D generated error = " << (int)glGetError() << std::endl;
retval = -1;
}
//Set texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
if (glGetError() != GL_NO_ERROR)
{
std::cout << "glTexParameteri generated error = " << (int)glGetError() << std::endl;
retval = -1;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if (glGetError() != GL_NO_ERROR)
{
std::cout << "glTexParameteri generated error = " << (int)glGetError() << std::endl;
retval = -1;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
if (glGetError() != GL_NO_ERROR)
{
std::cout << "glTexParameteri generated error = " << (int)glGetError() << std::endl;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (glGetError() != GL_NO_ERROR)
{
std::cout << "glTexParameteri generated error = " << (int)glGetError() << std::endl;
}
//Try to display
eglBindTexImage(display, surface, EGL_BACK_BUFFER);
std::cout << "eglBindTexImage: " << printableError() << std::endl;
glEnable(GL_TEXTURE_2D);
sleep(3);
eglSwapBuffers(display, surface);
std::cout << "eglSwapBuffers: " << printableError() << std::endl;
sleep(10);
eglTerminate(display);
return retval;
}
The output for this program is
Original bitmap = 2560 x 1600
eglGetDisplay: No error
eglInitialize: No error
eglBindAPI: No error
eglChooseConfig: No error
eglCreateContext: No error
eglCreatePbufferSurface: No error
eglMakeCurrent: No error
New texture = 1
Width/height = 1024, 768
eglBindTexImage: No error
eglSwapBuffers: No error
This program runs to completion, but the display does not change. I assume I’m missing something, but I have no idea what.