HUD and PDA now working

some minor bugs with videos not playing on the PDA but it is pretty much working how it was now.
This commit is contained in:
Simon 2020-10-08 23:01:13 +01:00
parent fb4d4a81d2
commit a9dbcb1f7b
11 changed files with 100 additions and 321 deletions

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.drbeef.doom3quest"
android:versionCode="12"
android:versionName="0.0.18" android:installLocation="auto" >
android:versionCode="13"
android:versionName="0.1.0" android:installLocation="auto" >
<!-- Tell the system this app requires OpenGL ES 3.1. -->
<uses-feature android:glEsVersion="0x00030001" android:required="true"/>

View file

@ -713,10 +713,12 @@ void idObjective::Event_CamShot( ) {
fullView.width = SCREEN_WIDTH;
fullView.height = SCREEN_HEIGHT;
// draw a view to a texture
renderSystem->DirectFrameBufferStart();
renderSystem->CropRenderSize( 256, 256, true );
gameRenderWorld->RenderScene( &fullView );
renderSystem->CaptureRenderToFile( shotName );
renderSystem->UnCrop();
renderSystem->DirectFrameBufferEnd();
}
}
}

View file

@ -455,6 +455,7 @@ idAngles idPlayerView::AngleOffset() const {
idPlayerView::SingleView
==================
*/
void idPlayerView::SingleView( idUserInterface *hud, const renderView_t *view ) {
// normal rendering
@ -462,13 +463,18 @@ void idPlayerView::SingleView( idUserInterface *hud, const renderView_t *view )
return;
}
renderSystem->DirectFrameBufferStart();
if ( player->objectiveSystemOpen ) {
player->objectiveSystem->Redraw( gameLocal.time );
} else {
player->DrawHUD(hud);
}
//renderSystem->CaptureRenderToImage( "_hudImage" );
renderSystem->CaptureRenderToImage( "_hudImage" );
renderSystem->DirectFrameBufferEnd();
// place the sound origin for the player
gameSoundWorld->PlaceListener( view->vieworg, view->viewaxis, player->entityNumber + 1, gameLocal.time, hud ? hud->State().GetString( "location" ) : "Undefined" );

View file

@ -88,6 +88,7 @@ src_renderer = \
renderer/tr_trisurf.cpp \
renderer/tr_turboshadow.cpp \
renderer/etc_android.cpp \
renderer/framebuffer.cpp
src_framework = \
framework/CVarSystem.cpp \

View file

@ -1181,3 +1181,18 @@ bool idRenderSystemLocal::UploadImage( const char *imageName, const byte *data,
image->SetImageFilterAndRepeat();
return true;
}
void idRenderSystemLocal::DirectFrameBufferStart()
{
emptyCommand_t *cmd;
cmd = (emptyCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) );
cmd->commandId = RC_DIRECT_BUFFER_START;
}
void idRenderSystemLocal::DirectFrameBufferEnd()
{
emptyCommand_t *cmd;
cmd = (emptyCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) );
cmd->commandId = RC_DIRECT_BUFFER_END;
}

View file

@ -229,6 +229,9 @@ public:
// texture filter / mipmapping / repeat won't be modified by the upload
// returns false if the image wasn't found
virtual bool UploadImage( const char *imageName, const byte *data, int width, int height ) = 0;
virtual void DirectFrameBufferStart() = 0;
virtual void DirectFrameBufferEnd() = 0;
};
extern idRenderSystem * renderSystem;

View file

@ -1738,6 +1738,8 @@ void idRenderSystemLocal::InitOpenGL( void ) {
common->Printf( "glGetError() = 0x%x\n", err );
}
}
R_InitFrameBuffer();
}
/*

View file

@ -5,356 +5,79 @@ GPL3
#include "renderer/tr_local.h"
#include "renderer/VertexCache.h"
idCVar r_framebufferFilter( "r_framebufferFilter", "0", CVAR_RENDERER | CVAR_BOOL, "Image filter when using the framebuffer. 0 = Nearest, 1 = Linear" );
static GLuint m_framebuffer = -1;
static GLuint m_depthbuffer;
static GLuint m_stencilbuffer;
static GLuint m_framebuffer[3];
static GLuint m_depthbuffer[3];
static int m_framebuffer_width, m_framebuffer_height;
static GLuint m_framebuffer_texture;
static GLuint m_framebuffer_texture[3];
static GLuint m_positionLoc;
static GLuint m_texCoordLoc;
static GLuint m_samplerLoc;
static GLuint r_program;
static int fixNpot(int v)
{
int ret = 1;
while(ret < v)
ret <<= 1;
return ret;
}
#define ALOGE(...) __android_log_print( ANDROID_LOG_ERROR, "FRAMEBUFFER", __VA_ARGS__ )
static const char * GlErrorString( GLenum error )
{
switch ( error )
{
case GL_NO_ERROR: return "GL_NO_ERROR";
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
case GL_INVALID_FRAMEBUFFER_OPERATION: return "GL_INVALID_FRAMEBUFFER_OPERATION";
case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
default: return "unknown";
}
}
static void GLCheckErrors( int line )
{
for ( int i = 0; i < 10; i++ )
{
const GLenum error = glGetError();
if ( error == GL_NO_ERROR )
{
break;
}
ALOGE( "GL error on line %d: %s", line, GlErrorString( error ) );
}
}
#define LOG common->Printf
int loadShader(int shaderType, const char * source)
{
int shader = qglCreateShader(shaderType);
if(shader != 0)
{
qglShaderSource(shader, 1, &source, NULL);
qglCompileShader(shader);
GLint length;
qglGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
if(length)
{
char* buffer = new char [ length ];
qglGetShaderInfoLog(shader, length, NULL, buffer);
LOG("shader = %s\n", buffer);
delete [] buffer;
GLint success;
qglGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if(success != GL_TRUE)
{
LOG("ERROR compiling shader\n");
}
}
}
else
{
LOG("FAILED to create shader");
}
return shader;
}
int createProgram(const char * vertexSource, const char * fragmentSource)
{
int vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource);
int pixelShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource);
int program = glCreateProgram();
if(program != 0)
{
glAttachShader(program, vertexShader);
// checkGlError("glAttachShader");
glAttachShader(program, pixelShader);
// checkGlError("glAttachShader");
glLinkProgram(program);
#define GL_LINK_STATUS 0x8B82
int linkStatus[1];
glGetProgramiv(program, GL_LINK_STATUS, linkStatus);
if(linkStatus[0] != GL_TRUE)
{
LOG("Could not link program: ");
char log[256];
GLsizei size;
glGetProgramInfoLog(program, 256, &size, log);
LOG("Log: %s", log);
//glDeleteProgram(program);
program = 0;
}
}
else
{
LOG("FAILED to create program");
}
LOG("Program linked OK %d", program);
return program;
}
static void createShaders (void)
{
const GLchar *vertSource = \
"attribute vec2 a_texCoord; \n \
attribute vec4 a_position; \n \
varying vec2 v_texCoord; \n \
void main() \n \
{ \n \
gl_Position = a_position; \n \
v_texCoord = a_texCoord; \n \
} \n \
";
const GLchar *fragSource = \
"precision mediump float; \n \
varying vec2 v_texCoord; \n \
uniform sampler2D s_texture; \n \
void main() \n \
{ \n \
gl_FragColor = texture2D( s_texture, v_texCoord ); \n \
//gl_FragColor = vec4( 0.8, 0.5, 0.9, 1.0 ); \n \
} \n \
";
r_program = createProgram(vertSource, fragSource);
glUseProgram(r_program);
// get attrib locations
m_positionLoc = glGetAttribLocation(r_program, "a_position");
m_texCoordLoc = glGetAttribLocation(r_program, "a_texCoord");
m_samplerLoc = glGetUniformLocation(r_program, "s_texture");
if(m_positionLoc == -1)
LOG("Failed to get m_positionLoc");
if(m_texCoordLoc == -1)
LOG("Failed to get m_texCoordLoc");
if(m_samplerLoc == -1)
LOG("Failed to get m_samplerLoc");
glUniform1i(m_samplerLoc, 0);
}
static GLint drawFboId = 0;
static int calldepth = 0;
void R_InitFrameBuffer()
{
//LOG("R_InitFrameBuffer Real[%d, %d] -> Framebuffer[%d,%d]", glConfig.vidWidthReal, glConfig.vidHeightReal, glConfig.vidWidth, glConfig.vidHeight);
/* if(glConfig.vidWidthReal == glConfig.vidWidth && glConfig.vidHeightReal == glConfig.vidHeight)
{
LOGI("Not using framebuffer");
return;
}*/
//glConfig.npotAvailable = false;
m_framebuffer_width = glConfig.vidWidth;
m_framebuffer_height = glConfig.vidHeight;
if (!glConfig.npotAvailable)
{
m_framebuffer_width = fixNpot(m_framebuffer_width);
m_framebuffer_height = fixNpot(m_framebuffer_height);
}
for (int i = 0; i < 3; ++i) {
// Create texture
glGenTextures(1, &m_framebuffer_texture[i]);
glBindTexture(GL_TEXTURE_2D, m_framebuffer_texture[i]);
LOGI("Framebuffer buffer size = [%d, %d]", m_framebuffer_width, m_framebuffer_height);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_framebuffer_width, m_framebuffer_height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Create texture
glGenTextures(1, &m_framebuffer_texture);
glBindTexture(GL_TEXTURE_2D, m_framebuffer_texture);
// Create framebuffer
glGenFramebuffers(1, &m_framebuffer[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_framebuffer_width, m_framebuffer_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
if(r_framebufferFilter.GetInteger() == 0)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
// Create framebuffer
glGenFramebuffers(1, &m_framebuffer);
// Create renderbuffer
glGenRenderbuffers(1, &m_depthbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_depthbuffer);
if(glConfig.depthStencilAvailable)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_framebuffer_width, m_framebuffer_height);
else
{
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_framebuffer_width, m_framebuffer_height);
// Need separate Stencil buffer
glGenRenderbuffers(1, &m_stencilbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_stencilbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, m_framebuffer_width, m_framebuffer_height);
}
createShaders();
// Create renderbuffer
glGenRenderbuffers(1, &m_depthbuffer[i]);
glBindRenderbuffer(GL_RENDERBUFFER, m_depthbuffer[i]);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_framebuffer_width,
m_framebuffer_height);
}
}
void R_FrameBufferStart()
{
if(m_framebuffer == -1)
return;
if (calldepth == 0) {
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &drawFboId);
}
// Render to framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
GLCheckErrors(__LINE__);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer[calldepth]);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
GLCheckErrors(__LINE__);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_framebuffer_texture, 0);
GLCheckErrors(__LINE__);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_framebuffer_texture[calldepth], 0);
// Attach combined depth+stencil
if(glConfig.depthStencilAvailable)
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthbuffer);
}
else
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencilbuffer);
}
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthbuffer[calldepth]);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthbuffer[calldepth]);
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(result != GL_FRAMEBUFFER_COMPLETE)
{
common->Error( "Error binding Framebuffer: %d\n", result );
common->Error( "Error binding Framebuffer: %i\n", result );
}
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
qglClear( GL_COLOR_BUFFER_BIT );
calldepth++;
}
void R_FrameBufferEnd()
{
if(m_framebuffer == -1)
return;
calldepth--;
//glBindFramebuffer(GL_FRAMEBUFFER, 0);
//glBindRenderbuffer(GL_RENDERBUFFER, 0);
// Bind the texture
glBindTexture(GL_TEXTURE_2D, m_framebuffer_texture);
GLCheckErrors(__LINE__);
// Unbind any VBOs
vertexCache.UnbindIndex();
vertexCache.UnbindVertex();
glUseProgram(r_program);
GLCheckErrors(__LINE__);
GLfloat vert[] =
{
-1.f, -1.f, 0.0f, // 0. left-bottom
-1.f, 1.f, 0.0f, // 1. left-top
1.f, 1.f, 0.0f, // 2. right-top
1.f, -1.f, 0.0f, // 3. right-bottom
};
GLfloat smax = 1;
GLfloat tmax = 1;
if (!glConfig.npotAvailable)
{
smax = (float)glConfig.vidWidth / (float)m_framebuffer_width;
tmax = (float)glConfig.vidHeight / (float)m_framebuffer_height;
}
GLfloat texVert[] =
{
0.0f, 0.0f, // TexCoord 0
0.0f, tmax, // TexCoord 1
smax, tmax, // TexCoord 2
smax, 0.0f // TexCoord 3
};
GLCheckErrors(__LINE__);
glVertexAttribPointer(m_positionLoc, 3, GL_FLOAT,
false,
3 * 4,
vert);
GLCheckErrors(__LINE__);
glVertexAttribPointer(m_texCoordLoc, 2, GL_FLOAT,
false,
2 * 4,
texVert);
GLCheckErrors(__LINE__);
glEnableVertexAttribArray(m_positionLoc);
GLCheckErrors(__LINE__);
glEnableVertexAttribArray(m_texCoordLoc);
GLCheckErrors(__LINE__);
// Set the sampler texture unit to 0
glUniform1i(m_samplerLoc, 0);
GLCheckErrors(__LINE__);
glViewport (0, 0, glConfig.vidWidth, glConfig.vidHeight );
//glViewport (0, 0, glConfig.vidWidthReal, glConfig.vidHeightReal );
GLCheckErrors(__LINE__);
glDisable(GL_BLEND);
GLCheckErrors(__LINE__);
glDisable(GL_SCISSOR_TEST);
GLCheckErrors(__LINE__);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
GLCheckErrors(__LINE__);
if (calldepth == 0) {
glBindFramebuffer(GL_FRAMEBUFFER, drawFboId);
} else {
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer[calldepth-1]);
}
}

View file

@ -418,6 +418,12 @@ void RB_ExecuteBackEndCommands( const emptyCommand_t *cmds ) {
RB_CopyRender(cmd);
c_copyRenders++;
break;
case RC_DIRECT_BUFFER_START:
R_FrameBufferStart();
break;
case RC_DIRECT_BUFFER_END:
R_FrameBufferEnd();
break;
default:
common->Error("RB_ExecuteBackEndCommands: bad commandId");
break;

View file

@ -491,7 +491,9 @@ typedef enum {
RC_DRAW_VIEW,
RC_SET_BUFFER,
RC_COPY_RENDER,
RC_SWAP_BUFFERS // can't just assume swap at end of list because
RC_SWAP_BUFFERS, // can't just assume swap at end of list because
RC_DIRECT_BUFFER_START,
RC_DIRECT_BUFFER_END
// of forced list submission before syncs
} renderCommand_t;
@ -715,6 +717,8 @@ public:
virtual void UnCrop();
virtual bool UploadImage( const char *imageName, const byte *data, int width, int height );
virtual void DirectFrameBufferStart();
virtual void DirectFrameBufferEnd();
public:
// internal functions
idRenderSystemLocal( void );
@ -1209,6 +1213,11 @@ void R_FreeEntityDefFadedDecals( idRenderEntityLocal *def, int time );
void R_CreateLightDefFogPortals( idRenderLightLocal *ldef );
// Framebuffer stuff
void R_InitFrameBuffer();
void R_FrameBufferStart();
void R_FrameBufferEnd();
/*
============================================================

View file

@ -324,6 +324,8 @@ static void R_RemoteRender( drawSurf_t *surf, textureStage_t *stage ) {
parms->superView = tr.viewDef;
parms->subviewSurface = surf;
R_FrameBufferStart();
// generate render commands for it
R_RenderView(parms);
@ -335,6 +337,8 @@ static void R_RemoteRender( drawSurf_t *surf, textureStage_t *stage ) {
tr.CaptureRenderToImage( stage->image->imgName );
tr.UnCrop();
R_FrameBufferEnd();
}
/*
@ -376,6 +380,8 @@ void R_MirrorRender( drawSurf_t *surf, textureStage_t *stage, idScreenRect sciss
// triangle culling order changes with mirroring
parms->isMirror = ( ( (int)parms->isMirror ^ (int)tr.viewDef->isMirror ) != 0 );
R_FrameBufferStart();
// generate render commands for it
R_RenderView( parms );
@ -385,6 +391,8 @@ void R_MirrorRender( drawSurf_t *surf, textureStage_t *stage, idScreenRect sciss
tr.CaptureRenderToImage( stage->image->imgName );
tr.UnCrop();
R_FrameBufferEnd();
}
/*
@ -426,6 +434,8 @@ void R_XrayRender( drawSurf_t *surf, textureStage_t *stage, idScreenRect scissor
// triangle culling order changes with mirroring
parms->isMirror = ( ( (int)parms->isMirror ^ (int)tr.viewDef->isMirror ) != 0 );
R_FrameBufferStart();
// generate render commands for it
R_RenderView( parms );
@ -435,6 +445,8 @@ void R_XrayRender( drawSurf_t *surf, textureStage_t *stage, idScreenRect scissor
tr.CaptureRenderToImage( stage->image->imgName );
tr.UnCrop();
R_FrameBufferEnd();
}
/*