/*---------------------------------------------------------------------------* Project: Horizon File: gx_TextureCombiner.cpp Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev: 47228 $ *---------------------------------------------------------------------------*/ #include #include #include #include #include #include #include "demo.h" namespace { /* Enumerated type */ typedef enum CombinerMode { COMB_MODE_ADD = 0, COMB_MODE_SUBTRACT, COMB_MODE_MULT, COMB_MODE_ADDMULT, COMB_MODE_DECAL, COMB_MODE_DECAL2, COMB_MODE_BLEND, COMB_MODE_TWOCOLOR_INTERPOLATE, COMB_MODE_NUM } CombinerMode; static char *g_CombinerModeName[] = { "ADD", "SUBTRACT", "MULTIPLY", "ADD AND MULTIPLY", "DECAL", "DECAL2", "BLENDING", "INTERPOLATE BY TWO COLORS" }; /* buffer id */ GLuint s_ArrayBufferID; GLuint s_ElementArrayBufferID; /* program id */ GLuint s_ProgramID; /* shader id */ GLuint s_ShaderID; /* Texture */ GLuint s_Texture[2]; GLuint s_TextureGray; GLuint s_TextureAlpha; /* Other variables */ int s_Count = 1; int s_Mode = COMB_MODE_ADD; GLfloat s_Intensity[4] = {0.0f, 0.0f, 0.0f, 0.0f}; nn::fnd::ExpHeap s_AppHeap; uptr s_AddrForGxHeap; const u32 s_GxHeapSize = 0x400000; demo::RenderSystemDrawing s_RenderSystem; } // Namespace // TODO: We will change this at some point so that it loads from a binary file. extern u8 g_TexBitmapUpper[]; extern u8 g_TexBitmapLower[]; extern u8 g_TexAlpha[]; extern u8 g_TexGray[]; /* Functions */ void LoadObjects(void); void ReadyObjects(void); void DrawDisplay0(void); void DrawDisplay1(void); void SetTextureCombiner(void); void DrawFrame(void); int Initialize(void); /* generate simple object */ void LoadObjects(void) { GLfloat coords[] = { -0.5f, 0.5f, 0.f, 1.f, -0.5f,-0.5f, 0.f, 1.f, 0.5f, 0.5f, 0.f, 1.f, 0.5f,-0.5f, 0.f, 1.f }; GLfloat texcoords[] = { 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 0.f, 0.f, }; GLushort idxs[] = {0, 1, 2, 3}; glGenBuffers(1, &s_ArrayBufferID); glBindBuffer(GL_ARRAY_BUFFER, s_ArrayBufferID); glBufferData(GL_ARRAY_BUFFER, sizeof(coords) + sizeof(texcoords), 0, GL_STATIC_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(coords), coords); glBufferSubData(GL_ARRAY_BUFFER, sizeof(coords), sizeof(texcoords), texcoords); glGenBuffers(1, &s_ElementArrayBufferID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_ElementArrayBufferID); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(idxs), idxs, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0) ; glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)sizeof(coords)); } void ReadyObjects(void) { glUseProgram(s_ProgramID); glBindBuffer(GL_ARRAY_BUFFER, s_ArrayBufferID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_ElementArrayBufferID); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(16*sizeof(GLfloat))); } void DrawDisplay0(void) { s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0); s_RenderSystem.Clear(); ReadyObjects(); // Texture combiner settings glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_Texture[0].samplerType"), GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_Texture[1].samplerType"), GL_TEXTURE_2D); if (s_Mode == COMB_MODE_TWOCOLOR_INTERPOLATE) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, s_TextureGray); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } else if (s_Mode == COMB_MODE_ADDMULT || s_Mode == COMB_MODE_DECAL) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, s_Texture[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, s_TextureAlpha); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } else { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, s_Texture[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, s_Texture[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } SetTextureCombiner(); nn::math::Matrix44 proj; nn::math::MTX44Frustum(&proj, -0.02f, 0.02f, -0.02f* static_cast(nn::gx::DISPLAY0_HEIGHT) / static_cast(nn::gx::DISPLAY0_WIDTH), 0.02f* static_cast(nn::gx::DISPLAY0_HEIGHT) / static_cast(nn::gx::DISPLAY0_WIDTH), 0.2f, 10.f); glUniformMatrix4fv(glGetUniformLocation(s_ProgramID, "uProjection"), 1, GL_TRUE, static_cast(proj)); nn::math::Matrix34 eye; nn::math::Vector3 camPos(0.f, 0.f, 5.5f); nn::math::Vector3 camUp(0.f, 1.f, 0.f); nn::math::Vector3 target(0.f, 0.f, 0.f); nn::math::MTX34LookAt(&eye, &camPos, &camUp, &target); nn::math::Matrix44 mv(eye); glUniformMatrix4fv(glGetUniformLocation(s_ProgramID, "uModelView"), 1, GL_TRUE, static_cast(mv)); glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0); s_RenderSystem.SwapBuffers(); } void DrawDisplay1(void) { s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1); s_RenderSystem.Clear(); s_RenderSystem.SetColor(1.0f, 1.0f, 1.0f); s_RenderSystem.DrawText(0.0f, 0.0f, "Count: %d", s_Count); s_RenderSystem.DrawText(0.0f, 8.0f, "MODE: %s", g_CombinerModeName[s_Mode]); s_RenderSystem.SwapBuffers(); } void SetTextureCombiner(void) { switch(s_Mode) { case COMB_MODE_ADD: glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_TEXTURE0, GL_TEXTURE1, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_TEXTURE0, GL_PREVIOUS, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_ADD); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_REPLACE); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f); break; case COMB_MODE_SUBTRACT: glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_TEXTURE0, GL_TEXTURE1, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_TEXTURE0, GL_PREVIOUS, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_SUBTRACT); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_REPLACE); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f); break; case COMB_MODE_MULT: glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_TEXTURE0, GL_TEXTURE1, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_TEXTURE0, GL_PREVIOUS, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_MODULATE); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_REPLACE); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f); break; case COMB_MODE_ADDMULT: // Requires texture data with an alpha component. glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcRgb"), GL_TEXTURE1, GL_TEXTURE1, GL_TEXTURE0); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcAlpha"), GL_TEXTURE0, GL_CONSTANT, GL_CONSTANT); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_ALPHA, GL_SRC_COLOR); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineRgb"), GL_MULT_ADD_DMP); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].scaleRgb"), 1.0f); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].scaleAlpha"), 1.0f); // Make sure to initialize the following texture combiner glUniform4f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].constRgba"), 0.0f, 0.0f, 0.0f, 0.0f); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].srcRgb"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].srcAlpha"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].combineRgb"), GL_REPLACE); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].combineAlpha"), GL_REPLACE); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].scaleRgb"), 1.0f); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].scaleAlpha"), 1.0f); glUniform4f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].constRgba"), 0.0f, 0.0f, 0.0f, 0.0f); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_REPLACE); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_REPLACE); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f); break; case COMB_MODE_DECAL: // Requires texture data with an alpha component. glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcRgb"), GL_TEXTURE1, GL_TEXTURE0, GL_TEXTURE1); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcAlpha"), GL_TEXTURE0, GL_CONSTANT, GL_CONSTANT); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineRgb"), GL_INTERPOLATE); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].scaleRgb"), 1.0f); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].scaleAlpha"), 1.0f); // Make sure to initialize the following texture combiner glUniform4f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].constRgba"), 0.0f, 0.0f, 0.0f, 0.0f); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].srcRgb"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].srcAlpha"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].combineRgb"), GL_REPLACE); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].combineAlpha"), GL_REPLACE); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].scaleRgb"), 1.0f); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].scaleAlpha"), 1.0f); glUniform4f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].constRgba"), 0.0f, 0.0f, 0.0f, 0.0f); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_REPLACE); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_REPLACE); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f); break; case COMB_MODE_DECAL2: glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].constRgba"), 1, s_Intensity); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].srcRgb"), GL_TEXTURE1, GL_CONSTANT, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].operandRgb"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_COLOR); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].combineRgb"), GL_MODULATE); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].scaleRgb"), 1.0f); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_TEXTURE1, GL_TEXTURE0, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_TEXTURE0, GL_PREVIOUS, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_INTERPOLATE); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_REPLACE); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f); break; case COMB_MODE_BLEND: glUniform4f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].constRgba"), 0.7f, 0.7f, 0.7f, 0.7f); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_TEXTURE0, GL_TEXTURE1, GL_CONSTANT); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_TEXTURE0, GL_TEXTURE1, GL_CONSTANT); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_INTERPOLATE); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_INTERPOLATE); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f); break; case COMB_MODE_TWOCOLOR_INTERPOLATE: // Requires gray scale texture glUniform4f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].constRgba"), 1.0f, 1.0f, 0.0f, 1.0f); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].srcRgb"), GL_CONSTANT, GL_TEXTURE0, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].combineRgb"), GL_MODULATE); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].scaleRgb"), 1.0f); glUniform4f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].constRgba"), 0.0f, 0.0f, 1.0f, 1.0f); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_CONSTANT, GL_TEXTURE0, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_TEXTURE0, GL_PREVIOUS, GL_PREVIOUS); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_COLOR); glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_MULT_ADD_DMP); glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_REPLACE); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f); glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f); break; default: break; } } void DrawFrame(void) { DrawDisplay0(); DrawDisplay1(); s_Count++; // Switches texture combiner setting using s_Count value if (s_Count % 100 == 0) { s_Mode++; if (s_Mode >= COMB_MODE_NUM) { s_Mode = COMB_MODE_ADD; } } if (s_Mode == COMB_MODE_DECAL2) { if (s_Count % 10 == 0) { for (int i=0; i<4; i++) { s_Intensity[i] += 0.1f; if (s_Intensity[i] > 1.0f) { s_Intensity[i] = 0.0f; } } } } s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH); } /* initialization */ int Initialize(void) { // fs initialization nn::fs::Initialize(); const size_t ROMFS_BUFFER_SIZE = 1024 * 64; static char buffer[ROMFS_BUFFER_SIZE]; NN_UTIL_PANIC_IF_FAILED( nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE)); /* Initialize display */ s_AppHeap.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize() ); s_AddrForGxHeap = reinterpret_cast(s_AppHeap.Allocate(s_GxHeapSize)); s_RenderSystem.Initialize(s_AddrForGxHeap, s_GxHeapSize); s_ProgramID = glCreateProgram(); s_ShaderID = glCreateShader(GL_VERTEX_SHADER); nn::fs::FileReader file(L"rom:/shader.shbin"); size_t fileSize = file.GetSize(); void* buf = s_AppHeap.Allocate(fileSize); s32 read = file.Read(buf, fileSize); glShaderBinary(1, &s_ShaderID, GL_PLATFORM_BINARY_DMP, buf, read); file.Finalize(); s_AppHeap.Free(buf); glAttachShader(s_ProgramID, s_ShaderID); glAttachShader(s_ProgramID, GL_DMP_FRAGMENT_SHADER_DMP); glBindAttribLocation(s_ProgramID, 0, "aPosition"); glBindAttribLocation(s_ProgramID, 1, "aTexCoord"); glLinkProgram(s_ProgramID); glValidateProgram(s_ProgramID); glUseProgram(s_ProgramID); // Load Texture glGenTextures(2, s_Texture); glGenTextures(1, &s_TextureGray); glGenTextures(1, &s_TextureAlpha); // TODO: Native texture formats supported glBindTexture(GL_TEXTURE_2D, s_Texture[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, g_TexBitmapUpper); glBindTexture(GL_TEXTURE_2D, s_Texture[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, g_TexBitmapLower); glBindTexture(GL_TEXTURE_2D, s_TextureGray); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 32, 32, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, g_TexGray); glBindTexture(GL_TEXTURE_2D, s_TextureAlpha); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, g_TexAlpha); glBindTexture(GL_TEXTURE_2D, 0); s_RenderSystem.SetClearColor(NN_GX_DISPLAY0, 0.36f, 0.42f, 0.5f, 1.0f); s_RenderSystem.SetClearColor(NN_GX_DISPLAY1, 0.36f, 0.42f, 0.5f, 1.0f); glClearDepthf(1.f); glEnable(GL_CULL_FACE); glFrontFace(GL_CCW); glCullFace(GL_BACK); LoadObjects(); return 0; } void nnMain(void) { // Call only nn::applet::Enable to also allow execution from the HOME Menu // HOME Menu transitions, POWER Button presses, and sleep are all unsupported nn::applet::Enable(); /* initialization */ if (Initialize() >= 0) { /* Enter loop */ while (1) { DrawFrame(); } } /* shutdown_display */ s_RenderSystem.Finalize(); s_AppHeap.Free(reinterpret_cast(s_AddrForGxHeap)); s_AppHeap.Finalize(); }