summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar archshift2014-10-12 22:40:26 -0700
committerGravatar archshift2015-03-09 15:51:41 -0700
commit041e99b6132775ff52822060512b8384b735e582 (patch)
treecd8dee92a0b578e512a188cd7e70239b627a5341 /src
parentImplement SetLcdForceBlack, move register enum to hw.h (diff)
downloadyuzu-041e99b6132775ff52822060512b8384b735e582.tar.gz
yuzu-041e99b6132775ff52822060512b8384b735e582.tar.xz
yuzu-041e99b6132775ff52822060512b8384b735e582.zip
Added LCD registers, and implementation for color filling in OGL code.
Diffstat (limited to 'src')
-rw-r--r--src/common/logging/backend.cpp1
-rw-r--r--src/common/logging/log.h1
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/service/gsp_gpu.cpp32
-rw-r--r--src/core/hw/gpu.h2
-rw-r--r--src/core/hw/hw.cpp12
-rw-r--r--src/core/hw/hw.h8
-rw-r--r--src/core/hw/lcd.cpp66
-rw-r--r--src/core/hw/lcd.h88
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp54
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h5
11 files changed, 234 insertions, 37 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 7c1010b22..da287f69e 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -45,6 +45,7 @@ static std::shared_ptr<Logger> global_logger;
45 SUB(Service, SOC) \ 45 SUB(Service, SOC) \
46 CLS(HW) \ 46 CLS(HW) \
47 SUB(HW, Memory) \ 47 SUB(HW, Memory) \
48 SUB(HW, LCD) \
48 SUB(HW, GPU) \ 49 SUB(HW, GPU) \
49 CLS(Frontend) \ 50 CLS(Frontend) \
50 CLS(Render) \ 51 CLS(Render) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index 7b67b3c07..83d64145b 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -65,6 +65,7 @@ enum class Class : ClassType {
65 Service_SOC, ///< The SOC (Socket) service 65 Service_SOC, ///< The SOC (Socket) service
66 HW, ///< Low-level hardware emulation 66 HW, ///< Low-level hardware emulation
67 HW_Memory, ///< Memory-map and address translation 67 HW_Memory, ///< Memory-map and address translation
68 HW_LCD, ///< LCD register emulation
68 HW_GPU, ///< GPU control emulation 69 HW_GPU, ///< GPU control emulation
69 Frontend, ///< Emulator UI 70 Frontend, ///< Emulator UI
70 Render, ///< Emulator video output and hardware acceleration 71 Render, ///< Emulator video output and hardware acceleration
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 212da25c5..33e5be3a4 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -87,6 +87,7 @@ set(SRCS
87 hle/svc.cpp 87 hle/svc.cpp
88 hw/gpu.cpp 88 hw/gpu.cpp
89 hw/hw.cpp 89 hw/hw.cpp
90 hw/lcd.cpp
90 loader/elf.cpp 91 loader/elf.cpp
91 loader/loader.cpp 92 loader/loader.cpp
92 loader/ncch.cpp 93 loader/ncch.cpp
@@ -196,6 +197,7 @@ set(HEADERS
196 hle/svc.h 197 hle/svc.h
197 hw/gpu.h 198 hw/gpu.h
198 hw/hw.h 199 hw/hw.h
200 hw/lcd.h
199 loader/elf.h 201 loader/elf.h
200 loader/loader.h 202 loader/loader.h
201 loader/ncch.h 203 loader/ncch.h
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index 3b4a7b664..cff585698 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -11,12 +11,16 @@
11#include "gsp_gpu.h" 11#include "gsp_gpu.h"
12#include "core/hw/hw.h" 12#include "core/hw/hw.h"
13#include "core/hw/gpu.h" 13#include "core/hw/gpu.h"
14#include "core/hw/lcd.h"
14 15
15#include "video_core/gpu_debugger.h" 16#include "video_core/gpu_debugger.h"
16 17
17// Main graphics debugger object - TODO: Here is probably not the best place for this 18// Main graphics debugger object - TODO: Here is probably not the best place for this
18GraphicsDebugger g_debugger; 19GraphicsDebugger g_debugger;
19 20
21// Beginning address of HW regs
22const static u32 REGS_BEGIN = 0x1EB00000;
23
20//////////////////////////////////////////////////////////////////////////////////////////////////// 24////////////////////////////////////////////////////////////////////////////////////////////////////
21// Namespace GSP_GPU 25// Namespace GSP_GPU
22 26
@@ -87,7 +91,7 @@ static void WriteHWRegs(u32 base_address, u32 size_in_bytes, const u32* data) {
87 return; 91 return;
88 92
89 while (size_in_bytes > 0) { 93 while (size_in_bytes > 0) {
90 HW::Write<u32>(base_address + 0x1EB00000, *data); 94 HW::Write<u32>(base_address + REGS_BEGIN, *data);
91 95
92 size_in_bytes -= 4; 96 size_in_bytes -= 4;
93 ++data; 97 ++data;
@@ -130,7 +134,7 @@ static void WriteHWRegsWithMask(u32 base_address, u32 size_in_bytes, const u32*
130 return; 134 return;
131 135
132 while (size_in_bytes > 0) { 136 while (size_in_bytes > 0) {
133 const u32 reg_address = base_address + 0x1EB00000; 137 const u32 reg_address = base_address + REGS_BEGIN;
134 138
135 u32 reg_value; 139 u32 reg_value;
136 HW::Read<u32>(reg_value, reg_address); 140 HW::Read<u32>(reg_value, reg_address);
@@ -190,7 +194,7 @@ static void ReadHWRegs(Service::Interface* self) {
190 u32* dst = (u32*)Memory::GetPointer(cmd_buff[0x41]); 194 u32* dst = (u32*)Memory::GetPointer(cmd_buff[0x41]);
191 195
192 while (size > 0) { 196 while (size > 0) {
193 HW::Read<u32>(*dst, reg_addr + 0x1EB00000); 197 HW::Read<u32>(*dst, reg_addr + REGS_BEGIN);
194 198
195 size -= 4; 199 size -= 4;
196 ++dst; 200 ++dst;
@@ -439,24 +443,18 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
439 * Outputs: 443 * Outputs:
440 * 1: Result code 444 * 1: Result code
441 */ 445 */
442void SetLcdForceBlack(Service::Interface* self) { 446static void SetLcdForceBlack(Service::Interface* self) {
443 // TODO: currently has no effect, as LCD reg writes have nowhere to go.
444
445 u32* cmd_buff = Kernel::GetCommandBuffer(); 447 u32* cmd_buff = Kernel::GetCommandBuffer();
448
446 bool enable_black = cmd_buff[1] != 0; 449 bool enable_black = cmd_buff[1] != 0;
447 u32 data = 0; 450 LCD::Regs::ColorFill data = {0};
448 451
449 if (enable_black) { 452 // Since data is already zeroed, there is no need to explicitly set
450 // Sets bit 24 to 1, enabling the fill 453 // the color to black (all zero).
451 // Since data is already 0x00000000, there is no need to explicitly set 454 data.is_enabled = enable_black;
452 // bits 0-23 to zero (black), or bit 24 to 0 (fill disabled).
453 data |= (1 << 24);
454 }
455 455
456 u32 data_main = data; 456 LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_top), data.raw); // Top LCD
457 u32 data_sub = data; 457 LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_bottom), data.raw); // Bottom LCD
458 WriteHWRegs(0x202204, 4, &data_main); // Main LCD
459 WriteHWRegs(0x202A04, 4, &data_sub); // Sub LCD
460 458
461 cmd_buff[1] = RESULT_SUCCESS.raw; 459 cmd_buff[1] = RESULT_SUCCESS.raw;
462} 460}
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h
index 737b1e968..76f4d66fe 100644
--- a/src/core/hw/gpu.h
+++ b/src/core/hw/gpu.h
@@ -246,6 +246,8 @@ struct Regs {
246 return content[index]; 246 return content[index];
247 } 247 }
248 248
249#undef ASSERT_MEMBER_SIZE
250
249private: 251private:
250 /* 252 /*
251 * Most physical addresses which GPU registers refer to are 8-byte aligned. 253 * Most physical addresses which GPU registers refer to are 8-byte aligned.
diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp
index bf4722cf7..bed50af50 100644
--- a/src/core/hw/hw.cpp
+++ b/src/core/hw/hw.cpp
@@ -6,17 +6,19 @@
6 6
7#include "core/hw/hw.h" 7#include "core/hw/hw.h"
8#include "core/hw/gpu.h" 8#include "core/hw/gpu.h"
9#include "core/hw/lcd.h"
9 10
10namespace HW { 11namespace HW {
11 12
12template <typename T> 13template <typename T>
13inline void Read(T &var, const u32 addr) { 14inline void Read(T &var, const u32 addr) {
14 switch (addr & 0xFFFFF000) { 15 switch (addr & 0xFFFFF000) {
15
16 case VADDR_GPU: 16 case VADDR_GPU:
17 GPU::Read(var, addr); 17 GPU::Read(var, addr);
18 break; 18 break;
19 19 case VADDR_LCD:
20 LCD::Write(var, addr);
21 break;
20 default: 22 default:
21 LOG_ERROR(HW_Memory, "unknown Read%lu @ 0x%08X", sizeof(var) * 8, addr); 23 LOG_ERROR(HW_Memory, "unknown Read%lu @ 0x%08X", sizeof(var) * 8, addr);
22 } 24 }
@@ -25,11 +27,12 @@ inline void Read(T &var, const u32 addr) {
25template <typename T> 27template <typename T>
26inline void Write(u32 addr, const T data) { 28inline void Write(u32 addr, const T data) {
27 switch (addr & 0xFFFFF000) { 29 switch (addr & 0xFFFFF000) {
28
29 case VADDR_GPU: 30 case VADDR_GPU:
30 GPU::Write(addr, data); 31 GPU::Write(addr, data);
31 break; 32 break;
32 33 case VADDR_LCD:
34 LCD::Write(addr, data);
35 break;
33 default: 36 default:
34 LOG_ERROR(HW_Memory, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, addr); 37 LOG_ERROR(HW_Memory, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, addr);
35 } 38 }
@@ -54,6 +57,7 @@ void Update() {
54/// Initialize hardware 57/// Initialize hardware
55void Init() { 58void Init() {
56 GPU::Init(); 59 GPU::Init();
60 LCD::Init();
57 LOG_DEBUG(HW, "initialized OK"); 61 LOG_DEBUG(HW, "initialized OK");
58} 62}
59 63
diff --git a/src/core/hw/hw.h b/src/core/hw/hw.h
index 6feeba08c..d65608910 100644
--- a/src/core/hw/hw.h
+++ b/src/core/hw/hw.h
@@ -8,8 +8,8 @@
8 8
9namespace HW { 9namespace HW {
10 10
11enum { 11/// Beginnings of IO register regions, in the user VA space.
12 VADDR_IO = 0x1EC00000, 12enum : u32 {
13 VADDR_HASH = 0x1EC01000, 13 VADDR_HASH = 0x1EC01000,
14 VADDR_CSND = 0x1EC03000, 14 VADDR_CSND = 0x1EC03000,
15 VADDR_DSP = 0x1EC40000, 15 VADDR_DSP = 0x1EC40000,
@@ -25,9 +25,7 @@ enum {
25 VADDR_SPI_3 = 0x1EC60000, 25 VADDR_SPI_3 = 0x1EC60000,
26 VADDR_I2C_3 = 0x1EC61000, 26 VADDR_I2C_3 = 0x1EC61000,
27 VADDR_MIC = 0x1EC62000, 27 VADDR_MIC = 0x1EC62000,
28 VADDR_PXI = 0x1EC63000, // 0xFFFD2000 28 VADDR_PXI = 0x1EC63000,
29 //VADDR_NTRCARD
30 VADDR_CDMA = 0xFFFDA000, // CoreLink DMA-330? Info
31 VADDR_LCD = 0x1ED02000, 29 VADDR_LCD = 0x1ED02000,
32 VADDR_DSP_2 = 0x1ED03000, 30 VADDR_DSP_2 = 0x1ED03000,
33 VADDR_HASH_2 = 0x1EE01000, 31 VADDR_HASH_2 = 0x1EE01000,
diff --git a/src/core/hw/lcd.cpp b/src/core/hw/lcd.cpp
new file mode 100644
index 000000000..7986f3ddb
--- /dev/null
+++ b/src/core/hw/lcd.cpp
@@ -0,0 +1,66 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/common_types.h"
6
7#include "core/arm/arm_interface.h"
8#include "core/hle/hle.h"
9#include "core/hw/hw.h"
10#include "core/hw/lcd.h"
11
12namespace LCD {
13
14Regs g_regs;
15
16template <typename T>
17inline void Read(T &var, const u32 raw_addr) {
18 u32 addr = raw_addr - HW::VADDR_LCD;
19 u32 index = addr / 4;
20
21 // Reads other than u32 are untested, so I'd rather have them abort than silently fail
22 if (index >= 0x400 || !std::is_same<T, u32>::value) {
23 LOG_ERROR(HW_LCD, "unknown Read%lu @ 0x%08X", sizeof(var) * 8, addr);
24 return;
25 }
26
27 var = g_regs[index];
28}
29
30template <typename T>
31inline void Write(u32 addr, const T data) {
32 addr -= HW::VADDR_LCD;
33 u32 index = addr / 4;
34
35 // Writes other than u32 are untested, so I'd rather have them abort than silently fail
36 if (index >= 0x400 || !std::is_same<T, u32>::value) {
37 LOG_ERROR(HW_LCD, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, addr);
38 return;
39 }
40
41 g_regs[index] = static_cast<u32>(data);
42}
43
44// Explicitly instantiate template functions because we aren't defining this in the header:
45
46template void Read<u64>(u64 &var, const u32 addr);
47template void Read<u32>(u32 &var, const u32 addr);
48template void Read<u16>(u16 &var, const u32 addr);
49template void Read<u8>(u8 &var, const u32 addr);
50
51template void Write<u64>(u32 addr, const u64 data);
52template void Write<u32>(u32 addr, const u32 data);
53template void Write<u16>(u32 addr, const u16 data);
54template void Write<u8>(u32 addr, const u8 data);
55
56/// Initialize hardware
57void Init() {
58 LOG_DEBUG(HW_LCD, "initialized OK");
59}
60
61/// Shutdown hardware
62void Shutdown() {
63 LOG_DEBUG(HW_LCD, "shutdown OK");
64}
65
66} // namespace
diff --git a/src/core/hw/lcd.h b/src/core/hw/lcd.h
new file mode 100644
index 000000000..43893a625
--- /dev/null
+++ b/src/core/hw/lcd.h
@@ -0,0 +1,88 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <cstddef>
8
9#include "common/common_types.h"
10#include "common/bit_field.h"
11
12#define LCD_REG_INDEX(field_name) (offsetof(LCD::Regs, field_name) / sizeof(u32))
13
14namespace LCD {
15
16struct Regs {
17
18 union ColorFill {
19 u32 raw;
20
21 BitField<0, 8, u32> color_r;
22 BitField<8, 8, u32> color_g;
23 BitField<16, 8, u32> color_b;
24 BitField<24, 1, u32> is_enabled;
25 };
26
27 INSERT_PADDING_WORDS(0x81);
28 ColorFill color_fill_top;
29 INSERT_PADDING_WORDS(0xE);
30 u32 backlight_top;
31
32 INSERT_PADDING_WORDS(0x1F0);
33
34 ColorFill color_fill_bottom;
35 INSERT_PADDING_WORDS(0xE);
36 u32 backlight_bottom;
37 INSERT_PADDING_WORDS(0x16F);
38
39 static inline size_t NumIds() {
40 return sizeof(Regs) / sizeof(u32);
41 }
42
43 u32& operator [] (int index) const {
44 u32* content = (u32*)this;
45 return content[index];
46 }
47
48 u32& operator [] (int index) {
49 u32* content = (u32*)this;
50 return content[index];
51 }
52
53#undef ASSERT_MEMBER_SIZE
54
55};
56static_assert(std::is_standard_layout<Regs>::value, "Structure does not use standard layout");
57
58// TODO: MSVC does not support using offsetof() on non-static data members even though this
59// is technically allowed since C++11. This macro should be enabled once MSVC adds
60// support for that.
61#ifndef _MSC_VER
62#define ASSERT_REG_POSITION(field_name, position) \
63 static_assert(offsetof(Regs, field_name) == position * 4, \
64 "Field "#field_name" has invalid position")
65
66ASSERT_REG_POSITION(color_fill_top, 0x81);
67ASSERT_REG_POSITION(backlight_top, 0x90);
68ASSERT_REG_POSITION(color_fill_bottom, 0x281);
69ASSERT_REG_POSITION(backlight_bottom, 0x290);
70
71#undef ASSERT_REG_POSITION
72#endif // !defined(_MSC_VER)
73
74extern Regs g_regs;
75
76template <typename T>
77void Read(T &var, const u32 addr);
78
79template <typename T>
80void Write(u32 addr, const T data);
81
82/// Initialize hardware
83void Init();
84
85/// Shutdown hardware
86void Shutdown();
87
88} // namespace
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 272695174..2fcbb0cca 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -3,6 +3,8 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hw/gpu.h" 5#include "core/hw/gpu.h"
6#include "core/hw/hw.h"
7#include "core/hw/lcd.h"
6#include "core/mem_map.h" 8#include "core/mem_map.h"
7#include "common/emu_window.h" 9#include "common/emu_window.h"
8#include "video_core/video_core.h" 10#include "video_core/video_core.h"
@@ -61,16 +63,33 @@ void RendererOpenGL::SwapBuffers() {
61 for(int i : {0, 1}) { 63 for(int i : {0, 1}) {
62 const auto& framebuffer = GPU::g_regs.framebuffer_config[i]; 64 const auto& framebuffer = GPU::g_regs.framebuffer_config[i];
63 65
64 if (textures[i].width != (GLsizei)framebuffer.width || 66 // Main LCD (0): 0x1ED02204, Sub LCD (1): 0x1ED02A04
65 textures[i].height != (GLsizei)framebuffer.height || 67 u32 lcd_color_addr = (i == 0) ? LCD_REG_INDEX(color_fill_top) : LCD_REG_INDEX(color_fill_bottom);
66 textures[i].format != framebuffer.color_format) { 68 lcd_color_addr = HW::VADDR_LCD + 4 * lcd_color_addr;
67 // Reallocate texture if the framebuffer size has changed. 69 LCD::Regs::ColorFill color_fill = {0};
68 // This is expected to not happen very often and hence should not be a 70 LCD::Read(color_fill.raw, lcd_color_addr);
69 // performance problem. 71
70 ConfigureFramebufferTexture(textures[i], framebuffer); 72 if (color_fill.is_enabled) {
73 LoadColorToActiveGLTexture(color_fill.color_r, color_fill.color_g, color_fill.color_b, textures[i]);
74
75 // Resize the texture in case the framebuffer size has changed
76 textures[i].width = 1;
77 textures[i].height = 1;
78 } else {
79 if (textures[i].width != (GLsizei)framebuffer.width ||
80 textures[i].height != (GLsizei)framebuffer.height ||
81 textures[i].format != framebuffer.color_format) {
82 // Reallocate texture if the framebuffer size has changed.
83 // This is expected to not happen very often and hence should not be a
84 // performance problem.
85 ConfigureFramebufferTexture(textures[i], framebuffer);
86 }
87 LoadFBToActiveGLTexture(framebuffer, textures[i]);
88
89 // Resize the texture in case the framebuffer size has changed
90 textures[i].width = framebuffer.width;
91 textures[i].height = framebuffer.height;
71 } 92 }
72
73 LoadFBToActiveGLTexture(GPU::g_regs.framebuffer_config[i], textures[i]);
74 } 93 }
75 94
76 DrawScreens(); 95 DrawScreens();
@@ -115,10 +134,25 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig&
115 // TODO: Applications could theoretically crash Citra here by specifying too large 134 // TODO: Applications could theoretically crash Citra here by specifying too large
116 // framebuffer sizes. We should make sure that this cannot happen. 135 // framebuffer sizes. We should make sure that this cannot happen.
117 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, framebuffer.width, framebuffer.height, 136 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, framebuffer.width, framebuffer.height,
118 texture.gl_format, texture.gl_type, framebuffer_data); 137 texture.gl_format, texture.gl_type, framebuffer_data);
119 138
120 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 139 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
140 glBindTexture(GL_TEXTURE_2D, 0);
141}
121 142
143/**
144 * Fills active OpenGL texture with the given RGB color.
145 * Since the color is solid, the texture can be 1x1 but will stretch across whatever it's rendered on.
146 * This has the added benefit of being *really fast*.
147 */
148void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b,
149 const TextureInfo& texture) {
150 glBindTexture(GL_TEXTURE_2D, texture.handle);
151
152 u8 framebuffer_data[3] = { color_r, color_g, color_b };
153
154 // Update existing texture
155 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, framebuffer_data);
122 glBindTexture(GL_TEXTURE_2D, 0); 156 glBindTexture(GL_TEXTURE_2D, 0);
123} 157}
124 158
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index bcabab557..cd782428e 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -58,6 +58,9 @@ private:
58 // Loads framebuffer from emulated memory into the active OpenGL texture. 58 // Loads framebuffer from emulated memory into the active OpenGL texture.
59 static void LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& framebuffer, 59 static void LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& framebuffer,
60 const TextureInfo& texture); 60 const TextureInfo& texture);
61 // Fills active OpenGL texture with the given RGB color.
62 static void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b,
63 const TextureInfo& texture);
61 64
62 /// Computes the viewport rectangle 65 /// Computes the viewport rectangle
63 MathUtil::Rectangle<unsigned> GetViewportExtent(); 66 MathUtil::Rectangle<unsigned> GetViewportExtent();
@@ -72,7 +75,7 @@ private:
72 GLuint vertex_array_handle; 75 GLuint vertex_array_handle;
73 GLuint vertex_buffer_handle; 76 GLuint vertex_buffer_handle;
74 GLuint program_id; 77 GLuint program_id;
75 std::array<TextureInfo, 2> textures; 78 std::array<TextureInfo, 2> textures; ///< Textures for top and bottom screens respectively
76 // Shader uniform location indices 79 // Shader uniform location indices
77 GLuint uniform_modelview_matrix; 80 GLuint uniform_modelview_matrix;
78 GLuint uniform_color_texture; 81 GLuint uniform_color_texture;