PDA

View Full Version : Moving the display window from (0,0) or top of screen to (x,y)



mcprakash
04-19-2015, 09:24 PM
Hi Everyone
I am using OpenGL ES 2.0 on the Raspberry Pi to print the raspi-cam image on the screen. The image is starting at (0,0) and I want it to start at some point (x,y)=(320,180). Please help me out.

My pseudocode looks like this

Working Code:


dst_rect.x=0
dst_rect.y=0
dst_rect.width=Width
dst_rect.height=Height

src_rect.x=0
src_rect.y=0
src_rect.width=Width
src_rect.height=Height

dispman_element=vc_dispmanx_element_add(dispman_up date,dispman_display,0,&dst_rect, 0,&src_rect,DISPMANX_PROTECTION_NONE,0,0,(DISPMANX_TR ANSFORM_T)0);

When I change this, the window moves as expected but the image is not being displayed.


dst_rect.x=320
dst_rect.y=180
dst_rect.width=Width
dst_rect.height=Height


Please help me out. :)

Chandra:tired

Alfonse Reinheart
04-19-2015, 10:18 PM
Where is the OpenGL ES code here?

mcprakash
04-19-2015, 10:46 PM
Hi
The complete code lools something like this

graphics.cpp



#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <unistd.h>
#include <iostream>
#include "bcm_host.h"
#include "graphics.h"

#define W_dst 1280
#define H_dst 720

#define check() assert(glGetError() == 0)

uint32_t GScreenWidth;
uint32_t GScreenHeight;
EGLDisplay GDisplay;
EGLSurface GSurface;
EGLContext GContext;

GfxShader GSimpleVS;
GfxShader GSimpleFS;
GfxShader GYUVFS;

GfxProgram GSimpleProg;
GfxProgram GYUVProg;

GLuint GQuadVertexBuffer;

void InitGraphics()
{
bcm_host_init();
int32_t success = 0;
EGLBoolean result;
EGLint num_config;

static EGL_DISPMANX_WINDOW_T nativewindow;

DISPMANX_ELEMENT_HANDLE_T dispman_element;
DISPMANX_DISPLAY_HANDLE_T dispman_display;
DISPMANX_UPDATE_HANDLE_T dispman_update;
VC_RECT_T dst_rect;
VC_RECT_T src_rect;

static const EGLint attribute_list[] =
{
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE
};

static const EGLint context_attributes[] =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
EGLConfig config;

// get an EGL display connection
GDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert(GDisplay!=EGL_NO_DISPLAY);
check();

// initialize the EGL display connection
result = eglInitialize(GDisplay, NULL, NULL);
assert(EGL_FALSE != result);
check();

// get an appropriate EGL frame buffer configuration
result = eglChooseConfig(GDisplay, attribute_list, &config, 1, &num_config);
assert(EGL_FALSE != result);
check();

// get an appropriate EGL frame buffer configuration
result = eglBindAPI(EGL_OPENGL_ES_API);
assert(EGL_FALSE != result);
check();

// create an EGL rendering context
GContext = eglCreateContext(GDisplay, config, EGL_NO_CONTEXT, context_attributes);
assert(GContext!=EGL_NO_CONTEXT);
check();

// create an EGL window surface
success = graphics_get_display_size(0 /* LCD */, &GScreenWidth, &GScreenHeight);
assert( success >= 0 );

dst_rect.x = 0;
dst_rect.y = 0;
dst_rect.width = W_dst;
dst_rect.height = H_dst;

src_rect.x = 0;
src_rect.y = 0;
src_rect.width = W_dst ;
src_rect.height = H_dst;

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*/, (DISPMANX_TRANSFORM_T)0/*transform*/);

nativewindow.element = dispman_element;
nativewindow.width = W_dst;
nativewindow.height = H_dst;
vc_dispmanx_update_submit_sync( dispman_update );

check();

GSurface = eglCreateWindowSurface( GDisplay, config, &nativewindow, NULL );
assert(GSurface != EGL_NO_SURFACE);
check();

// connect the context to the surface
result = eglMakeCurrent(GDisplay, GSurface, GSurface, GContext);
assert(EGL_FALSE != result);
check();

// Set background color and clear buffers
glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
glClear( GL_COLOR_BUFFER_BIT );

//load the test shaders
GSimpleVS.LoadVertexShader("shaders/simplevertshader.glsl");
GSimpleFS.LoadFragmentShader("shaders/simplefragshader.glsl");
GYUVFS.LoadFragmentShader("shaders/yuvfragshader.glsl");

GSimpleProg.Create(&GSimpleVS,&GSimpleFS);
GYUVProg.Create(&GSimpleVS,&GYUVFS);
check();

//create an ickle vertex buffer
static const GLfloat quad_vertex_positions[] = {
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f
};
glGenBuffers(1, &GQuadVertexBuffer);
check();
glBindBuffer(GL_ARRAY_BUFFER, GQuadVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertex_positions), quad_vertex_positions, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
check();
}

void BeginFrame()
{
// Prepare viewport
glViewport ( 0, 0, W_dst, H_dst );
check();

// Clear the background
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
check();
}

void EndFrame()
{
eglSwapBuffers(GDisplay,GSurface);
check();
}

void ReleaseGraphics()
{

}

// printShaderInfoLog
// From OpenGL Shading Language 3rd Edition, p215-216
// Display (hopefully) useful error messages if shader fails to compile
void printShaderInfoLog(GLint shader)
{
int infoLogLen = 0;
int charsWritten = 0;
GLchar *infoLog;

glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);

if (infoLogLen > 0)
{
infoLog = new GLchar[infoLogLen];
// error check for fail to allocate memory omitted
glGetShaderInfoLog(shader, infoLogLen, &charsWritten, infoLog);
std::cout << "InfoLog : " << std::endl << infoLog << std::endl;
delete [] infoLog;
}
}

bool GfxShader::LoadVertexShader(const char* filename)
{
//cheeky bit of code to read the whole file into memory
assert(!Src);
FILE* f = fopen(filename, "rb");
assert(f);
fseek(f,0,SEEK_END);
int sz = ftell(f);
fseek(f,0,SEEK_SET);
Src = new GLchar[sz+1];
fread(Src,1,sz,f);
Src[sz] = 0; //null terminate it!
fclose(f);

//now create and compile the shader
GlShaderType = GL_VERTEX_SHADER;
Id = glCreateShader(GlShaderType);
glShaderSource(Id, 1, (const GLchar**)&Src, 0);
glCompileShader(Id);
check();

//compilation check
GLint compiled;
glGetShaderiv(Id, GL_COMPILE_STATUS, &compiled);
if(compiled==0)
{
printf("Failed to compile vertex shader %s:\n%s\n", filename, Src);
printShaderInfoLog(Id);
glDeleteShader(Id);
return false;
}
else
{
//printf("Compiled vertex shader %s:\n%s\n", filename, Src);
printf("Compiled vertex shader %s:\n", filename);
}

return true;
}

bool GfxShader::LoadFragmentShader(const char* filename)
{
//cheeky bit of code to read the whole file into memory
assert(!Src);
FILE* f = fopen(filename, "rb");
assert(f);
fseek(f,0,SEEK_END);
int sz = ftell(f);
fseek(f,0,SEEK_SET);
Src = new GLchar[sz+1];
fread(Src,1,sz,f);
Src[sz] = 0; //null terminate it!
fclose(f);

//now create and compile the shader
GlShaderType = GL_FRAGMENT_SHADER;
Id = glCreateShader(GlShaderType);
glShaderSource(Id, 1, (const GLchar**)&Src, 0);
glCompileShader(Id);
check();

//compilation check
GLint compiled;
glGetShaderiv(Id, GL_COMPILE_STATUS, &compiled);
if(compiled==0)
{
printf("Failed to compile fragment shader %s:\n%s\n", filename, Src);
printShaderInfoLog(Id);
glDeleteShader(Id);
return false;
}
else
{
//printf("Compiled fragment shader %s:\n%s\n", filename, Src);
printf("Compiled fragment shader %s:\n", filename);
}

return true;
}

bool GfxProgram::Create(GfxShader* vertex_shader, GfxShader* fragment_shader)
{
VertexShader = vertex_shader;
FragmentShader = fragment_shader;
Id = glCreateProgram();
glAttachShader(Id, VertexShader->GetId());
glAttachShader(Id, FragmentShader->GetId());
glLinkProgram(Id);
check();
printf("Created program id %d from vs %d and fs %d\n", GetId(), VertexShader->GetId(), FragmentShader->GetId());

// Prints the information log for a program object
char log[1024];
glGetProgramInfoLog(Id,sizeof log,NULL,log);
printf("%d:program:\n%s\n", Id, log);

return true;
}

void DrawTextureRect(GfxTexture* texture, float x0, float y0, float x1, float y1)
{
glUseProgram(GSimpleProg.GetId());
check();

//float scale_mat[4]={x1-x0,y1-y0,y1-y0,x1-x0};

glUniform2f(glGetUniformLocation(GSimpleProg.GetId (),"offset"),x0,y0);
glUniform2f(glGetUniformLocation(GSimpleProg.GetId (),"scale"),x1-x0,y1-y0);
//glUniformMatrix2fv(glGetUniformLocation(GSimplePro g.GetId(),"scale"),1,false,scale_mat);
glUniform1i(glGetUniformLocation(GSimpleProg.GetId (),"tex"), 0);
check();

glBindBuffer(GL_ARRAY_BUFFER, GQuadVertexBuffer);
check();

glBindTexture(GL_TEXTURE_2D,texture->GetId());
check();

GLuint loc = glGetAttribLocation(GSimpleProg.GetId(),"vertex");
check();

glVertexAttribPointer(loc, 4, GL_FLOAT, 0, 16, 0);
check();

glEnableVertexAttribArray(loc);
check();

glDrawArrays ( GL_TRIANGLE_STRIP, 0, 4 );
check();

glFinish();
check();

glFlush();
check();

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);

}



void DrawTextureRect(GfxTexture* texture, float x0, float y0, float x1, float y1, GfxTexture* render_target)
{
if(render_target)
{
glBindFramebuffer(GL_FRAMEBUFFER,render_target->GetFramebufferId());
glViewport ( 0, 0, render_target->GetWidth(), render_target->GetHeight() );
check();
}

glUseProgram(GSimpleProg.GetId()); check();

glUniform2f(glGetUniformLocation(GSimpleProg.GetId (),"offset"),x0,y0);
glUniform2f(glGetUniformLocation(GSimpleProg.GetId (),"scale"),x1-x0,y1-y0);
glUniform1i(glGetUniformLocation(GSimpleProg.GetId (),"tex"), 0);
check();

glBindBuffer(GL_ARRAY_BUFFER, GQuadVertexBuffer); check();
glBindTexture(GL_TEXTURE_2D,texture->GetId()); check();

GLuint loc = glGetAttribLocation(GSimpleProg.GetId(),"vertex");
glVertexAttribPointer(loc, 4, GL_FLOAT, 0, 16, 0); check();
glEnableVertexAttribArray(loc); check();
glDrawArrays ( GL_TRIANGLE_STRIP, 0, 4 ); check();

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
if(render_target)
{
//glFinish(); check();
//glFlush(); check();
glBindFramebuffer(GL_FRAMEBUFFER,0);
glViewport ( 0, 0, W_dst, H_dst );
}
}


void DrawYUVTextureRect(GfxTexture* ytexture, GfxTexture* utexture, GfxTexture* vtexture, GfxTexture* render_target)
{
if(render_target)
{
glBindFramebuffer(GL_FRAMEBUFFER,render_target->GetFramebufferId());
glViewport ( 0, 0, render_target->GetWidth(), render_target->GetHeight() );
check();
}

glUseProgram(GYUVProg.GetId()); check();

glUniform2f(glGetUniformLocation(GYUVProg.GetId(),"offset"),-1,-1);
glUniform2f(glGetUniformLocation(GYUVProg.GetId(),"scale"),2,2);
glUniform1i(glGetUniformLocation(GYUVProg.GetId(),"tex0"), 0);
glUniform1i(glGetUniformLocation(GYUVProg.GetId(),"tex1"), 1);
glUniform1i(glGetUniformLocation(GYUVProg.GetId(),"tex2"), 2);
check();

glBindBuffer(GL_ARRAY_BUFFER, GQuadVertexBuffer); check();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,ytexture->GetId()); check();
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,utexture->GetId()); check();
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D,vtexture->GetId()); check();
glActiveTexture(GL_TEXTURE0);

GLuint loc = glGetAttribLocation(GYUVProg.GetId(),"vertex");
glVertexAttribPointer(loc, 4, GL_FLOAT, 0, 16, 0); check();
glEnableVertexAttribArray(loc); check();
glDrawArrays ( GL_TRIANGLE_STRIP, 0, 4 ); check();

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);

if(render_target)
{
//glFinish(); check();
//glFlush(); check();
glBindFramebuffer(GL_FRAMEBUFFER,0);
glViewport ( 0, 0, W_dst, H_dst );
}

}


bool GfxTexture::CreateRGBA(int width, int height, const void* data)
{
Width = width;
Height = height;
glGenTextures(1, &Id);
check();
glBindTexture(GL_TEXTURE_2D, Id);
check();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
check();
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
check();
glBindTexture(GL_TEXTURE_2D, 0);
IsRGBA = true;
return true;
}

bool GfxTexture::CreateGreyScale(int width, int height, const void* data)
{
Width = width;
Height = height;
glGenTextures(1, &Id);
check();
glBindTexture(GL_TEXTURE_2D, Id);
check();
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, Width, Height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
check();
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
check();
glBindTexture(GL_TEXTURE_2D, 0);
IsRGBA = false;
return true;
}

bool GfxTexture::GenerateFrameBuffer()
{
//Create a frame buffer that points to this texture
glGenFramebuffers(1,&FramebufferId);
check();
glBindFramebuffer(GL_FRAMEBUFFER,FramebufferId);
check();
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATT ACHMENT0,GL_TEXTURE_2D,Id,0);
check();
glBindFramebuffer(GL_FRAMEBUFFER,0);
check();
return true;
}

void GfxTexture::SetPixels(const void* data)
{
glBindTexture(GL_TEXTURE_2D, Id);
check();
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, Width, Height, IsRGBA ? GL_RGBA : GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
check();
glBindTexture(GL_TEXTURE_2D, 0);
check();
}



main.cpp






// <------------------------------------------------ Common Libraries ---------------------------------------------->
#include <stdio.h>
#include <unistd.h>
#include <curses.h>
#include <iostream>
#include <fstream>

// <------------------------------------------------ Camera Libraries ---------------------------------------------->
#include "camera.h"
#include "graphics.h"

// <------------------------------------------------ Eigen Libraries ---------------------------------------------->
#include <eigen3/Eigen/Dense>

// <------------------------------------------------ OpenCV Libraries ---------------------------------------------->
#include <opencv2/opencv.hpp>

// <------------------------------------------------ SO3 Functions ---------------------------------------------->
#include "so3.h"

// <------------------------------------------------ Include Namespaces ---------------------------------------------->
using namespace std;
using namespace cv;
using namespace Eigen;

// <------------------------------------------------ Camera Properties ---------------------------------------------->
#define MAIN_TEXTURE_WIDTH 1280
#define MAIN_TEXTURE_HEIGHT 720

#define W_img 1280
#define H_img 720

// <------------------------------------------------ Variables ---------------------------------------------->

// <-----------OpenGL Tex Variables ------------->
int frame_sz;
int ypitch, ysize, uvpitch, uvsize, upos, vpos;
float tdiff;

// <-----------Loop Variables------------->
int i=0,j=0;
int img_cnt=0;

// <------------------------------------------------ Main Function ---------------------------------------------->

int main(int argc, const char **argv)
{

// <------------------------------------------------ Initialize SO3 Functions ---------------------------------------------->
init_SO3();

// <------------------------------------------------ Initialize Camera and graphics ---------------------------------------------->
InitGraphics();
CCamera* cam = StartCamera(MAIN_TEXTURE_WIDTH, MAIN_TEXTURE_HEIGHT,10,1,false);

// <------------------------------------------------ Generate textures for image processing in OpenGL ---------------------------------------------->
GfxTexture ytexture,utexture,vtexture,tex, gray, hsv;
ytexture.CreateGreyScale(MAIN_TEXTURE_WIDTH,MAIN_T EXTURE_HEIGHT);
utexture.CreateGreyScale(MAIN_TEXTURE_WIDTH/2,MAIN_TEXTURE_HEIGHT/2);
vtexture.CreateGreyScale(MAIN_TEXTURE_WIDTH/2,MAIN_TEXTURE_HEIGHT/2);

tex.CreateRGBA(MAIN_TEXTURE_WIDTH/2,MAIN_TEXTURE_HEIGHT/2);
tex.GenerateFrameBuffer();

printf("Running frame loop\n");
const void* frame_data;
const uint8_t* data;

// <------------------------------------------------ Run program till user presses ESC ---------------------------------------------->

while(img_cnt<300)
{
img_cnt++;

// <------------------------------------------------ Wait for new image to appear ---------------------------------------------->
while(!cam->BeginReadFrame(0,frame_data,frame_sz)) {};

// <----------------lock the chosen frame buffer, and copy it directly into the corresponding open gl texture ---------------->
{
data = (const uint8_t*)frame_data;
ypitch = MAIN_TEXTURE_WIDTH;
ysize = ypitch*MAIN_TEXTURE_HEIGHT;
uvpitch = MAIN_TEXTURE_WIDTH/2;
uvsize = uvpitch*MAIN_TEXTURE_HEIGHT/2;
upos = ysize;
vpos = upos+uvsize;
ytexture.SetPixels(data);
utexture.SetPixels(data+upos);
vtexture.SetPixels(data+vpos);
cam->EndReadFrame(0);
}


// <----------------Image Processing in GPU using OpenGL---------------->
BeginFrame();

DrawYUVTextureRect(&ytexture,&utexture,&vtexture,&tex);

DrawTextureRect(&tex,-1.f,-1.f,1.f,1.f,NULL);

EndFrame();


}

// <------------------------------------------------ Finish Program ---------------------------------------------->

StopCamera();

endwin();


}



Thanks

Chandra

Dimple
04-20-2015, 05:41 AM
It should work

mcprakash
04-20-2015, 07:55 AM
Hi
Thanks. I just made a small mistake with the src_rect.width and src_rect.height. It is working now. Thanks once again.

Chandra :)